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 (!reply)
833		goto out;	/* ap_msg->rc indicates the error */
834	t86r = reply->message;
835	if (t86r->hdr.type == TYPE86_RSP_CODE &&
836		 t86r->cprbx.cprb_ver_id == 0x02) {
837		switch (resp_type->type) {
838		case PCIXCC_RESPONSE_TYPE_ICA:
839			length = sizeof(struct type86x_reply)
840				+ t86r->length - 2;
841			length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
842			memcpy(msg->message, reply->message, length);
843			break;
844		case PCIXCC_RESPONSE_TYPE_XCRB:
845			length = t86r->fmt2.offset2 + t86r->fmt2.count2;
846			length = min(MSGTYPE06_MAX_MSG_SIZE, length);
847			memcpy(msg->message, reply->message, length);
848			break;
849		default:
850			memcpy(msg->message, &error_reply,
851			       sizeof(error_reply));
852		}
853	} else
854		memcpy(msg->message, reply->message, sizeof(error_reply));
855out:
856	complete(&(resp_type->work));
857}
858
859/**
860 * This function is called from the AP bus code after a crypto request
861 * "msg" has finished with the reply message "reply".
862 * It is called from tasklet context.
863 * @ap_dev: pointer to the AP device
864 * @msg: pointer to the AP message
865 * @reply: pointer to the AP reply message
866 */
867static void zcrypt_msgtype6_receive_ep11(struct ap_device *ap_dev,
868					 struct ap_message *msg,
869					 struct ap_message *reply)
870{
871	static struct error_hdr error_reply = {
872		.type = TYPE82_RSP_CODE,
873		.reply_code = REP82_ERROR_MACHINE_FAILURE,
874	};
875	struct response_type *resp_type =
876		(struct response_type *)msg->private;
877	struct type86_ep11_reply *t86r;
878	int length;
879
880	/* Copy the reply message to the request message buffer. */
881	if (!reply)
882		goto out;	/* ap_msg->rc indicates the error */
883	t86r = reply->message;
884	if (t86r->hdr.type == TYPE86_RSP_CODE &&
885	    t86r->cprbx.cprb_ver_id == 0x04) {
886		switch (resp_type->type) {
887		case PCIXCC_RESPONSE_TYPE_EP11:
888			length = t86r->fmt2.offset1 + t86r->fmt2.count1;
889			length = min(MSGTYPE06_MAX_MSG_SIZE, length);
890			memcpy(msg->message, reply->message, length);
891			break;
892		default:
893			memcpy(msg->message, &error_reply, sizeof(error_reply));
894		}
895	} else {
896		memcpy(msg->message, reply->message, sizeof(error_reply));
897	  }
898out:
899	complete(&(resp_type->work));
900}
901
902static atomic_t zcrypt_step = ATOMIC_INIT(0);
903
904/**
905 * The request distributor calls this function if it picked the PCIXCC/CEX2C
906 * device to handle a modexpo request.
907 * @zdev: pointer to zcrypt_device structure that identifies the
908 *	  PCIXCC/CEX2C device to the request distributor
909 * @mex: pointer to the modexpo request buffer
910 */
911static long zcrypt_msgtype6_modexpo(struct zcrypt_device *zdev,
912				  struct ica_rsa_modexpo *mex)
913{
914	struct ap_message ap_msg;
915	struct response_type resp_type = {
916		.type = PCIXCC_RESPONSE_TYPE_ICA,
917	};
918	int rc;
919
920	ap_init_message(&ap_msg);
921	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
922	if (!ap_msg.message)
923		return -ENOMEM;
924	ap_msg.receive = zcrypt_msgtype6_receive;
925	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
926				atomic_inc_return(&zcrypt_step);
927	ap_msg.private = &resp_type;
928	rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
929	if (rc)
930		goto out_free;
931	init_completion(&resp_type.work);
932	ap_queue_message(zdev->ap_dev, &ap_msg);
933	rc = wait_for_completion_interruptible(&resp_type.work);
934	if (rc == 0) {
935		rc = ap_msg.rc;
936		if (rc == 0)
937			rc = convert_response_ica(zdev, &ap_msg,
938						  mex->outputdata,
939						  mex->outputdatalength);
940	} else
941		/* Signal pending. */
942		ap_cancel_message(zdev->ap_dev, &ap_msg);
943out_free:
944	free_page((unsigned long) ap_msg.message);
945	return rc;
946}
947
948/**
949 * The request distributor calls this function if it picked the PCIXCC/CEX2C
950 * device to handle a modexpo_crt request.
951 * @zdev: pointer to zcrypt_device structure that identifies the
952 *	  PCIXCC/CEX2C device to the request distributor
953 * @crt: pointer to the modexpoc_crt request buffer
954 */
955static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_device *zdev,
956				      struct ica_rsa_modexpo_crt *crt)
957{
958	struct ap_message ap_msg;
959	struct response_type resp_type = {
960		.type = PCIXCC_RESPONSE_TYPE_ICA,
961	};
962	int rc;
963
964	ap_init_message(&ap_msg);
965	ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
966	if (!ap_msg.message)
967		return -ENOMEM;
968	ap_msg.receive = zcrypt_msgtype6_receive;
969	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
970				atomic_inc_return(&zcrypt_step);
971	ap_msg.private = &resp_type;
972	rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
973	if (rc)
974		goto out_free;
975	init_completion(&resp_type.work);
976	ap_queue_message(zdev->ap_dev, &ap_msg);
977	rc = wait_for_completion_interruptible(&resp_type.work);
978	if (rc == 0) {
979		rc = ap_msg.rc;
980		if (rc == 0)
981			rc = convert_response_ica(zdev, &ap_msg,
982						  crt->outputdata,
983						  crt->outputdatalength);
984	} else
985		/* Signal pending. */
986		ap_cancel_message(zdev->ap_dev, &ap_msg);
987out_free:
988	free_page((unsigned long) ap_msg.message);
989	return rc;
990}
991
992/**
993 * The request distributor calls this function if it picked the PCIXCC/CEX2C
994 * device to handle a send_cprb request.
995 * @zdev: pointer to zcrypt_device structure that identifies the
996 *	  PCIXCC/CEX2C device to the request distributor
997 * @xcRB: pointer to the send_cprb request buffer
998 */
999static long zcrypt_msgtype6_send_cprb(struct zcrypt_device *zdev,
1000				    struct ica_xcRB *xcRB)
1001{
1002	struct ap_message ap_msg;
1003	struct response_type resp_type = {
1004		.type = PCIXCC_RESPONSE_TYPE_XCRB,
1005	};
1006	int rc;
1007
1008	ap_init_message(&ap_msg);
1009	ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1010	if (!ap_msg.message)
1011		return -ENOMEM;
1012	ap_msg.receive = zcrypt_msgtype6_receive;
1013	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1014				atomic_inc_return(&zcrypt_step);
1015	ap_msg.private = &resp_type;
1016	rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
1017	if (rc)
1018		goto out_free;
1019	init_completion(&resp_type.work);
1020	ap_queue_message(zdev->ap_dev, &ap_msg);
1021	rc = wait_for_completion_interruptible(&resp_type.work);
1022	if (rc == 0) {
1023		rc = ap_msg.rc;
1024		if (rc == 0)
1025			rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
1026	} else
1027		/* Signal pending. */
1028		ap_cancel_message(zdev->ap_dev, &ap_msg);
1029out_free:
1030	kzfree(ap_msg.message);
1031	return rc;
1032}
1033
1034/**
1035 * The request distributor calls this function if it picked the CEX4P
1036 * device to handle a send_ep11_cprb request.
1037 * @zdev: pointer to zcrypt_device structure that identifies the
1038 *	  CEX4P device to the request distributor
1039 * @xcRB: pointer to the ep11 user request block
1040 */
1041static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_device *zdev,
1042						struct ep11_urb *xcrb)
1043{
1044	struct ap_message ap_msg;
1045	struct response_type resp_type = {
1046		.type = PCIXCC_RESPONSE_TYPE_EP11,
1047	};
1048	int rc;
1049
1050	ap_init_message(&ap_msg);
1051	ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1052	if (!ap_msg.message)
1053		return -ENOMEM;
1054	ap_msg.receive = zcrypt_msgtype6_receive_ep11;
1055	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1056				atomic_inc_return(&zcrypt_step);
1057	ap_msg.private = &resp_type;
1058	rc = xcrb_msg_to_type6_ep11cprb_msgx(zdev, &ap_msg, xcrb);
1059	if (rc)
1060		goto out_free;
1061	init_completion(&resp_type.work);
1062	ap_queue_message(zdev->ap_dev, &ap_msg);
1063	rc = wait_for_completion_interruptible(&resp_type.work);
1064	if (rc == 0) {
1065		rc = ap_msg.rc;
1066		if (rc == 0)
1067			rc = convert_response_ep11_xcrb(zdev, &ap_msg, xcrb);
1068	} else
1069		/* Signal pending. */
1070		ap_cancel_message(zdev->ap_dev, &ap_msg);
1071
1072out_free:
1073	kzfree(ap_msg.message);
1074	return rc;
1075}
1076
1077/**
1078 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1079 * device to generate random data.
1080 * @zdev: pointer to zcrypt_device structure that identifies the
1081 *	  PCIXCC/CEX2C device to the request distributor
1082 * @buffer: pointer to a memory page to return random data
1083 */
1084
1085static long zcrypt_msgtype6_rng(struct zcrypt_device *zdev,
1086				    char *buffer)
1087{
1088	struct ap_message ap_msg;
1089	struct response_type resp_type = {
1090		.type = PCIXCC_RESPONSE_TYPE_XCRB,
1091	};
1092	int rc;
1093
1094	ap_init_message(&ap_msg);
1095	ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1096	if (!ap_msg.message)
1097		return -ENOMEM;
1098	ap_msg.receive = zcrypt_msgtype6_receive;
1099	ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1100				atomic_inc_return(&zcrypt_step);
1101	ap_msg.private = &resp_type;
1102	rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
1103	init_completion(&resp_type.work);
1104	ap_queue_message(zdev->ap_dev, &ap_msg);
1105	rc = wait_for_completion_interruptible(&resp_type.work);
1106	if (rc == 0) {
1107		rc = ap_msg.rc;
1108		if (rc == 0)
1109			rc = convert_response_rng(zdev, &ap_msg, buffer);
1110	} else
1111		/* Signal pending. */
1112		ap_cancel_message(zdev->ap_dev, &ap_msg);
1113	kfree(ap_msg.message);
1114	return rc;
1115}
1116
1117/**
1118 * The crypto operations for a PCIXCC/CEX2C card.
1119 */
1120static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
1121	.owner = THIS_MODULE,
1122	.name = MSGTYPE06_NAME,
1123	.variant = MSGTYPE06_VARIANT_NORNG,
1124	.rsa_modexpo = zcrypt_msgtype6_modexpo,
1125	.rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1126	.send_cprb = zcrypt_msgtype6_send_cprb,
1127};
1128
1129static struct zcrypt_ops zcrypt_msgtype6_ops = {
1130	.owner = THIS_MODULE,
1131	.name = MSGTYPE06_NAME,
1132	.variant = MSGTYPE06_VARIANT_DEFAULT,
1133	.rsa_modexpo = zcrypt_msgtype6_modexpo,
1134	.rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1135	.send_cprb = zcrypt_msgtype6_send_cprb,
1136	.rng = zcrypt_msgtype6_rng,
1137};
1138
1139static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = {
1140	.owner = THIS_MODULE,
1141	.name = MSGTYPE06_NAME,
1142	.variant = MSGTYPE06_VARIANT_EP11,
1143	.rsa_modexpo = NULL,
1144	.rsa_modexpo_crt = NULL,
1145	.send_ep11_cprb = zcrypt_msgtype6_send_ep11_cprb,
1146};
1147
1148int __init zcrypt_msgtype6_init(void)
1149{
1150	zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
1151	zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
1152	zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops);
1153	return 0;
1154}
1155
1156void __exit zcrypt_msgtype6_exit(void)
1157{
1158	zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
1159	zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
1160	zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops);
1161}
1162
1163module_init(zcrypt_msgtype6_init);
1164module_exit(zcrypt_msgtype6_exit);
1165