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