rtc: ds1307: factor out century bit handling
[linux-2.6/btrfs-unstable.git] / drivers / s390 / crypto / zcrypt_msgtype6.c
blobe5563ffeb8398158485e2842502479199608ebff
1 /*
2 * zcrypt 2.1.0
4 * Copyright IBM Corp. 2001, 2012
5 * Author(s): Robert Burroughs
6 * Eric Rossman (edrossma@us.ibm.com)
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>
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.
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.
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.
28 #define KMSG_COMPONENT "zcrypt"
29 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
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>
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"
45 #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
46 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
48 #define CEIL4(x) ((((x)+3)/4)*4)
50 struct response_type {
51 struct completion work;
52 int type;
54 #define PCIXCC_RESPONSE_TYPE_ICA 0
55 #define PCIXCC_RESPONSE_TYPE_XCRB 1
56 #define PCIXCC_RESPONSE_TYPE_EP11 2
58 MODULE_AUTHOR("IBM Corporation");
59 MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
60 "Copyright IBM Corp. 2001, 2012");
61 MODULE_LICENSE("GPL");
63 /**
64 * CPRB
65 * Note that all shorts, ints and longs are little-endian.
66 * All pointer fields are 32-bits long, and mean nothing
68 * A request CPRB is followed by a request_parameter_block.
70 * The request (or reply) parameter block is organized thus:
71 * function code
72 * VUD block
73 * key block
75 struct CPRB {
76 unsigned short cprb_len; /* CPRB length */
77 unsigned char cprb_ver_id; /* CPRB version id. */
78 unsigned char pad_000; /* Alignment pad byte. */
79 unsigned char srpi_rtcode[4]; /* SRPI return code LELONG */
80 unsigned char srpi_verb; /* SRPI verb type */
81 unsigned char flags; /* flags */
82 unsigned char func_id[2]; /* function id */
83 unsigned char checkpoint_flag; /* */
84 unsigned char resv2; /* reserved */
85 unsigned short req_parml; /* request parameter buffer */
86 /* length 16-bit little endian */
87 unsigned char req_parmp[4]; /* request parameter buffer *
88 * pointer (means nothing: the *
89 * parameter buffer follows *
90 * the CPRB). */
91 unsigned char req_datal[4]; /* request data buffer */
92 /* length ULELONG */
93 unsigned char req_datap[4]; /* request data buffer */
94 /* pointer */
95 unsigned short rpl_parml; /* reply parameter buffer */
96 /* length 16-bit little endian */
97 unsigned char pad_001[2]; /* Alignment pad bytes. ULESHORT */
98 unsigned char rpl_parmp[4]; /* reply parameter buffer *
99 * pointer (means nothing: the *
100 * parameter buffer follows *
101 * the CPRB). */
102 unsigned char rpl_datal[4]; /* reply data buffer len ULELONG */
103 unsigned char rpl_datap[4]; /* reply data buffer */
104 /* pointer */
105 unsigned short ccp_rscode; /* server reason code ULESHORT */
106 unsigned short ccp_rtcode; /* server return code ULESHORT */
107 unsigned char repd_parml[2]; /* replied parameter len ULESHORT*/
108 unsigned char mac_data_len[2]; /* Mac Data Length ULESHORT */
109 unsigned char repd_datal[4]; /* replied data length ULELONG */
110 unsigned char req_pc[2]; /* PC identifier */
111 unsigned char res_origin[8]; /* resource origin */
112 unsigned char mac_value[8]; /* Mac Value */
113 unsigned char logon_id[8]; /* Logon Identifier */
114 unsigned char usage_domain[2]; /* cdx */
115 unsigned char resv3[18]; /* reserved for requestor */
116 unsigned short svr_namel; /* server name length ULESHORT */
117 unsigned char svr_name[8]; /* server name */
118 } __packed;
120 struct function_and_rules_block {
121 unsigned char function_code[2];
122 unsigned short ulen;
123 unsigned char only_rule[8];
124 } __packed;
127 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
128 * card in a type6 message. The 3 fields that must be filled in at execution
129 * time are req_parml, rpl_parml and usage_domain.
130 * Everything about this interface is ascii/big-endian, since the
131 * device does *not* have 'Intel inside'.
133 * The CPRBX is followed immediately by the parm block.
134 * The parm block contains:
135 * - function code ('PD' 0x5044 or 'PK' 0x504B)
136 * - rule block (one of:)
137 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
138 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
139 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
140 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
141 * - VUD block
143 static struct CPRBX static_cprbx = {
144 .cprb_len = 0x00DC,
145 .cprb_ver_id = 0x02,
146 .func_id = {0x54, 0x32},
149 int speed_idx_cca(int req_type)
151 switch (req_type) {
152 case 0x4142:
153 case 0x4149:
154 case 0x414D:
155 case 0x4341:
156 case 0x4344:
157 case 0x4354:
158 case 0x4358:
159 case 0x444B:
160 case 0x4558:
161 case 0x4643:
162 case 0x4651:
163 case 0x4C47:
164 case 0x4C4B:
165 case 0x4C51:
166 case 0x4F48:
167 case 0x504F:
168 case 0x5053:
169 case 0x5058:
170 case 0x5343:
171 case 0x5344:
172 case 0x5345:
173 case 0x5350:
174 return LOW;
175 case 0x414B:
176 case 0x4345:
177 case 0x4349:
178 case 0x434D:
179 case 0x4847:
180 case 0x4849:
181 case 0x484D:
182 case 0x4850:
183 case 0x4851:
184 case 0x4954:
185 case 0x4958:
186 case 0x4B43:
187 case 0x4B44:
188 case 0x4B45:
189 case 0x4B47:
190 case 0x4B48:
191 case 0x4B49:
192 case 0x4B4E:
193 case 0x4B50:
194 case 0x4B52:
195 case 0x4B54:
196 case 0x4B58:
197 case 0x4D50:
198 case 0x4D53:
199 case 0x4D56:
200 case 0x4D58:
201 case 0x5044:
202 case 0x5045:
203 case 0x5046:
204 case 0x5047:
205 case 0x5049:
206 case 0x504B:
207 case 0x504D:
208 case 0x5254:
209 case 0x5347:
210 case 0x5349:
211 case 0x534B:
212 case 0x534D:
213 case 0x5356:
214 case 0x5358:
215 case 0x5443:
216 case 0x544B:
217 case 0x5647:
218 return HIGH;
219 default:
220 return MEDIUM;
224 int speed_idx_ep11(int req_type)
226 switch (req_type) {
227 case 1:
228 case 2:
229 case 36:
230 case 37:
231 case 38:
232 case 39:
233 case 40:
234 return LOW;
235 case 17:
236 case 18:
237 case 19:
238 case 20:
239 case 21:
240 case 22:
241 case 26:
242 case 30:
243 case 31:
244 case 32:
245 case 33:
246 case 34:
247 case 35:
248 return HIGH;
249 default:
250 return MEDIUM;
256 * Convert a ICAMEX message to a type6 MEX message.
258 * @zq: crypto device pointer
259 * @ap_msg: pointer to AP message
260 * @mex: pointer to user input data
262 * Returns 0 on success or -EFAULT.
264 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_queue *zq,
265 struct ap_message *ap_msg,
266 struct ica_rsa_modexpo *mex)
268 static struct type6_hdr static_type6_hdrX = {
269 .type = 0x06,
270 .offset1 = 0x00000058,
271 .agent_id = {'C', 'A',},
272 .function_code = {'P', 'K'},
274 static struct function_and_rules_block static_pke_fnr = {
275 .function_code = {'P', 'K'},
276 .ulen = 10,
277 .only_rule = {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '}
279 struct {
280 struct type6_hdr hdr;
281 struct CPRBX cprbx;
282 struct function_and_rules_block fr;
283 unsigned short length;
284 char text[0];
285 } __packed * msg = ap_msg->message;
286 int size;
288 /* VUD.ciphertext */
289 msg->length = mex->inputdatalength + 2;
290 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
291 return -EFAULT;
293 /* Set up key which is located after the variable length text. */
294 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
295 if (size < 0)
296 return size;
297 size += sizeof(*msg) + mex->inputdatalength;
299 /* message header, cprbx and f&r */
300 msg->hdr = static_type6_hdrX;
301 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
302 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
304 msg->cprbx = static_cprbx;
305 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
306 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
308 msg->fr = static_pke_fnr;
310 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
312 ap_msg->length = size;
313 return 0;
317 * Convert a ICACRT message to a type6 CRT message.
319 * @zq: crypto device pointer
320 * @ap_msg: pointer to AP message
321 * @crt: pointer to user input data
323 * Returns 0 on success or -EFAULT.
325 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_queue *zq,
326 struct ap_message *ap_msg,
327 struct ica_rsa_modexpo_crt *crt)
329 static struct type6_hdr static_type6_hdrX = {
330 .type = 0x06,
331 .offset1 = 0x00000058,
332 .agent_id = {'C', 'A',},
333 .function_code = {'P', 'D'},
335 static struct function_and_rules_block static_pkd_fnr = {
336 .function_code = {'P', 'D'},
337 .ulen = 10,
338 .only_rule = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
341 struct {
342 struct type6_hdr hdr;
343 struct CPRBX cprbx;
344 struct function_and_rules_block fr;
345 unsigned short length;
346 char text[0];
347 } __packed * msg = ap_msg->message;
348 int size;
350 /* VUD.ciphertext */
351 msg->length = crt->inputdatalength + 2;
352 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
353 return -EFAULT;
355 /* Set up key which is located after the variable length text. */
356 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
357 if (size < 0)
358 return size;
359 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
361 /* message header, cprbx and f&r */
362 msg->hdr = static_type6_hdrX;
363 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
364 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
366 msg->cprbx = static_cprbx;
367 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
368 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
369 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
371 msg->fr = static_pkd_fnr;
373 ap_msg->length = size;
374 return 0;
378 * Convert a XCRB message to a type6 CPRB message.
380 * @zq: crypto device pointer
381 * @ap_msg: pointer to AP message
382 * @xcRB: pointer to user input data
384 * Returns 0 on success or -EFAULT, -EINVAL.
386 struct type86_fmt2_msg {
387 struct type86_hdr hdr;
388 struct type86_fmt2_ext fmt2;
389 } __packed;
391 static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg,
392 struct ica_xcRB *xcRB,
393 unsigned int *fcode,
394 unsigned short **dom)
396 static struct type6_hdr static_type6_hdrX = {
397 .type = 0x06,
398 .offset1 = 0x00000058,
400 struct {
401 struct type6_hdr hdr;
402 struct CPRBX cprbx;
403 } __packed * msg = ap_msg->message;
405 int rcblen = CEIL4(xcRB->request_control_blk_length);
406 int replylen, req_sumlen, resp_sumlen;
407 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
408 char *function_code;
410 if (CEIL4(xcRB->request_control_blk_length) <
411 xcRB->request_control_blk_length)
412 return -EINVAL; /* overflow after alignment*/
414 /* length checks */
415 ap_msg->length = sizeof(struct type6_hdr) +
416 CEIL4(xcRB->request_control_blk_length) +
417 xcRB->request_data_length;
418 if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE)
419 return -EINVAL;
421 /* Overflow check
422 sum must be greater (or equal) than the largest operand */
423 req_sumlen = CEIL4(xcRB->request_control_blk_length) +
424 xcRB->request_data_length;
425 if ((CEIL4(xcRB->request_control_blk_length) <=
426 xcRB->request_data_length) ?
427 (req_sumlen < xcRB->request_data_length) :
428 (req_sumlen < CEIL4(xcRB->request_control_blk_length))) {
429 return -EINVAL;
432 if (CEIL4(xcRB->reply_control_blk_length) <
433 xcRB->reply_control_blk_length)
434 return -EINVAL; /* overflow after alignment*/
436 replylen = sizeof(struct type86_fmt2_msg) +
437 CEIL4(xcRB->reply_control_blk_length) +
438 xcRB->reply_data_length;
439 if (replylen > MSGTYPE06_MAX_MSG_SIZE)
440 return -EINVAL;
442 /* Overflow check
443 sum must be greater (or equal) than the largest operand */
444 resp_sumlen = CEIL4(xcRB->reply_control_blk_length) +
445 xcRB->reply_data_length;
446 if ((CEIL4(xcRB->reply_control_blk_length) <= xcRB->reply_data_length) ?
447 (resp_sumlen < xcRB->reply_data_length) :
448 (resp_sumlen < CEIL4(xcRB->reply_control_blk_length))) {
449 return -EINVAL;
452 /* prepare type6 header */
453 msg->hdr = static_type6_hdrX;
454 memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
455 msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
456 if (xcRB->request_data_length) {
457 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
458 msg->hdr.ToCardLen2 = xcRB->request_data_length;
460 msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
461 msg->hdr.FromCardLen2 = xcRB->reply_data_length;
463 /* prepare CPRB */
464 if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
465 xcRB->request_control_blk_length))
466 return -EFAULT;
467 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
468 xcRB->request_control_blk_length)
469 return -EINVAL;
470 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
471 memcpy(msg->hdr.function_code, function_code,
472 sizeof(msg->hdr.function_code));
474 *fcode = (msg->hdr.function_code[0] << 8) | msg->hdr.function_code[1];
475 *dom = (unsigned short *)&msg->cprbx.domain;
477 if (memcmp(function_code, "US", 2) == 0)
478 ap_msg->special = 1;
479 else
480 ap_msg->special = 0;
482 /* copy data block */
483 if (xcRB->request_data_length &&
484 copy_from_user(req_data, xcRB->request_data_address,
485 xcRB->request_data_length))
486 return -EFAULT;
488 return 0;
491 static int xcrb_msg_to_type6_ep11cprb_msgx(struct ap_message *ap_msg,
492 struct ep11_urb *xcRB,
493 unsigned int *fcode)
495 unsigned int lfmt;
496 static struct type6_hdr static_type6_ep11_hdr = {
497 .type = 0x06,
498 .rqid = {0x00, 0x01},
499 .function_code = {0x00, 0x00},
500 .agent_id[0] = 0x58, /* {'X'} */
501 .agent_id[1] = 0x43, /* {'C'} */
502 .offset1 = 0x00000058,
505 struct {
506 struct type6_hdr hdr;
507 struct ep11_cprb cprbx;
508 unsigned char pld_tag; /* fixed value 0x30 */
509 unsigned char pld_lenfmt; /* payload length format */
510 } __packed * msg = ap_msg->message;
512 struct pld_hdr {
513 unsigned char func_tag; /* fixed value 0x4 */
514 unsigned char func_len; /* fixed value 0x4 */
515 unsigned int func_val; /* function ID */
516 unsigned char dom_tag; /* fixed value 0x4 */
517 unsigned char dom_len; /* fixed value 0x4 */
518 unsigned int dom_val; /* domain id */
519 } __packed * payload_hdr = NULL;
521 if (CEIL4(xcRB->req_len) < xcRB->req_len)
522 return -EINVAL; /* overflow after alignment*/
524 /* length checks */
525 ap_msg->length = sizeof(struct type6_hdr) + xcRB->req_len;
526 if (CEIL4(xcRB->req_len) > MSGTYPE06_MAX_MSG_SIZE -
527 (sizeof(struct type6_hdr)))
528 return -EINVAL;
530 if (CEIL4(xcRB->resp_len) < xcRB->resp_len)
531 return -EINVAL; /* overflow after alignment*/
533 if (CEIL4(xcRB->resp_len) > MSGTYPE06_MAX_MSG_SIZE -
534 (sizeof(struct type86_fmt2_msg)))
535 return -EINVAL;
537 /* prepare type6 header */
538 msg->hdr = static_type6_ep11_hdr;
539 msg->hdr.ToCardLen1 = xcRB->req_len;
540 msg->hdr.FromCardLen1 = xcRB->resp_len;
542 /* Import CPRB data from the ioctl input parameter */
543 if (copy_from_user(&(msg->cprbx.cprb_len),
544 (char __force __user *)xcRB->req, xcRB->req_len)) {
545 return -EFAULT;
548 if ((msg->pld_lenfmt & 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/
549 switch (msg->pld_lenfmt & 0x03) {
550 case 1:
551 lfmt = 2;
552 break;
553 case 2:
554 lfmt = 3;
555 break;
556 default:
557 return -EINVAL;
559 } else {
560 lfmt = 1; /* length format #1 */
562 payload_hdr = (struct pld_hdr *)((&(msg->pld_lenfmt))+lfmt);
563 *fcode = payload_hdr->func_val & 0xFFFF;
565 return 0;
569 * Copy results from a type 86 ICA reply message back to user space.
571 * @zq: crypto device pointer
572 * @reply: reply AP message.
573 * @data: pointer to user output data
574 * @length: size of user output data
576 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
578 struct type86x_reply {
579 struct type86_hdr hdr;
580 struct type86_fmt2_ext fmt2;
581 struct CPRBX cprbx;
582 unsigned char pad[4]; /* 4 byte function code/rules block ? */
583 unsigned short length;
584 char text[0];
585 } __packed;
587 struct type86_ep11_reply {
588 struct type86_hdr hdr;
589 struct type86_fmt2_ext fmt2;
590 struct ep11_cprb cprbx;
591 } __packed;
593 static int convert_type86_ica(struct zcrypt_queue *zq,
594 struct ap_message *reply,
595 char __user *outputdata,
596 unsigned int outputdatalength)
598 static unsigned char static_pad[] = {
599 0x00, 0x02,
600 0x1B, 0x7B, 0x5D, 0xB5, 0x75, 0x01, 0x3D, 0xFD,
601 0x8D, 0xD1, 0xC7, 0x03, 0x2D, 0x09, 0x23, 0x57,
602 0x89, 0x49, 0xB9, 0x3F, 0xBB, 0x99, 0x41, 0x5B,
603 0x75, 0x21, 0x7B, 0x9D, 0x3B, 0x6B, 0x51, 0x39,
604 0xBB, 0x0D, 0x35, 0xB9, 0x89, 0x0F, 0x93, 0xA5,
605 0x0B, 0x47, 0xF1, 0xD3, 0xBB, 0xCB, 0xF1, 0x9D,
606 0x23, 0x73, 0x71, 0xFF, 0xF3, 0xF5, 0x45, 0xFB,
607 0x61, 0x29, 0x23, 0xFD, 0xF1, 0x29, 0x3F, 0x7F,
608 0x17, 0xB7, 0x1B, 0xA9, 0x19, 0xBD, 0x57, 0xA9,
609 0xD7, 0x95, 0xA3, 0xCB, 0xED, 0x1D, 0xDB, 0x45,
610 0x7D, 0x11, 0xD1, 0x51, 0x1B, 0xED, 0x71, 0xE9,
611 0xB1, 0xD1, 0xAB, 0xAB, 0x21, 0x2B, 0x1B, 0x9F,
612 0x3B, 0x9F, 0xF7, 0xF7, 0xBD, 0x63, 0xEB, 0xAD,
613 0xDF, 0xB3, 0x6F, 0x5B, 0xDB, 0x8D, 0xA9, 0x5D,
614 0xE3, 0x7D, 0x77, 0x49, 0x47, 0xF5, 0xA7, 0xFD,
615 0xAB, 0x2F, 0x27, 0x35, 0x77, 0xD3, 0x49, 0xC9,
616 0x09, 0xEB, 0xB1, 0xF9, 0xBF, 0x4B, 0xCB, 0x2B,
617 0xEB, 0xEB, 0x05, 0xFF, 0x7D, 0xC7, 0x91, 0x8B,
618 0x09, 0x83, 0xB9, 0xB9, 0x69, 0x33, 0x39, 0x6B,
619 0x79, 0x75, 0x19, 0xBF, 0xBB, 0x07, 0x1D, 0xBD,
620 0x29, 0xBF, 0x39, 0x95, 0x93, 0x1D, 0x35, 0xC7,
621 0xC9, 0x4D, 0xE5, 0x97, 0x0B, 0x43, 0x9B, 0xF1,
622 0x16, 0x93, 0x03, 0x1F, 0xA5, 0xFB, 0xDB, 0xF3,
623 0x27, 0x4F, 0x27, 0x61, 0x05, 0x1F, 0xB9, 0x23,
624 0x2F, 0xC3, 0x81, 0xA9, 0x23, 0x71, 0x55, 0x55,
625 0xEB, 0xED, 0x41, 0xE5, 0xF3, 0x11, 0xF1, 0x43,
626 0x69, 0x03, 0xBD, 0x0B, 0x37, 0x0F, 0x51, 0x8F,
627 0x0B, 0xB5, 0x89, 0x5B, 0x67, 0xA9, 0xD9, 0x4F,
628 0x01, 0xF9, 0x21, 0x77, 0x37, 0x73, 0x79, 0xC5,
629 0x7F, 0x51, 0xC1, 0xCF, 0x97, 0xA1, 0x75, 0xAD,
630 0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41,
631 0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09
633 struct type86x_reply *msg = reply->message;
634 unsigned short service_rc, service_rs;
635 unsigned int reply_len, pad_len;
636 char *data;
638 service_rc = msg->cprbx.ccp_rtcode;
639 if (unlikely(service_rc != 0)) {
640 service_rs = msg->cprbx.ccp_rscode;
641 if ((service_rc == 8 && service_rs == 66) ||
642 (service_rc == 8 && service_rs == 65) ||
643 (service_rc == 8 && service_rs == 72) ||
644 (service_rc == 8 && service_rs == 770) ||
645 (service_rc == 12 && service_rs == 769)) {
646 ZCRYPT_DBF(DBF_DEBUG,
647 "device=%02x.%04x rc/rs=%d/%d => rc=EINVAL\n",
648 AP_QID_CARD(zq->queue->qid),
649 AP_QID_QUEUE(zq->queue->qid),
650 (int) service_rc, (int) service_rs);
651 return -EINVAL;
653 if (service_rc == 8 && service_rs == 783) {
654 zq->zcard->min_mod_size =
655 PCIXCC_MIN_MOD_SIZE_OLD;
656 ZCRYPT_DBF(DBF_DEBUG,
657 "device=%02x.%04x rc/rs=%d/%d => rc=EAGAIN\n",
658 AP_QID_CARD(zq->queue->qid),
659 AP_QID_QUEUE(zq->queue->qid),
660 (int) service_rc, (int) service_rs);
661 return -EAGAIN;
663 zq->online = 0;
664 pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
665 AP_QID_CARD(zq->queue->qid),
666 AP_QID_QUEUE(zq->queue->qid));
667 ZCRYPT_DBF(DBF_ERR,
668 "device=%02x.%04x rc/rs=%d/%d => online=0 rc=EAGAIN\n",
669 AP_QID_CARD(zq->queue->qid),
670 AP_QID_QUEUE(zq->queue->qid),
671 (int) service_rc, (int) service_rs);
672 return -EAGAIN; /* repeat the request on a different device. */
674 data = msg->text;
675 reply_len = msg->length - 2;
676 if (reply_len > outputdatalength)
677 return -EINVAL;
679 * For all encipher requests, the length of the ciphertext (reply_len)
680 * will always equal the modulus length. For MEX decipher requests
681 * the output needs to get padded. Minimum pad size is 10.
683 * Currently, the cases where padding will be added is for:
684 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
685 * ZERO-PAD and CRT is only supported for PKD requests)
686 * - PCICC, always
688 pad_len = outputdatalength - reply_len;
689 if (pad_len > 0) {
690 if (pad_len < 10)
691 return -EINVAL;
692 /* 'restore' padding left in the PCICC/PCIXCC card. */
693 if (copy_to_user(outputdata, static_pad, pad_len - 1))
694 return -EFAULT;
695 if (put_user(0, outputdata + pad_len - 1))
696 return -EFAULT;
698 /* Copy the crypto response to user space. */
699 if (copy_to_user(outputdata + pad_len, data, reply_len))
700 return -EFAULT;
701 return 0;
705 * Copy results from a type 86 XCRB reply message back to user space.
707 * @zq: crypto device pointer
708 * @reply: reply AP message.
709 * @xcRB: pointer to XCRB
711 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
713 static int convert_type86_xcrb(struct zcrypt_queue *zq,
714 struct ap_message *reply,
715 struct ica_xcRB *xcRB)
717 struct type86_fmt2_msg *msg = reply->message;
718 char *data = reply->message;
720 /* Copy CPRB to user */
721 if (copy_to_user(xcRB->reply_control_blk_addr,
722 data + msg->fmt2.offset1, msg->fmt2.count1))
723 return -EFAULT;
724 xcRB->reply_control_blk_length = msg->fmt2.count1;
726 /* Copy data buffer to user */
727 if (msg->fmt2.count2)
728 if (copy_to_user(xcRB->reply_data_addr,
729 data + msg->fmt2.offset2, msg->fmt2.count2))
730 return -EFAULT;
731 xcRB->reply_data_length = msg->fmt2.count2;
732 return 0;
736 * Copy results from a type 86 EP11 XCRB reply message back to user space.
738 * @zq: crypto device pointer
739 * @reply: reply AP message.
740 * @xcRB: pointer to EP11 user request block
742 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
744 static int convert_type86_ep11_xcrb(struct zcrypt_queue *zq,
745 struct ap_message *reply,
746 struct ep11_urb *xcRB)
748 struct type86_fmt2_msg *msg = reply->message;
749 char *data = reply->message;
751 if (xcRB->resp_len < msg->fmt2.count1)
752 return -EINVAL;
754 /* Copy response CPRB to user */
755 if (copy_to_user((char __force __user *)xcRB->resp,
756 data + msg->fmt2.offset1, msg->fmt2.count1))
757 return -EFAULT;
758 xcRB->resp_len = msg->fmt2.count1;
759 return 0;
762 static int convert_type86_rng(struct zcrypt_queue *zq,
763 struct ap_message *reply,
764 char *buffer)
766 struct {
767 struct type86_hdr hdr;
768 struct type86_fmt2_ext fmt2;
769 struct CPRBX cprbx;
770 } __packed * msg = reply->message;
771 char *data = reply->message;
773 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
774 return -EINVAL;
775 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
776 return msg->fmt2.count2;
779 static int convert_response_ica(struct zcrypt_queue *zq,
780 struct ap_message *reply,
781 char __user *outputdata,
782 unsigned int outputdatalength)
784 struct type86x_reply *msg = reply->message;
786 switch (msg->hdr.type) {
787 case TYPE82_RSP_CODE:
788 case TYPE88_RSP_CODE:
789 return convert_error(zq, reply);
790 case TYPE86_RSP_CODE:
791 if (msg->cprbx.ccp_rtcode &&
792 (msg->cprbx.ccp_rscode == 0x14f) &&
793 (outputdatalength > 256)) {
794 if (zq->zcard->max_exp_bit_length <= 17) {
795 zq->zcard->max_exp_bit_length = 17;
796 return -EAGAIN;
797 } else
798 return -EINVAL;
800 if (msg->hdr.reply_code)
801 return convert_error(zq, reply);
802 if (msg->cprbx.cprb_ver_id == 0x02)
803 return convert_type86_ica(zq, reply,
804 outputdata, outputdatalength);
805 /* Fall through, no break, incorrect cprb version is an unknown
806 * response */
807 default: /* Unknown response type, this should NEVER EVER happen */
808 zq->online = 0;
809 pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
810 AP_QID_CARD(zq->queue->qid),
811 AP_QID_QUEUE(zq->queue->qid));
812 ZCRYPT_DBF(DBF_ERR,
813 "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
814 AP_QID_CARD(zq->queue->qid),
815 AP_QID_QUEUE(zq->queue->qid),
816 (int) msg->hdr.type);
817 return -EAGAIN; /* repeat the request on a different device. */
821 static int convert_response_xcrb(struct zcrypt_queue *zq,
822 struct ap_message *reply,
823 struct ica_xcRB *xcRB)
825 struct type86x_reply *msg = reply->message;
827 switch (msg->hdr.type) {
828 case TYPE82_RSP_CODE:
829 case TYPE88_RSP_CODE:
830 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
831 return convert_error(zq, reply);
832 case TYPE86_RSP_CODE:
833 if (msg->hdr.reply_code) {
834 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
835 return convert_error(zq, reply);
837 if (msg->cprbx.cprb_ver_id == 0x02)
838 return convert_type86_xcrb(zq, reply, xcRB);
839 /* Fall through, no break, incorrect cprb version is an unknown
840 * response */
841 default: /* Unknown response type, this should NEVER EVER happen */
842 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
843 zq->online = 0;
844 pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
845 AP_QID_CARD(zq->queue->qid),
846 AP_QID_QUEUE(zq->queue->qid));
847 ZCRYPT_DBF(DBF_ERR,
848 "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
849 AP_QID_CARD(zq->queue->qid),
850 AP_QID_QUEUE(zq->queue->qid),
851 (int) msg->hdr.type);
852 return -EAGAIN; /* repeat the request on a different device. */
856 static int convert_response_ep11_xcrb(struct zcrypt_queue *zq,
857 struct ap_message *reply, struct ep11_urb *xcRB)
859 struct type86_ep11_reply *msg = reply->message;
861 switch (msg->hdr.type) {
862 case TYPE82_RSP_CODE:
863 case TYPE87_RSP_CODE:
864 return convert_error(zq, reply);
865 case TYPE86_RSP_CODE:
866 if (msg->hdr.reply_code)
867 return convert_error(zq, reply);
868 if (msg->cprbx.cprb_ver_id == 0x04)
869 return convert_type86_ep11_xcrb(zq, reply, xcRB);
870 /* Fall through, no break, incorrect cprb version is an unknown resp.*/
871 default: /* Unknown response type, this should NEVER EVER happen */
872 zq->online = 0;
873 pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
874 AP_QID_CARD(zq->queue->qid),
875 AP_QID_QUEUE(zq->queue->qid));
876 ZCRYPT_DBF(DBF_ERR,
877 "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
878 AP_QID_CARD(zq->queue->qid),
879 AP_QID_QUEUE(zq->queue->qid),
880 (int) msg->hdr.type);
881 return -EAGAIN; /* repeat the request on a different device. */
885 static int convert_response_rng(struct zcrypt_queue *zq,
886 struct ap_message *reply,
887 char *data)
889 struct type86x_reply *msg = reply->message;
891 switch (msg->hdr.type) {
892 case TYPE82_RSP_CODE:
893 case TYPE88_RSP_CODE:
894 return -EINVAL;
895 case TYPE86_RSP_CODE:
896 if (msg->hdr.reply_code)
897 return -EINVAL;
898 if (msg->cprbx.cprb_ver_id == 0x02)
899 return convert_type86_rng(zq, reply, data);
900 /* Fall through, no break, incorrect cprb version is an unknown
901 * response */
902 default: /* Unknown response type, this should NEVER EVER happen */
903 zq->online = 0;
904 pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
905 AP_QID_CARD(zq->queue->qid),
906 AP_QID_QUEUE(zq->queue->qid));
907 ZCRYPT_DBF(DBF_ERR,
908 "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n",
909 AP_QID_CARD(zq->queue->qid),
910 AP_QID_QUEUE(zq->queue->qid),
911 (int) msg->hdr.type);
912 return -EAGAIN; /* repeat the request on a different device. */
917 * This function is called from the AP bus code after a crypto request
918 * "msg" has finished with the reply message "reply".
919 * It is called from tasklet context.
920 * @aq: pointer to the AP queue
921 * @msg: pointer to the AP message
922 * @reply: pointer to the AP reply message
924 static void zcrypt_msgtype6_receive(struct ap_queue *aq,
925 struct ap_message *msg,
926 struct ap_message *reply)
928 static struct error_hdr error_reply = {
929 .type = TYPE82_RSP_CODE,
930 .reply_code = REP82_ERROR_MACHINE_FAILURE,
932 struct response_type *resp_type =
933 (struct response_type *) msg->private;
934 struct type86x_reply *t86r;
935 int length;
937 /* Copy the reply message to the request message buffer. */
938 if (!reply)
939 goto out; /* ap_msg->rc indicates the error */
940 t86r = reply->message;
941 if (t86r->hdr.type == TYPE86_RSP_CODE &&
942 t86r->cprbx.cprb_ver_id == 0x02) {
943 switch (resp_type->type) {
944 case PCIXCC_RESPONSE_TYPE_ICA:
945 length = sizeof(struct type86x_reply)
946 + t86r->length - 2;
947 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
948 memcpy(msg->message, reply->message, length);
949 break;
950 case PCIXCC_RESPONSE_TYPE_XCRB:
951 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
952 length = min(MSGTYPE06_MAX_MSG_SIZE, length);
953 memcpy(msg->message, reply->message, length);
954 break;
955 default:
956 memcpy(msg->message, &error_reply,
957 sizeof(error_reply));
959 } else
960 memcpy(msg->message, reply->message, sizeof(error_reply));
961 out:
962 complete(&(resp_type->work));
966 * This function is called from the AP bus code after a crypto request
967 * "msg" has finished with the reply message "reply".
968 * It is called from tasklet context.
969 * @aq: pointer to the AP queue
970 * @msg: pointer to the AP message
971 * @reply: pointer to the AP reply message
973 static void zcrypt_msgtype6_receive_ep11(struct ap_queue *aq,
974 struct ap_message *msg,
975 struct ap_message *reply)
977 static struct error_hdr error_reply = {
978 .type = TYPE82_RSP_CODE,
979 .reply_code = REP82_ERROR_MACHINE_FAILURE,
981 struct response_type *resp_type =
982 (struct response_type *)msg->private;
983 struct type86_ep11_reply *t86r;
984 int length;
986 /* Copy the reply message to the request message buffer. */
987 if (!reply)
988 goto out; /* ap_msg->rc indicates the error */
989 t86r = reply->message;
990 if (t86r->hdr.type == TYPE86_RSP_CODE &&
991 t86r->cprbx.cprb_ver_id == 0x04) {
992 switch (resp_type->type) {
993 case PCIXCC_RESPONSE_TYPE_EP11:
994 length = t86r->fmt2.offset1 + t86r->fmt2.count1;
995 length = min(MSGTYPE06_MAX_MSG_SIZE, length);
996 memcpy(msg->message, reply->message, length);
997 break;
998 default:
999 memcpy(msg->message, &error_reply, sizeof(error_reply));
1001 } else {
1002 memcpy(msg->message, reply->message, sizeof(error_reply));
1004 out:
1005 complete(&(resp_type->work));
1008 static atomic_t zcrypt_step = ATOMIC_INIT(0);
1011 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1012 * device to handle a modexpo request.
1013 * @zq: pointer to zcrypt_queue structure that identifies the
1014 * PCIXCC/CEX2C device to the request distributor
1015 * @mex: pointer to the modexpo request buffer
1017 static long zcrypt_msgtype6_modexpo(struct zcrypt_queue *zq,
1018 struct ica_rsa_modexpo *mex)
1020 struct ap_message ap_msg;
1021 struct response_type resp_type = {
1022 .type = PCIXCC_RESPONSE_TYPE_ICA,
1024 int rc;
1026 ap_init_message(&ap_msg);
1027 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
1028 if (!ap_msg.message)
1029 return -ENOMEM;
1030 ap_msg.receive = zcrypt_msgtype6_receive;
1031 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1032 atomic_inc_return(&zcrypt_step);
1033 ap_msg.private = &resp_type;
1034 rc = ICAMEX_msg_to_type6MEX_msgX(zq, &ap_msg, mex);
1035 if (rc)
1036 goto out_free;
1037 init_completion(&resp_type.work);
1038 ap_queue_message(zq->queue, &ap_msg);
1039 rc = wait_for_completion_interruptible(&resp_type.work);
1040 if (rc == 0) {
1041 rc = ap_msg.rc;
1042 if (rc == 0)
1043 rc = convert_response_ica(zq, &ap_msg,
1044 mex->outputdata,
1045 mex->outputdatalength);
1046 } else
1047 /* Signal pending. */
1048 ap_cancel_message(zq->queue, &ap_msg);
1049 out_free:
1050 free_page((unsigned long) ap_msg.message);
1051 return rc;
1055 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1056 * device to handle a modexpo_crt request.
1057 * @zq: pointer to zcrypt_queue structure that identifies the
1058 * PCIXCC/CEX2C device to the request distributor
1059 * @crt: pointer to the modexpoc_crt request buffer
1061 static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
1062 struct ica_rsa_modexpo_crt *crt)
1064 struct ap_message ap_msg;
1065 struct response_type resp_type = {
1066 .type = PCIXCC_RESPONSE_TYPE_ICA,
1068 int rc;
1070 ap_init_message(&ap_msg);
1071 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
1072 if (!ap_msg.message)
1073 return -ENOMEM;
1074 ap_msg.receive = zcrypt_msgtype6_receive;
1075 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
1076 atomic_inc_return(&zcrypt_step);
1077 ap_msg.private = &resp_type;
1078 rc = ICACRT_msg_to_type6CRT_msgX(zq, &ap_msg, crt);
1079 if (rc)
1080 goto out_free;
1081 init_completion(&resp_type.work);
1082 ap_queue_message(zq->queue, &ap_msg);
1083 rc = wait_for_completion_interruptible(&resp_type.work);
1084 if (rc == 0) {
1085 rc = ap_msg.rc;
1086 if (rc == 0)
1087 rc = convert_response_ica(zq, &ap_msg,
1088 crt->outputdata,
1089 crt->outputdatalength);
1090 } else {
1091 /* Signal pending. */
1092 ap_cancel_message(zq->queue, &ap_msg);
1094 out_free:
1095 free_page((unsigned long) ap_msg.message);
1096 return rc;
1099 unsigned int get_cprb_fc(struct ica_xcRB *xcRB,
1100 struct ap_message *ap_msg,
1101 unsigned int *func_code, unsigned short **dom)
1103 struct response_type resp_type = {
1104 .type = PCIXCC_RESPONSE_TYPE_XCRB,
1106 int rc;
1108 ap_init_message(ap_msg);
1109 ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1110 if (!ap_msg->message)
1111 return -ENOMEM;
1112 ap_msg->receive = zcrypt_msgtype6_receive;
1113 ap_msg->psmid = (((unsigned long long) current->pid) << 32) +
1114 atomic_inc_return(&zcrypt_step);
1115 ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL);
1116 if (!ap_msg->private) {
1117 kzfree(ap_msg->message);
1118 return -ENOMEM;
1120 memcpy(ap_msg->private, &resp_type, sizeof(resp_type));
1121 rc = XCRB_msg_to_type6CPRB_msgX(ap_msg, xcRB, func_code, dom);
1122 if (rc) {
1123 kzfree(ap_msg->message);
1124 kzfree(ap_msg->private);
1126 return rc;
1130 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1131 * device to handle a send_cprb request.
1132 * @zq: pointer to zcrypt_queue structure that identifies the
1133 * PCIXCC/CEX2C device to the request distributor
1134 * @xcRB: pointer to the send_cprb request buffer
1136 static long zcrypt_msgtype6_send_cprb(struct zcrypt_queue *zq,
1137 struct ica_xcRB *xcRB,
1138 struct ap_message *ap_msg)
1140 int rc;
1141 struct response_type *rtype = (struct response_type *)(ap_msg->private);
1143 init_completion(&rtype->work);
1144 ap_queue_message(zq->queue, ap_msg);
1145 rc = wait_for_completion_interruptible(&rtype->work);
1146 if (rc == 0) {
1147 rc = ap_msg->rc;
1148 if (rc == 0)
1149 rc = convert_response_xcrb(zq, ap_msg, xcRB);
1150 } else
1151 /* Signal pending. */
1152 ap_cancel_message(zq->queue, ap_msg);
1154 kzfree(ap_msg->message);
1155 kzfree(ap_msg->private);
1156 return rc;
1159 unsigned int get_ep11cprb_fc(struct ep11_urb *xcrb,
1160 struct ap_message *ap_msg,
1161 unsigned int *func_code)
1163 struct response_type resp_type = {
1164 .type = PCIXCC_RESPONSE_TYPE_EP11,
1166 int rc;
1168 ap_init_message(ap_msg);
1169 ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1170 if (!ap_msg->message)
1171 return -ENOMEM;
1172 ap_msg->receive = zcrypt_msgtype6_receive_ep11;
1173 ap_msg->psmid = (((unsigned long long) current->pid) << 32) +
1174 atomic_inc_return(&zcrypt_step);
1175 ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL);
1176 if (!ap_msg->private) {
1177 kzfree(ap_msg->message);
1178 return -ENOMEM;
1180 memcpy(ap_msg->private, &resp_type, sizeof(resp_type));
1181 rc = xcrb_msg_to_type6_ep11cprb_msgx(ap_msg, xcrb, func_code);
1182 if (rc) {
1183 kzfree(ap_msg->message);
1184 kzfree(ap_msg->private);
1186 return rc;
1190 * The request distributor calls this function if it picked the CEX4P
1191 * device to handle a send_ep11_cprb request.
1192 * @zq: pointer to zcrypt_queue structure that identifies the
1193 * CEX4P device to the request distributor
1194 * @xcRB: pointer to the ep11 user request block
1196 static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_queue *zq,
1197 struct ep11_urb *xcrb,
1198 struct ap_message *ap_msg)
1200 int rc;
1201 unsigned int lfmt;
1202 struct response_type *rtype = (struct response_type *)(ap_msg->private);
1203 struct {
1204 struct type6_hdr hdr;
1205 struct ep11_cprb cprbx;
1206 unsigned char pld_tag; /* fixed value 0x30 */
1207 unsigned char pld_lenfmt; /* payload length format */
1208 } __packed * msg = ap_msg->message;
1209 struct pld_hdr {
1210 unsigned char func_tag; /* fixed value 0x4 */
1211 unsigned char func_len; /* fixed value 0x4 */
1212 unsigned int func_val; /* function ID */
1213 unsigned char dom_tag; /* fixed value 0x4 */
1214 unsigned char dom_len; /* fixed value 0x4 */
1215 unsigned int dom_val; /* domain id */
1216 } __packed * payload_hdr = NULL;
1220 * The target domain field within the cprb body/payload block will be
1221 * replaced by the usage domain for non-management commands only.
1222 * Therefore we check the first bit of the 'flags' parameter for
1223 * management command indication.
1224 * 0 - non management command
1225 * 1 - management command
1227 if (!((msg->cprbx.flags & 0x80) == 0x80)) {
1228 msg->cprbx.target_id = (unsigned int)
1229 AP_QID_QUEUE(zq->queue->qid);
1231 if ((msg->pld_lenfmt & 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/
1232 switch (msg->pld_lenfmt & 0x03) {
1233 case 1:
1234 lfmt = 2;
1235 break;
1236 case 2:
1237 lfmt = 3;
1238 break;
1239 default:
1240 return -EINVAL;
1242 } else {
1243 lfmt = 1; /* length format #1 */
1245 payload_hdr = (struct pld_hdr *)((&(msg->pld_lenfmt))+lfmt);
1246 payload_hdr->dom_val = (unsigned int)
1247 AP_QID_QUEUE(zq->queue->qid);
1250 init_completion(&rtype->work);
1251 ap_queue_message(zq->queue, ap_msg);
1252 rc = wait_for_completion_interruptible(&rtype->work);
1253 if (rc == 0) {
1254 rc = ap_msg->rc;
1255 if (rc == 0)
1256 rc = convert_response_ep11_xcrb(zq, ap_msg, xcrb);
1257 } else
1258 /* Signal pending. */
1259 ap_cancel_message(zq->queue, ap_msg);
1261 kzfree(ap_msg->message);
1262 kzfree(ap_msg->private);
1263 return rc;
1266 unsigned int get_rng_fc(struct ap_message *ap_msg, int *func_code,
1267 unsigned int *domain)
1269 struct response_type resp_type = {
1270 .type = PCIXCC_RESPONSE_TYPE_XCRB,
1273 ap_init_message(ap_msg);
1274 ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
1275 if (!ap_msg->message)
1276 return -ENOMEM;
1277 ap_msg->receive = zcrypt_msgtype6_receive;
1278 ap_msg->psmid = (((unsigned long long) current->pid) << 32) +
1279 atomic_inc_return(&zcrypt_step);
1280 ap_msg->private = kmalloc(sizeof(resp_type), GFP_KERNEL);
1281 if (!ap_msg->private) {
1282 kzfree(ap_msg->message);
1283 return -ENOMEM;
1285 memcpy(ap_msg->private, &resp_type, sizeof(resp_type));
1287 rng_type6CPRB_msgX(ap_msg, ZCRYPT_RNG_BUFFER_SIZE, domain);
1289 *func_code = HWRNG;
1290 return 0;
1294 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1295 * device to generate random data.
1296 * @zq: pointer to zcrypt_queue structure that identifies the
1297 * PCIXCC/CEX2C device to the request distributor
1298 * @buffer: pointer to a memory page to return random data
1300 static long zcrypt_msgtype6_rng(struct zcrypt_queue *zq,
1301 char *buffer, struct ap_message *ap_msg)
1303 struct {
1304 struct type6_hdr hdr;
1305 struct CPRBX cprbx;
1306 char function_code[2];
1307 short int rule_length;
1308 char rule[8];
1309 short int verb_length;
1310 short int key_length;
1311 } __packed * msg = ap_msg->message;
1312 struct response_type *rtype = (struct response_type *)(ap_msg->private);
1313 int rc;
1315 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
1317 init_completion(&rtype->work);
1318 ap_queue_message(zq->queue, ap_msg);
1319 rc = wait_for_completion_interruptible(&rtype->work);
1320 if (rc == 0) {
1321 rc = ap_msg->rc;
1322 if (rc == 0)
1323 rc = convert_response_rng(zq, ap_msg, buffer);
1324 } else
1325 /* Signal pending. */
1326 ap_cancel_message(zq->queue, ap_msg);
1328 kzfree(ap_msg->message);
1329 kzfree(ap_msg->private);
1330 return rc;
1334 * The crypto operations for a PCIXCC/CEX2C card.
1336 static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
1337 .owner = THIS_MODULE,
1338 .name = MSGTYPE06_NAME,
1339 .variant = MSGTYPE06_VARIANT_NORNG,
1340 .rsa_modexpo = zcrypt_msgtype6_modexpo,
1341 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1342 .send_cprb = zcrypt_msgtype6_send_cprb,
1345 static struct zcrypt_ops zcrypt_msgtype6_ops = {
1346 .owner = THIS_MODULE,
1347 .name = MSGTYPE06_NAME,
1348 .variant = MSGTYPE06_VARIANT_DEFAULT,
1349 .rsa_modexpo = zcrypt_msgtype6_modexpo,
1350 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1351 .send_cprb = zcrypt_msgtype6_send_cprb,
1352 .rng = zcrypt_msgtype6_rng,
1355 static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = {
1356 .owner = THIS_MODULE,
1357 .name = MSGTYPE06_NAME,
1358 .variant = MSGTYPE06_VARIANT_EP11,
1359 .rsa_modexpo = NULL,
1360 .rsa_modexpo_crt = NULL,
1361 .send_ep11_cprb = zcrypt_msgtype6_send_ep11_cprb,
1364 void __init zcrypt_msgtype6_init(void)
1366 zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
1367 zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
1368 zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops);
1371 void __exit zcrypt_msgtype6_exit(void)
1373 zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
1374 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
1375 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops);