1 // SPDX-License-Identifier: GPL-2.0+
5 * Copyright IBM Corp. 2001, 2012
6 * Author(s): Robert Burroughs
7 * Eric Rossman (edrossma@us.ibm.com)
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>
15 #define KMSG_COMPONENT "zcrypt"
16 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
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>
27 #include "zcrypt_api.h"
28 #include "zcrypt_error.h"
29 #include "zcrypt_msgtype6.h"
30 #include "zcrypt_cca_key.h"
32 #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
33 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
35 #define CEIL4(x) ((((x)+3)/4)*4)
37 struct response_type
{
38 struct completion work
;
41 #define PCIXCC_RESPONSE_TYPE_ICA 0
42 #define PCIXCC_RESPONSE_TYPE_XCRB 1
43 #define PCIXCC_RESPONSE_TYPE_EP11 2
45 MODULE_AUTHOR("IBM Corporation");
46 MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
47 "Copyright IBM Corp. 2001, 2012");
48 MODULE_LICENSE("GPL");
52 * Note that all shorts, ints and longs are little-endian.
53 * All pointer fields are 32-bits long, and mean nothing
55 * A request CPRB is followed by a request_parameter_block.
57 * The request (or reply) parameter block is organized thus:
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 *
78 unsigned char req_datal
[4]; /* request data buffer */
80 unsigned char req_datap
[4]; /* request data buffer */
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 *
89 unsigned char rpl_datal
[4]; /* reply data buffer len ULELONG */
90 unsigned char rpl_datap
[4]; /* reply data buffer */
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 */
107 struct function_and_rules_block
{
108 unsigned char function_code
[2];
110 unsigned char only_rule
[8];
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'.
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')
130 static const struct CPRBX static_cprbx
= {
133 .func_id
= {0x54, 0x32},
136 int speed_idx_cca(int req_type
)
211 int speed_idx_ep11(int req_type
)
243 * Convert a ICAMEX message to a type6 MEX message.
245 * @zq: crypto device pointer
246 * @ap_msg: pointer to AP message
247 * @mex: pointer to user input data
249 * Returns 0 on success or -EFAULT.
251 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_queue
*zq
,
252 struct ap_message
*ap_msg
,
253 struct ica_rsa_modexpo
*mex
)
255 static struct type6_hdr static_type6_hdrX
= {
257 .offset1
= 0x00000058,
258 .agent_id
= {'C', 'A',},
259 .function_code
= {'P', 'K'},
261 static struct function_and_rules_block static_pke_fnr
= {
262 .function_code
= {'P', 'K'},
264 .only_rule
= {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '}
267 struct type6_hdr hdr
;
269 struct function_and_rules_block fr
;
270 unsigned short length
;
272 } __packed
* msg
= ap_msg
->message
;
276 msg
->length
= mex
->inputdatalength
+ 2;
277 if (copy_from_user(msg
->text
, mex
->inputdata
, mex
->inputdatalength
))
280 /* Set up key which is located after the variable length text. */
281 size
= zcrypt_type6_mex_key_en(mex
, msg
->text
+mex
->inputdatalength
);
284 size
+= sizeof(*msg
) + mex
->inputdatalength
;
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
);
291 msg
->cprbx
= static_cprbx
;
292 msg
->cprbx
.domain
= AP_QID_QUEUE(zq
->queue
->qid
);
293 msg
->cprbx
.rpl_msgbl
= msg
->hdr
.FromCardLen1
;
295 msg
->fr
= static_pke_fnr
;
297 msg
->cprbx
.req_parml
= size
- sizeof(msg
->hdr
) - sizeof(msg
->cprbx
);
299 ap_msg
->length
= size
;
304 * Convert a ICACRT message to a type6 CRT message.
306 * @zq: crypto device pointer
307 * @ap_msg: pointer to AP message
308 * @crt: pointer to user input data
310 * Returns 0 on success or -EFAULT.
312 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_queue
*zq
,
313 struct ap_message
*ap_msg
,
314 struct ica_rsa_modexpo_crt
*crt
)
316 static struct type6_hdr static_type6_hdrX
= {
318 .offset1
= 0x00000058,
319 .agent_id
= {'C', 'A',},
320 .function_code
= {'P', 'D'},
322 static struct function_and_rules_block static_pkd_fnr
= {
323 .function_code
= {'P', 'D'},
325 .only_rule
= {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
329 struct type6_hdr hdr
;
331 struct function_and_rules_block fr
;
332 unsigned short length
;
334 } __packed
* msg
= ap_msg
->message
;
338 msg
->length
= crt
->inputdatalength
+ 2;
339 if (copy_from_user(msg
->text
, crt
->inputdata
, crt
->inputdatalength
))
342 /* Set up key which is located after the variable length text. */
343 size
= zcrypt_type6_crt_key(crt
, msg
->text
+ crt
->inputdatalength
);
346 size
+= sizeof(*msg
) + crt
->inputdatalength
; /* total size of msg */
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
);
353 msg
->cprbx
= static_cprbx
;
354 msg
->cprbx
.domain
= AP_QID_QUEUE(zq
->queue
->qid
);
355 msg
->cprbx
.req_parml
= msg
->cprbx
.rpl_msgbl
=
356 size
- sizeof(msg
->hdr
) - sizeof(msg
->cprbx
);
358 msg
->fr
= static_pkd_fnr
;
360 ap_msg
->length
= size
;
365 * Convert a XCRB message to a type6 CPRB message.
367 * @zq: crypto device pointer
368 * @ap_msg: pointer to AP message
369 * @xcRB: pointer to user input data
371 * Returns 0 on success or -EFAULT, -EINVAL.
373 struct type86_fmt2_msg
{
374 struct type86_hdr hdr
;
375 struct type86_fmt2_ext fmt2
;
378 static int XCRB_msg_to_type6CPRB_msgX(struct ap_message
*ap_msg
,
379 struct ica_xcRB
*xcRB
,
381 unsigned short **dom
)
383 static struct type6_hdr static_type6_hdrX
= {
385 .offset1
= 0x00000058,
388 struct type6_hdr hdr
;
390 } __packed
* msg
= ap_msg
->message
;
392 int rcblen
= CEIL4(xcRB
->request_control_blk_length
);
393 int replylen
, req_sumlen
, resp_sumlen
;
394 char *req_data
= ap_msg
->message
+ sizeof(struct type6_hdr
) + rcblen
;
397 if (CEIL4(xcRB
->request_control_blk_length
) <
398 xcRB
->request_control_blk_length
)
399 return -EINVAL
; /* overflow after alignment*/
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
)
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
))) {
419 if (CEIL4(xcRB
->reply_control_blk_length
) <
420 xcRB
->reply_control_blk_length
)
421 return -EINVAL
; /* overflow after alignment*/
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
)
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
))) {
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
;
447 msg
->hdr
.FromCardLen1
= xcRB
->reply_control_blk_length
;
448 msg
->hdr
.FromCardLen2
= xcRB
->reply_data_length
;
451 if (copy_from_user(&(msg
->cprbx
), xcRB
->request_control_blk_addr
,
452 xcRB
->request_control_blk_length
))
454 if (msg
->cprbx
.cprb_len
+ sizeof(msg
->hdr
.function_code
) >
455 xcRB
->request_control_blk_length
)
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
));
461 *fcode
= (msg
->hdr
.function_code
[0] << 8) | msg
->hdr
.function_code
[1];
462 *dom
= (unsigned short *)&msg
->cprbx
.domain
;
464 if (memcmp(function_code
, "US", 2) == 0
465 || memcmp(function_code
, "AU", 2) == 0)
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
))
479 static int xcrb_msg_to_type6_ep11cprb_msgx(struct ap_message
*ap_msg
,
480 struct ep11_urb
*xcRB
,
484 static struct type6_hdr static_type6_ep11_hdr
= {
486 .rqid
= {0x00, 0x01},
487 .function_code
= {0x00, 0x00},
488 .agent_id
[0] = 0x58, /* {'X'} */
489 .agent_id
[1] = 0x43, /* {'C'} */
490 .offset1
= 0x00000058,
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
;
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 */
507 } __packed
* payload_hdr
= NULL
;
509 if (CEIL4(xcRB
->req_len
) < xcRB
->req_len
)
510 return -EINVAL
; /* overflow after alignment*/
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
)))
518 if (CEIL4(xcRB
->resp_len
) < xcRB
->resp_len
)
519 return -EINVAL
; /* overflow after alignment*/
521 if (CEIL4(xcRB
->resp_len
) > MSGTYPE06_MAX_MSG_SIZE
-
522 (sizeof(struct type86_fmt2_msg
)))
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
;
530 /* Import CPRB data from the ioctl input parameter */
531 if (copy_from_user(&(msg
->cprbx
.cprb_len
),
532 (char __force __user
*)xcRB
->req
, xcRB
->req_len
)) {
536 if ((msg
->pld_lenfmt
& 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/
537 switch (msg
->pld_lenfmt
& 0x03) {
548 lfmt
= 1; /* length format #1 */
550 payload_hdr
= (struct pld_hdr
*)((&(msg
->pld_lenfmt
))+lfmt
);
551 *fcode
= payload_hdr
->func_val
& 0xFFFF;
557 * Copy results from a type 86 ICA reply message back to user space.
559 * @zq: crypto device pointer
560 * @reply: reply AP message.
561 * @data: pointer to user output data
562 * @length: size of user output data
564 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
566 struct type86x_reply
{
567 struct type86_hdr hdr
;
568 struct type86_fmt2_ext fmt2
;
570 unsigned char pad
[4]; /* 4 byte function code/rules block ? */
571 unsigned short length
;
575 struct type86_ep11_reply
{
576 struct type86_hdr hdr
;
577 struct type86_fmt2_ext fmt2
;
578 struct ep11_cprb cprbx
;
581 static int convert_type86_ica(struct zcrypt_queue
*zq
,
582 struct ap_message
*reply
,
583 char __user
*outputdata
,
584 unsigned int outputdatalength
)
586 static unsigned char static_pad
[] = {
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
621 struct type86x_reply
*msg
= reply
->message
;
622 unsigned short service_rc
, service_rs
;
623 unsigned int reply_len
, pad_len
;
626 service_rc
= msg
->cprbx
.ccp_rtcode
;
627 if (unlikely(service_rc
!= 0)) {
628 service_rs
= msg
->cprbx
.ccp_rscode
;
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
);
641 if (service_rc
== 8 && service_rs
== 783) {
642 zq
->zcard
->min_mod_size
=
643 PCIXCC_MIN_MOD_SIZE_OLD
;
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
);
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
));
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
);
660 return -EAGAIN
; /* repeat the request on a different device. */
663 reply_len
= msg
->length
- 2;
664 if (reply_len
> outputdatalength
)
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.
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)
676 pad_len
= outputdatalength
- reply_len
;
680 /* 'restore' padding left in the PCICC/PCIXCC card. */
681 if (copy_to_user(outputdata
, static_pad
, pad_len
- 1))
683 if (put_user(0, outputdata
+ pad_len
- 1))
686 /* Copy the crypto response to user space. */
687 if (copy_to_user(outputdata
+ pad_len
, data
, reply_len
))
693 * Copy results from a type 86 XCRB reply message back to user space.
695 * @zq: crypto device pointer
696 * @reply: reply AP message.
697 * @xcRB: pointer to XCRB
699 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
701 static int convert_type86_xcrb(struct zcrypt_queue
*zq
,
702 struct ap_message
*reply
,
703 struct ica_xcRB
*xcRB
)
705 struct type86_fmt2_msg
*msg
= reply
->message
;
706 char *data
= reply
->message
;
708 /* Copy CPRB to user */
709 if (copy_to_user(xcRB
->reply_control_blk_addr
,
710 data
+ msg
->fmt2
.offset1
, msg
->fmt2
.count1
))
712 xcRB
->reply_control_blk_length
= msg
->fmt2
.count1
;
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
))
719 xcRB
->reply_data_length
= msg
->fmt2
.count2
;
724 * Copy results from a type 86 EP11 XCRB reply message back to user space.
726 * @zq: crypto device pointer
727 * @reply: reply AP message.
728 * @xcRB: pointer to EP11 user request block
730 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
732 static int convert_type86_ep11_xcrb(struct zcrypt_queue
*zq
,
733 struct ap_message
*reply
,
734 struct ep11_urb
*xcRB
)
736 struct type86_fmt2_msg
*msg
= reply
->message
;
737 char *data
= reply
->message
;
739 if (xcRB
->resp_len
< msg
->fmt2
.count1
)
742 /* Copy response CPRB to user */
743 if (copy_to_user((char __force __user
*)xcRB
->resp
,
744 data
+ msg
->fmt2
.offset1
, msg
->fmt2
.count1
))
746 xcRB
->resp_len
= msg
->fmt2
.count1
;
750 static int convert_type86_rng(struct zcrypt_queue
*zq
,
751 struct ap_message
*reply
,
755 struct type86_hdr hdr
;
756 struct type86_fmt2_ext fmt2
;
758 } __packed
* msg
= reply
->message
;
759 char *data
= reply
->message
;
761 if (msg
->cprbx
.ccp_rtcode
!= 0 || msg
->cprbx
.ccp_rscode
!= 0)
763 memcpy(buffer
, data
+ msg
->fmt2
.offset2
, msg
->fmt2
.count2
);
764 return msg
->fmt2
.count2
;
767 static int convert_response_ica(struct zcrypt_queue
*zq
,
768 struct ap_message
*reply
,
769 char __user
*outputdata
,
770 unsigned int outputdatalength
)
772 struct type86x_reply
*msg
= reply
->message
;
774 switch (msg
->hdr
.type
) {
775 case TYPE82_RSP_CODE
:
776 case TYPE88_RSP_CODE
:
777 return convert_error(zq
, reply
);
778 case TYPE86_RSP_CODE
:
779 if (msg
->cprbx
.ccp_rtcode
&&
780 (msg
->cprbx
.ccp_rscode
== 0x14f) &&
781 (outputdatalength
> 256)) {
782 if (zq
->zcard
->max_exp_bit_length
<= 17) {
783 zq
->zcard
->max_exp_bit_length
= 17;
788 if (msg
->hdr
.reply_code
)
789 return convert_error(zq
, reply
);
790 if (msg
->cprbx
.cprb_ver_id
== 0x02)
791 return convert_type86_ica(zq
, reply
,
792 outputdata
, outputdatalength
);
793 /* Fall through, no break, incorrect cprb version is an unknown
795 default: /* Unknown response type, this should NEVER EVER happen */
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
));
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
);
805 return -EAGAIN
; /* repeat the request on a different device. */
809 static int convert_response_xcrb(struct zcrypt_queue
*zq
,
810 struct ap_message
*reply
,
811 struct ica_xcRB
*xcRB
)
813 struct type86x_reply
*msg
= reply
->message
;
815 switch (msg
->hdr
.type
) {
816 case TYPE82_RSP_CODE
:
817 case TYPE88_RSP_CODE
:
818 xcRB
->status
= 0x0008044DL
; /* HDD_InvalidParm */
819 return convert_error(zq
, reply
);
820 case TYPE86_RSP_CODE
:
821 if (msg
->hdr
.reply_code
) {
822 memcpy(&(xcRB
->status
), msg
->fmt2
.apfs
, sizeof(u32
));
823 return convert_error(zq
, reply
);
825 if (msg
->cprbx
.cprb_ver_id
== 0x02)
826 return convert_type86_xcrb(zq
, reply
, xcRB
);
827 /* Fall through, no break, incorrect cprb version is an unknown
829 default: /* Unknown response type, this should NEVER EVER happen */
830 xcRB
->status
= 0x0008044DL
; /* HDD_InvalidParm */
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
));
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
);
840 return -EAGAIN
; /* repeat the request on a different device. */
844 static int convert_response_ep11_xcrb(struct zcrypt_queue
*zq
,
845 struct ap_message
*reply
, struct ep11_urb
*xcRB
)
847 struct type86_ep11_reply
*msg
= reply
->message
;
849 switch (msg
->hdr
.type
) {
850 case TYPE82_RSP_CODE
:
851 case TYPE87_RSP_CODE
:
852 return convert_error(zq
, reply
);
853 case TYPE86_RSP_CODE
:
854 if (msg
->hdr
.reply_code
)
855 return convert_error(zq
, reply
);
856 if (msg
->cprbx
.cprb_ver_id
== 0x04)
857 return convert_type86_ep11_xcrb(zq
, reply
, xcRB
);
858 /* Fall through, no break, incorrect cprb version is an unknown resp.*/
859 default: /* Unknown response type, this should NEVER EVER happen */
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
));
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
);
869 return -EAGAIN
; /* repeat the request on a different device. */
873 static int convert_response_rng(struct zcrypt_queue
*zq
,
874 struct ap_message
*reply
,
877 struct type86x_reply
*msg
= reply
->message
;
879 switch (msg
->hdr
.type
) {
880 case TYPE82_RSP_CODE
:
881 case TYPE88_RSP_CODE
:
883 case TYPE86_RSP_CODE
:
884 if (msg
->hdr
.reply_code
)
886 if (msg
->cprbx
.cprb_ver_id
== 0x02)
887 return convert_type86_rng(zq
, reply
, data
);
888 /* Fall through, no break, incorrect cprb version is an unknown
890 default: /* Unknown response type, this should NEVER EVER happen */
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
));
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
);
900 return -EAGAIN
; /* repeat the request on a different device. */
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.
908 * @aq: pointer to the AP queue
909 * @msg: pointer to the AP message
910 * @reply: pointer to the AP reply message
912 static void zcrypt_msgtype6_receive(struct ap_queue
*aq
,
913 struct ap_message
*msg
,
914 struct ap_message
*reply
)
916 static struct error_hdr error_reply
= {
917 .type
= TYPE82_RSP_CODE
,
918 .reply_code
= REP82_ERROR_MACHINE_FAILURE
,
920 struct response_type
*resp_type
=
921 (struct response_type
*) msg
->private;
922 struct type86x_reply
*t86r
;
925 /* Copy the reply message to the request message buffer. */
927 goto out
; /* ap_msg->rc indicates the error */
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
)
935 length
= min(PCIXCC_MAX_ICA_RESPONSE_SIZE
, length
);
936 memcpy(msg
->message
, reply
->message
, length
);
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
);
944 memcpy(msg
->message
, &error_reply
,
945 sizeof(error_reply
));
948 memcpy(msg
->message
, reply
->message
, sizeof(error_reply
));
950 complete(&(resp_type
->work
));
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.
957 * @aq: pointer to the AP queue
958 * @msg: pointer to the AP message
959 * @reply: pointer to the AP reply message
961 static void zcrypt_msgtype6_receive_ep11(struct ap_queue
*aq
,
962 struct ap_message
*msg
,
963 struct ap_message
*reply
)
965 static struct error_hdr error_reply
= {
966 .type
= TYPE82_RSP_CODE
,
967 .reply_code
= REP82_ERROR_MACHINE_FAILURE
,
969 struct response_type
*resp_type
=
970 (struct response_type
*)msg
->private;
971 struct type86_ep11_reply
*t86r
;
974 /* Copy the reply message to the request message buffer. */
976 goto out
; /* ap_msg->rc indicates the error */
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
);
987 memcpy(msg
->message
, &error_reply
, sizeof(error_reply
));
990 memcpy(msg
->message
, reply
->message
, sizeof(error_reply
));
993 complete(&(resp_type
->work
));
996 static atomic_t zcrypt_step
= ATOMIC_INIT(0);
999 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1000 * device to handle a modexpo request.
1001 * @zq: pointer to zcrypt_queue structure that identifies the
1002 * PCIXCC/CEX2C device to the request distributor
1003 * @mex: pointer to the modexpo request buffer
1005 static long zcrypt_msgtype6_modexpo(struct zcrypt_queue
*zq
,
1006 struct ica_rsa_modexpo
*mex
)
1008 struct ap_message ap_msg
;
1009 struct response_type resp_type
= {
1010 .type
= PCIXCC_RESPONSE_TYPE_ICA
,
1014 ap_init_message(&ap_msg
);
1015 ap_msg
.message
= (void *) get_zeroed_page(GFP_KERNEL
);
1016 if (!ap_msg
.message
)
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
;
1022 rc
= ICAMEX_msg_to_type6MEX_msgX(zq
, &ap_msg
, mex
);
1025 init_completion(&resp_type
.work
);
1026 ap_queue_message(zq
->queue
, &ap_msg
);
1027 rc
= wait_for_completion_interruptible(&resp_type
.work
);
1031 rc
= convert_response_ica(zq
, &ap_msg
,
1033 mex
->outputdatalength
);
1035 /* Signal pending. */
1036 ap_cancel_message(zq
->queue
, &ap_msg
);
1038 free_page((unsigned long) ap_msg
.message
);
1043 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1044 * device to handle a modexpo_crt request.
1045 * @zq: pointer to zcrypt_queue structure that identifies the
1046 * PCIXCC/CEX2C device to the request distributor
1047 * @crt: pointer to the modexpoc_crt request buffer
1049 static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue
*zq
,
1050 struct ica_rsa_modexpo_crt
*crt
)
1052 struct ap_message ap_msg
;
1053 struct response_type resp_type
= {
1054 .type
= PCIXCC_RESPONSE_TYPE_ICA
,
1058 ap_init_message(&ap_msg
);
1059 ap_msg
.message
= (void *) get_zeroed_page(GFP_KERNEL
);
1060 if (!ap_msg
.message
)
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
;
1066 rc
= ICACRT_msg_to_type6CRT_msgX(zq
, &ap_msg
, crt
);
1069 init_completion(&resp_type
.work
);
1070 ap_queue_message(zq
->queue
, &ap_msg
);
1071 rc
= wait_for_completion_interruptible(&resp_type
.work
);
1075 rc
= convert_response_ica(zq
, &ap_msg
,
1077 crt
->outputdatalength
);
1079 /* Signal pending. */
1080 ap_cancel_message(zq
->queue
, &ap_msg
);
1083 free_page((unsigned long) ap_msg
.message
);
1087 unsigned int get_cprb_fc(struct ica_xcRB
*xcRB
,
1088 struct ap_message
*ap_msg
,
1089 unsigned int *func_code
, unsigned short **dom
)
1091 struct response_type resp_type
= {
1092 .type
= PCIXCC_RESPONSE_TYPE_XCRB
,
1096 ap_init_message(ap_msg
);
1097 ap_msg
->message
= kmalloc(MSGTYPE06_MAX_MSG_SIZE
, GFP_KERNEL
);
1098 if (!ap_msg
->message
)
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
);
1108 memcpy(ap_msg
->private, &resp_type
, sizeof(resp_type
));
1109 rc
= XCRB_msg_to_type6CPRB_msgX(ap_msg
, xcRB
, func_code
, dom
);
1111 kzfree(ap_msg
->message
);
1112 kzfree(ap_msg
->private);
1118 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1119 * device to handle a send_cprb request.
1120 * @zq: pointer to zcrypt_queue structure that identifies the
1121 * PCIXCC/CEX2C device to the request distributor
1122 * @xcRB: pointer to the send_cprb request buffer
1124 static long zcrypt_msgtype6_send_cprb(struct zcrypt_queue
*zq
,
1125 struct ica_xcRB
*xcRB
,
1126 struct ap_message
*ap_msg
)
1129 struct response_type
*rtype
= (struct response_type
*)(ap_msg
->private);
1131 init_completion(&rtype
->work
);
1132 ap_queue_message(zq
->queue
, ap_msg
);
1133 rc
= wait_for_completion_interruptible(&rtype
->work
);
1137 rc
= convert_response_xcrb(zq
, ap_msg
, xcRB
);
1139 /* Signal pending. */
1140 ap_cancel_message(zq
->queue
, ap_msg
);
1142 kzfree(ap_msg
->message
);
1143 kzfree(ap_msg
->private);
1147 unsigned int get_ep11cprb_fc(struct ep11_urb
*xcrb
,
1148 struct ap_message
*ap_msg
,
1149 unsigned int *func_code
)
1151 struct response_type resp_type
= {
1152 .type
= PCIXCC_RESPONSE_TYPE_EP11
,
1156 ap_init_message(ap_msg
);
1157 ap_msg
->message
= kmalloc(MSGTYPE06_MAX_MSG_SIZE
, GFP_KERNEL
);
1158 if (!ap_msg
->message
)
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
);
1168 memcpy(ap_msg
->private, &resp_type
, sizeof(resp_type
));
1169 rc
= xcrb_msg_to_type6_ep11cprb_msgx(ap_msg
, xcrb
, func_code
);
1171 kzfree(ap_msg
->message
);
1172 kzfree(ap_msg
->private);
1178 * The request distributor calls this function if it picked the CEX4P
1179 * device to handle a send_ep11_cprb request.
1180 * @zq: pointer to zcrypt_queue structure that identifies the
1181 * CEX4P device to the request distributor
1182 * @xcRB: pointer to the ep11 user request block
1184 static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_queue
*zq
,
1185 struct ep11_urb
*xcrb
,
1186 struct ap_message
*ap_msg
)
1190 struct response_type
*rtype
= (struct response_type
*)(ap_msg
->private);
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
;
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
;
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
1215 if (!((msg
->cprbx
.flags
& 0x80) == 0x80)) {
1216 msg
->cprbx
.target_id
= (unsigned int)
1217 AP_QID_QUEUE(zq
->queue
->qid
);
1219 if ((msg
->pld_lenfmt
& 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/
1220 switch (msg
->pld_lenfmt
& 0x03) {
1231 lfmt
= 1; /* length format #1 */
1233 payload_hdr
= (struct pld_hdr
*)((&(msg
->pld_lenfmt
))+lfmt
);
1234 payload_hdr
->dom_val
= (unsigned int)
1235 AP_QID_QUEUE(zq
->queue
->qid
);
1238 init_completion(&rtype
->work
);
1239 ap_queue_message(zq
->queue
, ap_msg
);
1240 rc
= wait_for_completion_interruptible(&rtype
->work
);
1244 rc
= convert_response_ep11_xcrb(zq
, ap_msg
, xcrb
);
1246 /* Signal pending. */
1247 ap_cancel_message(zq
->queue
, ap_msg
);
1249 kzfree(ap_msg
->message
);
1250 kzfree(ap_msg
->private);
1254 unsigned int get_rng_fc(struct ap_message
*ap_msg
, int *func_code
,
1255 unsigned int *domain
)
1257 struct response_type resp_type
= {
1258 .type
= PCIXCC_RESPONSE_TYPE_XCRB
,
1261 ap_init_message(ap_msg
);
1262 ap_msg
->message
= kmalloc(MSGTYPE06_MAX_MSG_SIZE
, GFP_KERNEL
);
1263 if (!ap_msg
->message
)
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
);
1273 memcpy(ap_msg
->private, &resp_type
, sizeof(resp_type
));
1275 rng_type6CPRB_msgX(ap_msg
, ZCRYPT_RNG_BUFFER_SIZE
, domain
);
1282 * The request distributor calls this function if it picked the PCIXCC/CEX2C
1283 * device to generate random data.
1284 * @zq: pointer to zcrypt_queue structure that identifies the
1285 * PCIXCC/CEX2C device to the request distributor
1286 * @buffer: pointer to a memory page to return random data
1288 static long zcrypt_msgtype6_rng(struct zcrypt_queue
*zq
,
1289 char *buffer
, struct ap_message
*ap_msg
)
1292 struct type6_hdr hdr
;
1294 char function_code
[2];
1295 short int rule_length
;
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);
1303 msg
->cprbx
.domain
= AP_QID_QUEUE(zq
->queue
->qid
);
1305 init_completion(&rtype
->work
);
1306 ap_queue_message(zq
->queue
, ap_msg
);
1307 rc
= wait_for_completion_interruptible(&rtype
->work
);
1311 rc
= convert_response_rng(zq
, ap_msg
, buffer
);
1313 /* Signal pending. */
1314 ap_cancel_message(zq
->queue
, ap_msg
);
1316 kzfree(ap_msg
->message
);
1317 kzfree(ap_msg
->private);
1322 * The crypto operations for a PCIXCC/CEX2C card.
1324 static struct zcrypt_ops zcrypt_msgtype6_norng_ops
= {
1325 .owner
= THIS_MODULE
,
1326 .name
= MSGTYPE06_NAME
,
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
,
1333 static struct zcrypt_ops zcrypt_msgtype6_ops
= {
1334 .owner
= THIS_MODULE
,
1335 .name
= MSGTYPE06_NAME
,
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
,
1343 static struct zcrypt_ops zcrypt_msgtype6_ep11_ops
= {
1344 .owner
= THIS_MODULE
,
1345 .name
= MSGTYPE06_NAME
,
1346 .variant
= MSGTYPE06_VARIANT_EP11
,
1347 .rsa_modexpo
= NULL
,
1348 .rsa_modexpo_crt
= NULL
,
1349 .send_ep11_cprb
= zcrypt_msgtype6_send_ep11_cprb
,
1352 void __init
zcrypt_msgtype6_init(void)
1354 zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops
);
1355 zcrypt_msgtype_register(&zcrypt_msgtype6_ops
);
1356 zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops
);
1359 void __exit
zcrypt_msgtype6_exit(void)
1361 zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops
);
1362 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops
);
1363 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops
);