• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
50 struct 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 
58 MODULE_AUTHOR("IBM Corporation");
59 MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
60 		   "Copyright IBM Corp. 2001, 2012");
61 MODULE_LICENSE("GPL");
62 
63 static 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  */
78 struct 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 
123 struct 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  */
146 static 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  */
ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device * zdev,struct ap_message * ap_msg,struct ica_rsa_modexpo * mex)161 static 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  */
ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device * zdev,struct ap_message * ap_msg,struct ica_rsa_modexpo_crt * crt)228 static 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  */
295 struct type86_fmt2_msg {
296 	struct type86_hdr hdr;
297 	struct type86_fmt2_ext fmt2;
298 } __packed;
299 
XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device * zdev,struct ap_message * ap_msg,struct ica_xcRB * xcRB)300 static 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 
xcrb_msg_to_type6_ep11cprb_msgx(struct zcrypt_device * zdev,struct ap_message * ap_msg,struct ep11_urb * xcRB)395 static 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  */
496 struct 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 
505 struct type86_ep11_reply {
506 	struct type86_hdr hdr;
507 	struct type86_fmt2_ext fmt2;
508 	struct ep11_cprb cprbx;
509 } __packed;
510 
convert_type86_ica(struct zcrypt_device * zdev,struct ap_message * reply,char __user * outputdata,unsigned int outputdatalength)511 static 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  */
convert_type86_xcrb(struct zcrypt_device * zdev,struct ap_message * reply,struct ica_xcRB * xcRB)620 static 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  */
convert_type86_ep11_xcrb(struct zcrypt_device * zdev,struct ap_message * reply,struct ep11_urb * xcRB)651 static 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 
convert_type86_rng(struct zcrypt_device * zdev,struct ap_message * reply,char * buffer)669 static 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 
convert_response_ica(struct zcrypt_device * zdev,struct ap_message * reply,char __user * outputdata,unsigned int outputdatalength)686 static 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 
convert_response_xcrb(struct zcrypt_device * zdev,struct ap_message * reply,struct ica_xcRB * xcRB)725 static 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 
convert_response_ep11_xcrb(struct zcrypt_device * zdev,struct ap_message * reply,struct ep11_urb * xcRB)757 static 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 
convert_response_rng(struct zcrypt_device * zdev,struct ap_message * reply,char * data)783 static 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  */
zcrypt_msgtype6_receive(struct ap_device * ap_dev,struct ap_message * msg,struct ap_message * reply)818 static 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));
857 out:
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  */
zcrypt_msgtype6_receive_ep11(struct ap_device * ap_dev,struct ap_message * msg,struct ap_message * reply)869 static 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 	  }
902 out:
903 	complete(&(resp_type->work));
904 }
905 
906 static 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  */
zcrypt_msgtype6_modexpo(struct zcrypt_device * zdev,struct ica_rsa_modexpo * mex)915 static 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);
944 out_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  */
zcrypt_msgtype6_modexpo_crt(struct zcrypt_device * zdev,struct ica_rsa_modexpo_crt * crt)956 static 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);
985 out_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  */
zcrypt_msgtype6_send_cprb(struct zcrypt_device * zdev,struct ica_xcRB * xcRB)997 static 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);
1025 out_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  */
zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_device * zdev,struct ep11_urb * xcrb)1037 static 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 
1065 out_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 
zcrypt_msgtype6_rng(struct zcrypt_device * zdev,char * buffer)1078 static 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  */
1111 static 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 
1119 static 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 
1128 static 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 
zcrypt_msgtype6_init(void)1136 int __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 
zcrypt_msgtype6_exit(void)1144 void __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 
1151 module_init(zcrypt_msgtype6_init);
1152 module_exit(zcrypt_msgtype6_exit);
1153