1/*
2 *  zcrypt 2.1.0
3 *
4 *  Copyright IBM Corp. 2001, 2012
5 *  Author(s): Robert Burroughs
6 *	       Eric Rossman (edrossma@us.ibm.com)
7 *
8 *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
9 *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
10 *				  Ralph Wuerthner <rwuerthn@de.ibm.com>
11 *  MSGTYPE restruct:		  Holger Dengler <hd@linux.vnet.ibm.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#define KMSG_COMPONENT "zcrypt"
29#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/err.h>
34#include <linux/delay.h>
35#include <linux/slab.h>
36#include <linux/atomic.h>
37#include <linux/uaccess.h>
38
39#include "ap_bus.h"
40#include "zcrypt_api.h"
41#include "zcrypt_error.h"
42#include "zcrypt_msgtype6.h"
43#include "zcrypt_cca_key.h"
44
45#define PCIXCC_MIN_MOD_SIZE_OLD	 64	/*  512 bits	*/
46#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply	    */
47
48#define CEIL4(x) ((((x)+3)/4)*4)
49
50struct response_type {
51	struct completion work;
52	int type;
53};
54#define PCIXCC_RESPONSE_TYPE_ICA  0
55#define PCIXCC_RESPONSE_TYPE_XCRB 1
56#define PCIXCC_RESPONSE_TYPE_EP11 2
57
58MODULE_AUTHOR("IBM Corporation");
59MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
60		   "Copyright IBM Corp. 2001, 2012");
61MODULE_LICENSE("GPL");
62
63static void zcrypt_msgtype6_receive(struct ap_device *, struct ap_message *,
64				 struct ap_message *);
65
66/**
67 * CPRB
68 *	  Note that all shorts, ints and longs are little-endian.
69 *	  All pointer fields are 32-bits long, and mean nothing
70 *
71 *	  A request CPRB is followed by a request_parameter_block.
72 *
73 *	  The request (or reply) parameter block is organized thus:
74 *	    function code
75 *	    VUD block
76 *	    key block
77 */
78struct CPRB {
79	unsigned short cprb_len;	/* CPRB length			 */
80	unsigned char cprb_ver_id;	/* CPRB version id.		 */
81	unsigned char pad_000;		/* Alignment pad byte.		 */
82	unsigned char srpi_rtcode[4];	/* SRPI return code LELONG	 */
83	unsigned char srpi_verb;	/* SRPI verb type		 */
84	unsigned char flags;		/* flags			 */
85	unsigned char func_id[2];	/* function id			 */
86	unsigned char checkpoint_flag;	/*				 */
87	unsigned char resv2;		/* reserved			 */
88	unsigned short req_parml;	/* request parameter buffer	 */
89					/* length 16-bit little endian	 */
90	unsigned char req_parmp[4];	/* request parameter buffer	 *
91					 * pointer (means nothing: the	 *
92					 * parameter buffer follows	 *
93					 * the CPRB).			 */
94	unsigned char req_datal[4];	/* request data buffer		 */
95					/* length	  ULELONG	 */
96	unsigned char req_datap[4];	/* request data buffer		 */
97					/* pointer			 */
98	unsigned short rpl_parml;	/* reply  parameter buffer	 */
99					/* length 16-bit little endian	 */
100	unsigned char pad_001[2];	/* Alignment pad bytes. ULESHORT */
101	unsigned char rpl_parmp[4];	/* reply parameter buffer	 *
102					 * pointer (means nothing: the	 *
103					 * parameter buffer follows	 *
104					 * the CPRB).			 */
105	unsigned char rpl_datal[4];	/* reply data buffer len ULELONG */
106	unsigned char rpl_datap[4];	/* reply data buffer		 */
107					/* pointer			 */
108	unsigned short ccp_rscode;	/* server reason code	ULESHORT */
109	unsigned short ccp_rtcode;	/* server return code	ULESHORT */
110	unsigned char repd_parml[2];	/* replied parameter len ULESHORT*/
111	unsigned char mac_data_len[2];	/* Mac Data Length	ULESHORT */
112	unsigned char repd_datal[4];	/* replied data length	ULELONG	 */
113	unsigned char req_pc[2];	/* PC identifier		 */
114	unsigned char res_origin[8];	/* resource origin		 */
115	unsigned char mac_value[8];	/* Mac Value			 */
116	unsigned char logon_id[8];	/* Logon Identifier		 */
117	unsigned char usage_domain[2];	/* cdx				 */
118	unsigned char resv3[18];	/* reserved for requestor	 */
119	unsigned short svr_namel;	/* server name length  ULESHORT	 */
120	unsigned char svr_name[8];	/* server name			 */
121} __packed;
122
123struct function_and_rules_block {
124	unsigned char function_code[2];
125	unsigned short ulen;
126	unsigned char only_rule[8];
127} __packed;
128
129/**
130 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
131 * card in a type6 message. The 3 fields that must be filled in at execution
132 * time are  req_parml, rpl_parml and usage_domain.
133 * Everything about this interface is ascii/big-endian, since the
134 * device does *not* have 'Intel inside'.
135 *
136 * The CPRBX is followed immediately by the parm block.
137 * The parm block contains:
138 * - function code ('PD' 0x5044 or 'PK' 0x504B)
139 * - rule block (one of:)
140 *   + 0x000A 'PKCS-1.2' (MCL2 'PD')
141 *   + 0x000A 'ZERO-PAD' (MCL2 'PK')
142 *   + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
143 *   + 0x000A 'MRP     ' (MCL3 'PK' or CEX2C 'PK')
144 * - VUD block
145 */
146static struct CPRBX static_cprbx = {
147	.cprb_len	=  0x00DC,
148	.cprb_ver_id	=  0x02,
149	.func_id	= {0x54, 0x32},
150};
151
152/**
153 * Convert a ICAMEX message to a type6 MEX message.
154 *
155 * @zdev: crypto device pointer
156 * @ap_msg: pointer to AP message
157 * @mex: pointer to user input data
158 *
159 * Returns 0 on success or -EFAULT.
160 */
161static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
162				       struct ap_message *ap_msg,
163				       struct ica_rsa_modexpo *mex)
164{
165	static struct type6_hdr static_type6_hdrX = {
166		.type		=  0x06,
167		.offset1	=  0x00000058,
168		.agent_id	= {'C', 'A',},
169		.function_code	= {'P', 'K'},
170	};
171	static struct function_and_rules_block static_pke_fnr = {
172		.function_code	= {'P', 'K'},
173		.ulen		= 10,
174		.only_rule	= {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '}
175	};
176	static struct function_and_rules_block static_pke_fnr_MCL2 = {
177		.function_code	= {'P', 'K'},
178		.ulen		= 10,
179		.only_rule	= {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
180	};
181	struct {
182		struct type6_hdr hdr;
183		struct CPRBX cprbx;
184		struct function_and_rules_block fr;
185		unsigned short length;
186		char text[0];
187	} __packed * msg = ap_msg->message;
188	int size;
189
190	/* VUD.ciphertext */
191	msg->length = mex->inputdatalength + 2;
192	if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
193		return -EFAULT;
194
195	/* Set up key which is located after the variable length text. */
196	size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
197	if (size < 0)
198		return size;
199	size += sizeof(*msg) + mex->inputdatalength;
200
201	/* message header, cprbx and f&r */
202	msg->hdr = static_type6_hdrX;
203	msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
204	msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
205
206	msg->cprbx = static_cprbx;
207	msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
208	msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
209
210	msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
211		static_pke_fnr_MCL2 : static_pke_fnr;
212
213	msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
214
215	ap_msg->length = size;
216	return 0;
217}
218
219/**
220 * Convert a ICACRT message to a type6 CRT message.
221 *
222 * @zdev: crypto device pointer
223 * @ap_msg: pointer to AP message
224 * @crt: pointer to user input data
225 *
226 * Returns 0 on success or -EFAULT.
227 */
228static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
229				       struct ap_message *ap_msg,
230				       struct ica_rsa_modexpo_crt *crt)
231{
232	static struct type6_hdr static_type6_hdrX = {
233		.type		=  0x06,
234		.offset1	=  0x00000058,
235		.agent_id	= {'C', 'A',},
236		.function_code	= {'P', 'D'},
237	};
238	static struct function_and_rules_block static_pkd_fnr = {
239		.function_code	= {'P', 'D'},
240		.ulen		= 10,
241		.only_rule	= {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
242	};
243
244	static struct function_and_rules_block static_pkd_fnr_MCL2 = {
245		.function_code	= {'P', 'D'},
246		.ulen		= 10,
247		.only_rule	= {'P', 'K', 'C', 'S', '-', '1', '.', '2'}
248	};
249	struct {
250		struct type6_hdr hdr;
251		struct CPRBX cprbx;
252		struct function_and_rules_block fr;
253		unsigned short length;
254		char text[0];
255	} __packed * msg = ap_msg->message;
256	int size;
257
258	/* VUD.ciphertext */
259	msg->length = crt->inputdatalength + 2;
260	if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
261		return -EFAULT;
262
263	/* Set up key which is located after the variable length text. */
264	size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
265	if (size < 0)
266		return size;
267	size += sizeof(*msg) + crt->inputdatalength;	/* total size of msg */
268
269	/* message header, cprbx and f&r */
270	msg->hdr = static_type6_hdrX;
271	msg->hdr.ToCardLen1 = size -  sizeof(msg->hdr);
272	msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
273
274	msg->cprbx = static_cprbx;
275	msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
276	msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
277		size - sizeof(msg->hdr) - sizeof(msg->cprbx);
278
279	msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
280		static_pkd_fnr_MCL2 : static_pkd_fnr;
281
282	ap_msg->length = size;
283	return 0;
284}
285
286/**
287 * Convert a XCRB message to a type6 CPRB message.
288 *
289 * @zdev: crypto device pointer
290 * @ap_msg: pointer to AP message
291 * @xcRB: pointer to user input data
292 *
293 * Returns 0 on success or -EFAULT, -EINVAL.
294 */
295struct type86_fmt2_msg {
296	struct type86_hdr hdr;
297	struct type86_fmt2_ext fmt2;
298} __packed;
299
300static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
301				       struct ap_message *ap_msg,
302				       struct ica_xcRB *xcRB)
303{
304	static struct type6_hdr static_type6_hdrX = {
305		.type		=  0x06,
306		.offset1	=  0x00000058,
307	};
308	struct {
309		struct type6_hdr hdr;
310		struct CPRBX cprbx;
311	} __packed * msg = ap_msg->message;
312
313	int rcblen = CEIL4(xcRB->request_control_blk_length);
314	int replylen, req_sumlen, resp_sumlen;
315	char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
316	char *function_code;
317
318	if (CEIL4(xcRB->request_control_blk_length) <
319			xcRB->request_control_blk_length)
320		return -EINVAL; /* overflow after alignment*/
321
322	/* length checks */
323	ap_msg->length = sizeof(struct type6_hdr) +
324		CEIL4(xcRB->request_control_blk_length) +
325		xcRB->request_data_length;
326	if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE)
327		return -EINVAL;
328
329	/* Overflow check
330	   sum must be greater (or equal) than the largest operand */
331	req_sumlen = CEIL4(xcRB->request_control_blk_length) +
332			xcRB->request_data_length;
333	if ((CEIL4(xcRB->request_control_blk_length) <=
334						xcRB->request_data_length) ?
335		(req_sumlen < xcRB->request_data_length) :
336		(req_sumlen < CEIL4(xcRB->request_control_blk_length))) {
337		return -EINVAL;
338	}
339
340	if (CEIL4(xcRB->reply_control_blk_length) <
341			xcRB->reply_control_blk_length)
342		return -EINVAL; /* overflow after alignment*/
343
344	replylen = sizeof(struct type86_fmt2_msg) +
345		CEIL4(xcRB->reply_control_blk_length) +
346		xcRB->reply_data_length;
347	if (replylen > MSGTYPE06_MAX_MSG_SIZE)
348		return -EINVAL;
349
350	/* Overflow check
351	   sum must be greater (or equal) than the largest operand */
352	resp_sumlen = CEIL4(xcRB->reply_control_blk_length) +
353			xcRB->reply_data_length;
354	if ((CEIL4(xcRB->reply_control_blk_length) <= xcRB->reply_data_length) ?
355		(resp_sumlen < xcRB->reply_data_length) :
356		(resp_sumlen < CEIL4(xcRB->reply_control_blk_length))) {
357		return -EINVAL;
358	}
359
360	/* prepare type6 header */
361	msg->hdr = static_type6_hdrX;
362	memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
363	msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
364	if (xcRB->request_data_length) {
365		msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
366		msg->hdr.ToCardLen2 = xcRB->request_data_length;
367	}
368	msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
369	msg->hdr.FromCardLen2 = xcRB->reply_data_length;
370
371	/* prepare CPRB */
372	if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
373		    xcRB->request_control_blk_length))
374		return -EFAULT;
375	if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
376	    xcRB->request_control_blk_length)
377		return -EINVAL;
378	function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
379	memcpy(msg->hdr.function_code, function_code,
380	       sizeof(msg->hdr.function_code));
381
382	if (memcmp(function_code, "US", 2) == 0)
383		ap_msg->special = 1;
384	else
385		ap_msg->special = 0;
386
387	/* copy data block */
388	if (xcRB->request_data_length &&
389	    copy_from_user(req_data, xcRB->request_data_address,
390		xcRB->request_data_length))
391		return -EFAULT;
392	return 0;
393}
394
395static int xcrb_msg_to_type6_ep11cprb_msgx(struct zcrypt_device *zdev,
396				       struct ap_message *ap_msg,
397				       struct ep11_urb *xcRB)
398{
399	unsigned int lfmt;
400
401	static struct type6_hdr static_type6_ep11_hdr = {
402		.type		=  0x06,
403		.rqid		= {0x00, 0x01},
404		.function_code	= {0x00, 0x00},
405		.agent_id[0]	=  0x58,	/* {'X'} */
406		.agent_id[1]	=  0x43,	/* {'C'} */
407		.offset1	=  0x00000058,
408	};
409
410	struct {
411		struct type6_hdr hdr;
412		struct ep11_cprb cprbx;
413		unsigned char	pld_tag;	/* fixed value 0x30 */
414		unsigned char	pld_lenfmt;	/* payload length format */
415	} __packed * msg = ap_msg->message;
416
417	struct pld_hdr {
418		unsigned char	func_tag;	/* fixed value 0x4 */
419		unsigned char	func_len;	/* fixed value 0x4 */
420		unsigned int	func_val;	/* function ID	   */
421		unsigned char	dom_tag;	/* fixed value 0x4 */
422		unsigned char	dom_len;	/* fixed value 0x4 */
423		unsigned int	dom_val;	/* domain id	   */
424	} __packed * payload_hdr;
425
426	if (CEIL4(xcRB->req_len) < xcRB->req_len)
427		return -EINVAL; /* overflow after alignment*/
428
429	/* length checks */
430	ap_msg->length = sizeof(struct type6_hdr) + xcRB->req_len;
431	if (CEIL4(xcRB->req_len) > MSGTYPE06_MAX_MSG_SIZE -
432				   (sizeof(struct type6_hdr)))
433		return -EINVAL;
434
435	if (CEIL4(xcRB->resp_len) < xcRB->resp_len)
436		return -EINVAL; /* overflow after alignment*/
437
438	if (CEIL4(xcRB->resp_len) > MSGTYPE06_MAX_MSG_SIZE -
439				    (sizeof(struct type86_fmt2_msg)))
440		return -EINVAL;
441
442	/* prepare type6 header */
443	msg->hdr = static_type6_ep11_hdr;
444	msg->hdr.ToCardLen1   = xcRB->req_len;
445	msg->hdr.FromCardLen1 = xcRB->resp_len;
446
447	/* Import CPRB data from the ioctl input parameter */
448	if (copy_from_user(&(msg->cprbx.cprb_len),
449			   (char __force __user *)xcRB->req, xcRB->req_len)) {
450		return -EFAULT;
451	}
452
453	/*
454	 The target domain field within the cprb body/payload block will be
455	 replaced by the usage domain for non-management commands only.
456	 Therefore we check the first bit of the 'flags' parameter for
457	 management command indication.
458	   0 - non management command
459	   1 - management command
460	*/
461	if (!((msg->cprbx.flags & 0x80) == 0x80)) {
462		msg->cprbx.target_id = (unsigned int)
463					AP_QID_QUEUE(zdev->ap_dev->qid);
464
465		if ((msg->pld_lenfmt & 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/
466			switch (msg->pld_lenfmt & 0x03) {
467			case 1:
468				lfmt = 2;
469				break;
470			case 2:
471				lfmt = 3;
472				break;
473			default:
474				return -EINVAL;
475			}
476		} else {
477			lfmt = 1; /* length format #1 */
478		  }
479		payload_hdr = (struct pld_hdr *)((&(msg->pld_lenfmt))+lfmt);
480		payload_hdr->dom_val = (unsigned int)
481					AP_QID_QUEUE(zdev->ap_dev->qid);
482	}
483	return 0;
484}
485
486/**
487 * Copy results from a type 86 ICA reply message back to user space.
488 *
489 * @zdev: crypto device pointer
490 * @reply: reply AP message.
491 * @data: pointer to user output data
492 * @length: size of user output data
493 *
494 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
495 */
496struct type86x_reply {
497	struct type86_hdr hdr;
498	struct type86_fmt2_ext fmt2;
499	struct CPRBX cprbx;
500	unsigned char pad[4];	/* 4 byte function code/rules block ? */
501	unsigned short length;
502	char text[0];
503} __packed;
504
505struct type86_ep11_reply {
506	struct type86_hdr hdr;
507	struct type86_fmt2_ext fmt2;
508	struct ep11_cprb cprbx;
509} __packed;
510
511static int convert_type86_ica(struct zcrypt_device *zdev,
512			  struct ap_message *reply,
513			  char __user *outputdata,
514			  unsigned int outputdatalength)
515{
516	static unsigned char static_pad[] = {
517		0x00, 0x02,
518		0x1B, 0x7B, 0x5D, 0xB5, 0x75, 0x01, 0x3D, 0xFD,
519		0x8D, 0xD1, 0xC7, 0x03, 0x2D, 0x09, 0x23, 0x57,
520		0x89, 0x49, 0xB9, 0x3F, 0xBB, 0x99, 0x41, 0x5B,
521		0x75, 0x21, 0x7B, 0x9D, 0x3B, 0x6B, 0x51, 0x39,
522		0xBB, 0x0D, 0x35, 0xB9, 0x89, 0x0F, 0x93, 0xA5,
523		0x0B, 0x47, 0xF1, 0xD3, 0xBB, 0xCB, 0xF1, 0x9D,
524		0x23, 0x73, 0x71, 0xFF, 0xF3, 0xF5, 0x45, 0xFB,
525		0x61, 0x29, 0x23, 0xFD, 0xF1, 0x29, 0x3F, 0x7F,
526		0x17, 0xB7, 0x1B, 0xA9, 0x19, 0xBD, 0x57, 0xA9,
527		0xD7, 0x95, 0xA3, 0xCB, 0xED, 0x1D, 0xDB, 0x45,
528		0x7D, 0x11, 0xD1, 0x51, 0x1B, 0xED, 0x71, 0xE9,
529		0xB1, 0xD1, 0xAB, 0xAB, 0x21, 0x2B, 0x1B, 0x9F,
530		0x3B, 0x9F, 0xF7, 0xF7, 0xBD, 0x63, 0xEB, 0xAD,
531		0xDF, 0xB3, 0x6F, 0x5B, 0xDB, 0x8D, 0xA9, 0x5D,
532		0xE3, 0x7D, 0x77, 0x49, 0x47, 0xF5, 0xA7, 0xFD,
533		0xAB, 0x2F, 0x27, 0x35, 0x77, 0xD3, 0x49, 0xC9,
534		0x09, 0xEB, 0xB1, 0xF9, 0xBF, 0x4B, 0xCB, 0x2B,
535		0xEB, 0xEB, 0x05, 0xFF, 0x7D, 0xC7, 0x91, 0x8B,
536		0x09, 0x83, 0xB9, 0xB9, 0x69, 0x33, 0x39, 0x6B,
537		0x79, 0x75, 0x19, 0xBF, 0xBB, 0x07, 0x1D, 0xBD,
538		0x29, 0xBF, 0x39, 0x95, 0x93, 0x1D, 0x35, 0xC7,
539		0xC9, 0x4D, 0xE5, 0x97, 0x0B, 0x43, 0x9B, 0xF1,
540		0x16, 0x93, 0x03, 0x1F, 0xA5, 0xFB, 0xDB, 0xF3,
541		0x27, 0x4F, 0x27, 0x61, 0x05, 0x1F, 0xB9, 0x23,
542		0x2F, 0xC3, 0x81, 0xA9, 0x23, 0x71, 0x55, 0x55,
543		0xEB, 0xED, 0x41, 0xE5, 0xF3, 0x11, 0xF1, 0x43,
544		0x69, 0x03, 0xBD, 0x0B, 0x37, 0x0F, 0x51, 0x8F,
545		0x0B, 0xB5, 0x89, 0x5B, 0x67, 0xA9, 0xD9, 0x4F,
546		0x01, 0xF9, 0x21, 0x77, 0x37, 0x73, 0x79, 0xC5,
547		0x7F, 0x51, 0xC1, 0xCF, 0x97, 0xA1, 0x75, 0xAD,
548		0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41,
549		0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09
550	};
551	struct type86x_reply *msg = reply->message;
552	unsigned short service_rc, service_rs;
553	unsigned int reply_len, pad_len;
554	char *data;
555
556	service_rc = msg->cprbx.ccp_rtcode;
557	if (unlikely(service_rc != 0)) {
558		service_rs = msg->cprbx.ccp_rscode;
559		if (service_rc == 8 && service_rs == 66)
560			return -EINVAL;
561		if (service_rc == 8 && service_rs == 65)
562			return -EINVAL;
563		if (service_rc == 8 && service_rs == 770)
564			return -EINVAL;
565		if (service_rc == 8 && service_rs == 783) {
566			zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
567			return -EAGAIN;
568		}
569		if (service_rc == 12 && service_rs == 769)
570			return -EINVAL;
571		if (service_rc == 8 && service_rs == 72)
572			return -EINVAL;
573		zdev->online = 0;
574		pr_err("Cryptographic device %x failed and was set offline\n",
575		       zdev->ap_dev->qid);
576		ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%drc%d",
577			       zdev->ap_dev->qid, zdev->online,
578			       msg->hdr.reply_code);
579		return -EAGAIN;	/* repeat the request on a different device. */
580	}
581	data = msg->text;
582	reply_len = msg->length - 2;
583	if (reply_len > outputdatalength)
584		return -EINVAL;
585	/*
586	 * For all encipher requests, the length of the ciphertext (reply_len)
587	 * will always equal the modulus length. For MEX decipher requests
588	 * the output needs to get padded. Minimum pad size is 10.
589	 *
590	 * Currently, the cases where padding will be added is for:
591	 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
592	 *   ZERO-PAD and CRT is only supported for PKD requests)
593	 * - PCICC, always
594	 */
595	pad_len = outputdatalength - reply_len;
596	if (pad_len > 0) {
597		if (pad_len < 10)
598			return -EINVAL;
599		/* 'restore' padding left in the PCICC/PCIXCC card. */
600		if (copy_to_user(outputdata, static_pad, pad_len - 1))
601			return -EFAULT;
602		if (put_user(0, outputdata + pad_len - 1))
603			return -EFAULT;
604	}
605	/* Copy the crypto response to user space. */
606	if (copy_to_user(outputdata + pad_len, data, reply_len))
607		return -EFAULT;
608	return 0;
609}
610
611/**
612 * Copy results from a type 86 XCRB reply message back to user space.
613 *
614 * @zdev: crypto device pointer
615 * @reply: reply AP message.
616 * @xcRB: pointer to XCRB
617 *
618 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
619 */
620static int convert_type86_xcrb(struct zcrypt_device *zdev,
621			       struct ap_message *reply,
622			       struct ica_xcRB *xcRB)
623{
624	struct type86_fmt2_msg *msg = reply->message;
625	char *data = reply->message;
626
627	/* Copy CPRB to user */
628	if (copy_to_user(xcRB->reply_control_blk_addr,
629		data + msg->fmt2.offset1, msg->fmt2.count1))
630		return -EFAULT;
631	xcRB->reply_control_blk_length = msg->fmt2.count1;
632
633	/* Copy data buffer to user */
634	if (msg->fmt2.count2)
635		if (copy_to_user(xcRB->reply_data_addr,
636			data + msg->fmt2.offset2, msg->fmt2.count2))
637			return -EFAULT;
638	xcRB->reply_data_length = msg->fmt2.count2;
639	return 0;
640}
641
642/**
643 * Copy results from a type 86 EP11 XCRB reply message back to user space.
644 *
645 * @zdev: crypto device pointer
646 * @reply: reply AP message.
647 * @xcRB: pointer to EP11 user request block
648 *
649 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
650 */
651static int convert_type86_ep11_xcrb(struct zcrypt_device *zdev,
652				    struct ap_message *reply,
653				    struct ep11_urb *xcRB)
654{
655	struct type86_fmt2_msg *msg = reply->message;
656	char *data = reply->message;
657
658	if (xcRB->resp_len < msg->fmt2.count1)
659		return -EINVAL;
660
661	/* Copy response CPRB to user */
662	if (copy_to_user((char __force __user *)xcRB->resp,
663			 data + msg->fmt2.offset1, msg->fmt2.count1))
664		return -EFAULT;
665	xcRB->resp_len = msg->fmt2.count1;
666	return 0;
667}
668
669static int convert_type86_rng(struct zcrypt_device *zdev,
670			  struct ap_message *reply,
671			  char *buffer)
672{
673	struct {
674		struct type86_hdr hdr;
675		struct type86_fmt2_ext fmt2;
676		struct CPRBX cprbx;
677	} __packed * msg = reply->message;
678	char *data = reply->message;
679
680	if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
681		return -EINVAL;
682	memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
683	return msg->fmt2.count2;
684}
685
686static int convert_response_ica(struct zcrypt_device *zdev,
687			    struct ap_message *reply,
688			    char __user *outputdata,
689			    unsigned int outputdatalength)
690{
691	struct type86x_reply *msg = reply->message;
692
693	/* Response type byte is the second byte in the response. */
694	switch (((unsigned char *) reply->message)[1]) {
695	case TYPE82_RSP_CODE:
696	case TYPE88_RSP_CODE:
697		return convert_error(zdev, reply);
698	case TYPE86_RSP_CODE:
699		if (msg->cprbx.ccp_rtcode &&
700		   (msg->cprbx.ccp_rscode == 0x14f) &&
701		   (outputdatalength > 256)) {
702			if (zdev->max_exp_bit_length <= 17) {
703				zdev->max_exp_bit_length = 17;
704				return -EAGAIN;
705			} else
706				return -EINVAL;
707		}
708		if (msg->hdr.reply_code)
709			return convert_error(zdev, reply);
710		if (msg->cprbx.cprb_ver_id == 0x02)
711			return convert_type86_ica(zdev, reply,
712						  outputdata, outputdatalength);
713		/* Fall through, no break, incorrect cprb version is an unknown
714		 * response */
715	default: /* Unknown response type, this should NEVER EVER happen */
716		zdev->online = 0;
717		pr_err("Cryptographic device %x failed and was set offline\n",
718		       zdev->ap_dev->qid);
719		ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
720			       zdev->ap_dev->qid, zdev->online);
721		return -EAGAIN;	/* repeat the request on a different device. */
722	}
723}
724
725static int convert_response_xcrb(struct zcrypt_device *zdev,
726			    struct ap_message *reply,
727			    struct ica_xcRB *xcRB)
728{
729	struct type86x_reply *msg = reply->message;
730
731	/* Response type byte is the second byte in the response. */
732	switch (((unsigned char *) reply->message)[1]) {
733	case TYPE82_RSP_CODE:
734	case TYPE88_RSP_CODE:
735		xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
736		return convert_error(zdev, reply);
737	case TYPE86_RSP_CODE:
738		if (msg->hdr.reply_code) {
739			memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
740			return convert_error(zdev, reply);
741		}
742		if (msg->cprbx.cprb_ver_id == 0x02)
743			return convert_type86_xcrb(zdev, reply, xcRB);
744		/* Fall through, no break, incorrect cprb version is an unknown
745		 * response */
746	default: /* Unknown response type, this should NEVER EVER happen */
747		xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
748		zdev->online = 0;
749		pr_err("Cryptographic device %x failed and was set offline\n",
750		       zdev->ap_dev->qid);
751		ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
752			       zdev->ap_dev->qid, zdev->online);
753		return -EAGAIN;	/* repeat the request on a different device. */
754	}
755}
756
757static int convert_response_ep11_xcrb(struct zcrypt_device *zdev,
758	struct ap_message *reply, struct ep11_urb *xcRB)
759{
760	struct type86_ep11_reply *msg = reply->message;
761
762	/* Response type byte is the second byte in the response. */
763	switch (((unsigned char *)reply->message)[1]) {
764	case TYPE82_RSP_CODE:
765	case TYPE87_RSP_CODE:
766		return convert_error(zdev, reply);
767	case TYPE86_RSP_CODE:
768		if (msg->hdr.reply_code)
769			return convert_error(zdev, reply);
770		if (msg->cprbx.cprb_ver_id == 0x04)
771			return convert_type86_ep11_xcrb(zdev, reply, xcRB);
772	/* Fall through, no break, incorrect cprb version is an unknown resp.*/
773	default: /* Unknown response type, this should NEVER EVER happen */
774		zdev->online = 0;
775		pr_err("Cryptographic device %x failed and was set offline\n",
776		       zdev->ap_dev->qid);
777		ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
778			       zdev->ap_dev->qid, zdev->online);
779		return -EAGAIN; /* repeat the request on a different device. */
780	}
781}
782
783static int convert_response_rng(struct zcrypt_device *zdev,
784				 struct ap_message *reply,
785				 char *data)
786{
787	struct type86x_reply *msg = reply->message;
788
789	switch (msg->hdr.type) {
790	case TYPE82_RSP_CODE:
791	case TYPE88_RSP_CODE:
792		return -EINVAL;
793	case TYPE86_RSP_CODE:
794		if (msg->hdr.reply_code)
795			return -EINVAL;
796		if (msg->cprbx.cprb_ver_id == 0x02)
797			return convert_type86_rng(zdev, reply, data);
798		/* Fall through, no break, incorrect cprb version is an unknown
799		 * response */
800	default: /* Unknown response type, this should NEVER EVER happen */
801		zdev->online = 0;
802		pr_err("Cryptographic device %x failed and was set offline\n",
803		       zdev->ap_dev->qid);
804		ZCRYPT_DBF_DEV(DBF_ERR, zdev, "dev%04xo%dfail",
805			       zdev->ap_dev->qid, zdev->online);
806		return -EAGAIN;	/* repeat the request on a different device. */
807	}
808}
809
810/**
811 * This function is called from the AP bus code after a crypto request
812 * "msg" has finished with the reply message "reply".
813 * It is called from tasklet context.
814 * @ap_dev: pointer to the AP device
815 * @msg: pointer to the AP message
816 * @reply: pointer to the AP reply message
817 */
818static void zcrypt_msgtype6_receive(struct ap_device *ap_dev,
819				  struct ap_message *msg,
820				  struct ap_message *reply)
821{
822	static struct error_hdr error_reply = {
823		.type = TYPE82_RSP_CODE,
824		.reply_code = REP82_ERROR_MACHINE_FAILURE,
825	};
826	struct response_type *resp_type =
827		(struct response_type *) msg->private;
828	struct type86x_reply *t86r;
829	int length;
830
831	/* Copy the reply message to the request message buffer. */
832	if (IS_ERR(reply)) {
833		memcpy(msg->message, &error_reply, sizeof(error_reply));
834		goto out;
835	}
836	t86r = reply->message;
837	if (t86r->hdr.type == TYPE86_RSP_CODE &&
838		 t86r->cprbx.cprb_ver_id == 0x02) {
839		switch (resp_type->type) {
840		case PCIXCC_RESPONSE_TYPE_ICA:
841			length = sizeof(struct type86x_reply)
842				+ t86r->length - 2;
843			length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
844			memcpy(msg->message, reply->message, length);
845			break;
846		case PCIXCC_RESPONSE_TYPE_XCRB:
847			length = t86r->fmt2.offset2 + t86r->fmt2.count2;
848			length = min(MSGTYPE06_MAX_MSG_SIZE, length);
849			memcpy(msg->message, reply->message, length);
850			break;
851		default:
852			memcpy(msg->message, &error_reply,
853			       sizeof(error_reply));
854		}
855	} else
856		memcpy(msg->message, reply->message, sizeof(error_reply));
857out:
858	complete(&(resp_type->work));
859}
860
861/**
862 * This function is called from the AP bus code after a crypto request
863 * "msg" has finished with the reply message "reply".
864 * It is called from tasklet context.
865 * @ap_dev: pointer to the AP device
866 * @msg: pointer to the AP message
867 * @reply: pointer to the AP reply message
868 */
869static void zcrypt_msgtype6_receive_ep11(struct ap_device *ap_dev,
870					 struct ap_message *msg,
871					 struct ap_message *reply)
872{
873	static struct error_hdr error_reply = {
874		.type = TYPE82_RSP_CODE,
875		.reply_code = REP82_ERROR_MACHINE_FAILURE,
876	};
877	struct response_type *resp_type =
878		(struct response_type *)msg->private;
879	struct type86_ep11_reply *t86r;
880	int length;
881
882	/* Copy the reply message to the request message buffer. */
883	if (IS_ERR(reply)) {
884		memcpy(msg->message, &error_reply, sizeof(error_reply));
885		goto out;
886	}
887	t86r = reply->message;
888	if (t86r->hdr.type == TYPE86_RSP_CODE &&
889	    t86r->cprbx.cprb_ver_id == 0x04) {
890		switch (resp_type->type) {
891		case PCIXCC_RESPONSE_TYPE_EP11:
892			length = t86r->fmt2.offset1 + t86r->fmt2.count1;
893			length = min(MSGTYPE06_MAX_MSG_SIZE, length);
894			memcpy(msg->message, reply->message, length);
895			break;
896		default:
897			memcpy(msg->message, &error_reply, sizeof(error_reply));
898		}
899	} else {
900		memcpy(msg->message, reply->message, sizeof(error_reply));
901	  }
902out:
903	complete(&(resp_type->work));
904}
905
906static atomic_t zcrypt_step = ATOMIC_INIT(0);
907
908/**
909 * The request distributor calls this function if it picked the PCIXCC/CEX2C
910 * device to handle a modexpo request.
911 * @zdev: pointer to zcrypt_device structure that identifies the
912 *	  PCIXCC/CEX2C device to the request distributor
913 * @mex: pointer to the modexpo request buffer
914 */
915static long zcrypt_msgtype6_modexpo(struct zcrypt_device *zdev,
916				  struct ica_rsa_modexpo *mex)
917{
918	struct ap_message ap_msg;
919	struct response_type resp_type = {
920		.type = PCIXCC_RESPONSE_TYPE_ICA,
921	};
922	int rc;
923
924	ap_init_message(&ap_msg);
925	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
926	if (!ap_msg.message)
927		return -ENOMEM;
928	ap_msg.receive = zcrypt_msgtype6_receive;
929	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
930				atomic_inc_return(&zcrypt_step);
931	ap_msg.private = &resp_type;
932	rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
933	if (rc)
934		goto out_free;
935	init_completion(&resp_type.work);
936	ap_queue_message(zdev->ap_dev, &ap_msg);
937	rc = wait_for_completion_interruptible(&resp_type.work);
938	if (rc == 0)
939		rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
940					  mex->outputdatalength);
941	else
942		/* Signal pending. */
943		ap_cancel_message(zdev->ap_dev, &ap_msg);
944out_free:
945	free_page((unsigned long) ap_msg.message);
946	return rc;
947}
948
949/**
950 * The request distributor calls this function if it picked the PCIXCC/CEX2C
951 * device to handle a modexpo_crt request.
952 * @zdev: pointer to zcrypt_device structure that identifies the
953 *	  PCIXCC/CEX2C device to the request distributor
954 * @crt: pointer to the modexpoc_crt request buffer
955 */
956static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_device *zdev,
957				      struct ica_rsa_modexpo_crt *crt)
958{
959	struct ap_message ap_msg;
960	struct response_type resp_type = {
961		.type = PCIXCC_RESPONSE_TYPE_ICA,
962	};
963	int rc;
964
965	ap_init_message(&ap_msg);
966	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
967	if (!ap_msg.message)
968		return -ENOMEM;
969	ap_msg.receive = zcrypt_msgtype6_receive;
970	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
971				atomic_inc_return(&zcrypt_step);
972	ap_msg.private = &resp_type;
973	rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
974	if (rc)
975		goto out_free;
976	init_completion(&resp_type.work);
977	ap_queue_message(zdev->ap_dev, &ap_msg);
978	rc = wait_for_completion_interruptible(&resp_type.work);
979	if (rc == 0)
980		rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
981					  crt->outputdatalength);
982	else
983		/* Signal pending. */
984		ap_cancel_message(zdev->ap_dev, &ap_msg);
985out_free:
986	free_page((unsigned long) ap_msg.message);
987	return rc;
988}
989
990/**
991 * The request distributor calls this function if it picked the PCIXCC/CEX2C
992 * device to handle a send_cprb request.
993 * @zdev: pointer to zcrypt_device structure that identifies the
994 *	  PCIXCC/CEX2C device to the request distributor
995 * @xcRB: pointer to the send_cprb request buffer
996 */
997static long zcrypt_msgtype6_send_cprb(struct zcrypt_device *zdev,
998				    struct ica_xcRB *xcRB)
999{
1000	struct ap_message ap_msg;
1001	struct response_type resp_type = {
1002		.type = PCIXCC_RESPONSE_TYPE_XCRB,
1003	};
1004	int rc;
1005
1006	ap_init_message(&ap_msg);
1007	ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1008	if (!ap_msg.message)
1009		return -ENOMEM;
1010	ap_msg.receive = zcrypt_msgtype6_receive;
1011	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1012				atomic_inc_return(&zcrypt_step);
1013	ap_msg.private = &resp_type;
1014	rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
1015	if (rc)
1016		goto out_free;
1017	init_completion(&resp_type.work);
1018	ap_queue_message(zdev->ap_dev, &ap_msg);
1019	rc = wait_for_completion_interruptible(&resp_type.work);
1020	if (rc == 0)
1021		rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
1022	else
1023		/* Signal pending. */
1024		ap_cancel_message(zdev->ap_dev, &ap_msg);
1025out_free:
1026	kzfree(ap_msg.message);
1027	return rc;
1028}
1029
1030/**
1031 * The request distributor calls this function if it picked the CEX4P
1032 * device to handle a send_ep11_cprb request.
1033 * @zdev: pointer to zcrypt_device structure that identifies the
1034 *	  CEX4P device to the request distributor
1035 * @xcRB: pointer to the ep11 user request block
1036 */
1037static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_device *zdev,
1038						struct ep11_urb *xcrb)
1039{
1040	struct ap_message ap_msg;
1041	struct response_type resp_type = {
1042		.type = PCIXCC_RESPONSE_TYPE_EP11,
1043	};
1044	int rc;
1045
1046	ap_init_message(&ap_msg);
1047	ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1048	if (!ap_msg.message)
1049		return -ENOMEM;
1050	ap_msg.receive = zcrypt_msgtype6_receive_ep11;
1051	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1052				atomic_inc_return(&zcrypt_step);
1053	ap_msg.private = &resp_type;
1054	rc = xcrb_msg_to_type6_ep11cprb_msgx(zdev, &ap_msg, xcrb);
1055	if (rc)
1056		goto out_free;
1057	init_completion(&resp_type.work);
1058	ap_queue_message(zdev->ap_dev, &ap_msg);
1059	rc = wait_for_completion_interruptible(&resp_type.work);
1060	if (rc == 0)
1061		rc = convert_response_ep11_xcrb(zdev, &ap_msg, xcrb);
1062	else /* Signal pending. */
1063		ap_cancel_message(zdev->ap_dev, &ap_msg);
1064
1065out_free:
1066	kzfree(ap_msg.message);
1067	return rc;
1068}
1069
1070/**
1071 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1072 * device to generate random data.
1073 * @zdev: pointer to zcrypt_device structure that identifies the
1074 *	  PCIXCC/CEX2C device to the request distributor
1075 * @buffer: pointer to a memory page to return random data
1076 */
1077
1078static long zcrypt_msgtype6_rng(struct zcrypt_device *zdev,
1079				    char *buffer)
1080{
1081	struct ap_message ap_msg;
1082	struct response_type resp_type = {
1083		.type = PCIXCC_RESPONSE_TYPE_XCRB,
1084	};
1085	int rc;
1086
1087	ap_init_message(&ap_msg);
1088	ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1089	if (!ap_msg.message)
1090		return -ENOMEM;
1091	ap_msg.receive = zcrypt_msgtype6_receive;
1092	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1093				atomic_inc_return(&zcrypt_step);
1094	ap_msg.private = &resp_type;
1095	rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
1096	init_completion(&resp_type.work);
1097	ap_queue_message(zdev->ap_dev, &ap_msg);
1098	rc = wait_for_completion_interruptible(&resp_type.work);
1099	if (rc == 0)
1100		rc = convert_response_rng(zdev, &ap_msg, buffer);
1101	else
1102		/* Signal pending. */
1103		ap_cancel_message(zdev->ap_dev, &ap_msg);
1104	kfree(ap_msg.message);
1105	return rc;
1106}
1107
1108/**
1109 * The crypto operations for a PCIXCC/CEX2C card.
1110 */
1111static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
1112	.owner = THIS_MODULE,
1113	.variant = MSGTYPE06_VARIANT_NORNG,
1114	.rsa_modexpo = zcrypt_msgtype6_modexpo,
1115	.rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1116	.send_cprb = zcrypt_msgtype6_send_cprb,
1117};
1118
1119static struct zcrypt_ops zcrypt_msgtype6_ops = {
1120	.owner = THIS_MODULE,
1121	.variant = MSGTYPE06_VARIANT_DEFAULT,
1122	.rsa_modexpo = zcrypt_msgtype6_modexpo,
1123	.rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1124	.send_cprb = zcrypt_msgtype6_send_cprb,
1125	.rng = zcrypt_msgtype6_rng,
1126};
1127
1128static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = {
1129	.owner = THIS_MODULE,
1130	.variant = MSGTYPE06_VARIANT_EP11,
1131	.rsa_modexpo = NULL,
1132	.rsa_modexpo_crt = NULL,
1133	.send_ep11_cprb = zcrypt_msgtype6_send_ep11_cprb,
1134};
1135
1136int __init zcrypt_msgtype6_init(void)
1137{
1138	zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
1139	zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
1140	zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops);
1141	return 0;
1142}
1143
1144void __exit zcrypt_msgtype6_exit(void)
1145{
1146	zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
1147	zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
1148	zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops);
1149}
1150
1151module_init(zcrypt_msgtype6_init);
1152module_exit(zcrypt_msgtype6_exit);
1153