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