]> Pileus Git - ~andy/linux/blob - drivers/s390/crypto/zcrypt_msgtype6.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
[~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 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/err.h>
31 #include <linux/delay.h>
32 #include <linux/slab.h>
33 #include <linux/atomic.h>
34 #include <linux/uaccess.h>
35
36 #include "ap_bus.h"
37 #include "zcrypt_api.h"
38 #include "zcrypt_error.h"
39 #include "zcrypt_msgtype6.h"
40 #include "zcrypt_cca_key.h"
41
42 #define PCIXCC_MIN_MOD_SIZE_OLD  64     /*  512 bits    */
43 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply      */
44
45 #define CEIL4(x) ((((x)+3)/4)*4)
46
47 struct response_type {
48         struct completion work;
49         int type;
50 };
51 #define PCIXCC_RESPONSE_TYPE_ICA  0
52 #define PCIXCC_RESPONSE_TYPE_XCRB 1
53
54 MODULE_AUTHOR("IBM Corporation");
55 MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
56                    "Copyright IBM Corp. 2001, 2012");
57 MODULE_LICENSE("GPL");
58
59 static void zcrypt_msgtype6_receive(struct ap_device *, struct ap_message *,
60                                  struct ap_message *);
61
62 /**
63  * CPRB
64  *        Note that all shorts, ints and longs are little-endian.
65  *        All pointer fields are 32-bits long, and mean nothing
66  *
67  *        A request CPRB is followed by a request_parameter_block.
68  *
69  *        The request (or reply) parameter block is organized thus:
70  *          function code
71  *          VUD block
72  *          key block
73  */
74 struct CPRB {
75         unsigned short cprb_len;        /* CPRB length                   */
76         unsigned char cprb_ver_id;      /* CPRB version id.              */
77         unsigned char pad_000;          /* Alignment pad byte.           */
78         unsigned char srpi_rtcode[4];   /* SRPI return code LELONG       */
79         unsigned char srpi_verb;        /* SRPI verb type                */
80         unsigned char flags;            /* flags                         */
81         unsigned char func_id[2];       /* function id                   */
82         unsigned char checkpoint_flag;  /*                               */
83         unsigned char resv2;            /* reserved                      */
84         unsigned short req_parml;       /* request parameter buffer      */
85                                         /* length 16-bit little endian   */
86         unsigned char req_parmp[4];     /* request parameter buffer      *
87                                          * pointer (means nothing: the   *
88                                          * parameter buffer follows      *
89                                          * the CPRB).                    */
90         unsigned char req_datal[4];     /* request data buffer           */
91                                         /* length         ULELONG        */
92         unsigned char req_datap[4];     /* request data buffer           */
93                                         /* pointer                       */
94         unsigned short rpl_parml;       /* reply  parameter buffer       */
95                                         /* length 16-bit little endian   */
96         unsigned char pad_001[2];       /* Alignment pad bytes. ULESHORT */
97         unsigned char rpl_parmp[4];     /* reply parameter buffer        *
98                                          * pointer (means nothing: the   *
99                                          * parameter buffer follows      *
100                                          * the CPRB).                    */
101         unsigned char rpl_datal[4];     /* reply data buffer len ULELONG */
102         unsigned char rpl_datap[4];     /* reply data buffer             */
103                                         /* pointer                       */
104         unsigned short ccp_rscode;      /* server reason code   ULESHORT */
105         unsigned short ccp_rtcode;      /* server return code   ULESHORT */
106         unsigned char repd_parml[2];    /* replied parameter len ULESHORT*/
107         unsigned char mac_data_len[2];  /* Mac Data Length      ULESHORT */
108         unsigned char repd_datal[4];    /* replied data length  ULELONG  */
109         unsigned char req_pc[2];        /* PC identifier                 */
110         unsigned char res_origin[8];    /* resource origin               */
111         unsigned char mac_value[8];     /* Mac Value                     */
112         unsigned char logon_id[8];      /* Logon Identifier              */
113         unsigned char usage_domain[2];  /* cdx                           */
114         unsigned char resv3[18];        /* reserved for requestor        */
115         unsigned short svr_namel;       /* server name length  ULESHORT  */
116         unsigned char svr_name[8];      /* server name                   */
117 } __packed;
118
119 struct function_and_rules_block {
120         unsigned char function_code[2];
121         unsigned short ulen;
122         unsigned char only_rule[8];
123 } __packed;
124
125 /**
126  * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
127  * card in a type6 message. The 3 fields that must be filled in at execution
128  * time are  req_parml, rpl_parml and usage_domain.
129  * Everything about this interface is ascii/big-endian, since the
130  * device does *not* have 'Intel inside'.
131  *
132  * The CPRBX is followed immediately by the parm block.
133  * The parm block contains:
134  * - function code ('PD' 0x5044 or 'PK' 0x504B)
135  * - rule block (one of:)
136  *   + 0x000A 'PKCS-1.2' (MCL2 'PD')
137  *   + 0x000A 'ZERO-PAD' (MCL2 'PK')
138  *   + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
139  *   + 0x000A 'MRP     ' (MCL3 'PK' or CEX2C 'PK')
140  * - VUD block
141  */
142 static struct CPRBX static_cprbx = {
143         .cprb_len       =  0x00DC,
144         .cprb_ver_id    =  0x02,
145         .func_id        = {0x54, 0x32},
146 };
147
148 /**
149  * Convert a ICAMEX message to a type6 MEX message.
150  *
151  * @zdev: crypto device pointer
152  * @ap_msg: pointer to AP message
153  * @mex: pointer to user input data
154  *
155  * Returns 0 on success or -EFAULT.
156  */
157 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
158                                        struct ap_message *ap_msg,
159                                        struct ica_rsa_modexpo *mex)
160 {
161         static struct type6_hdr static_type6_hdrX = {
162                 .type           =  0x06,
163                 .offset1        =  0x00000058,
164                 .agent_id       = {'C', 'A',},
165                 .function_code  = {'P', 'K'},
166         };
167         static struct function_and_rules_block static_pke_fnr = {
168                 .function_code  = {'P', 'K'},
169                 .ulen           = 10,
170                 .only_rule      = {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '}
171         };
172         static struct function_and_rules_block static_pke_fnr_MCL2 = {
173                 .function_code  = {'P', 'K'},
174                 .ulen           = 10,
175                 .only_rule      = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
176         };
177         struct {
178                 struct type6_hdr hdr;
179                 struct CPRBX cprbx;
180                 struct function_and_rules_block fr;
181                 unsigned short length;
182                 char text[0];
183         } __packed * msg = ap_msg->message;
184         int size;
185
186         /* VUD.ciphertext */
187         msg->length = mex->inputdatalength + 2;
188         if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
189                 return -EFAULT;
190
191         /* Set up key which is located after the variable length text. */
192         size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
193         if (size < 0)
194                 return size;
195         size += sizeof(*msg) + mex->inputdatalength;
196
197         /* message header, cprbx and f&r */
198         msg->hdr = static_type6_hdrX;
199         msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
200         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
201
202         msg->cprbx = static_cprbx;
203         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
204         msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
205
206         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
207                 static_pke_fnr_MCL2 : static_pke_fnr;
208
209         msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
210
211         ap_msg->length = size;
212         return 0;
213 }
214
215 /**
216  * Convert a ICACRT message to a type6 CRT message.
217  *
218  * @zdev: crypto device pointer
219  * @ap_msg: pointer to AP message
220  * @crt: pointer to user input data
221  *
222  * Returns 0 on success or -EFAULT.
223  */
224 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
225                                        struct ap_message *ap_msg,
226                                        struct ica_rsa_modexpo_crt *crt)
227 {
228         static struct type6_hdr static_type6_hdrX = {
229                 .type           =  0x06,
230                 .offset1        =  0x00000058,
231                 .agent_id       = {'C', 'A',},
232                 .function_code  = {'P', 'D'},
233         };
234         static struct function_and_rules_block static_pkd_fnr = {
235                 .function_code  = {'P', 'D'},
236                 .ulen           = 10,
237                 .only_rule      = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
238         };
239
240         static struct function_and_rules_block static_pkd_fnr_MCL2 = {
241                 .function_code  = {'P', 'D'},
242                 .ulen           = 10,
243                 .only_rule      = {'P', 'K', 'C', 'S', '-', '1', '.', '2'}
244         };
245         struct {
246                 struct type6_hdr hdr;
247                 struct CPRBX cprbx;
248                 struct function_and_rules_block fr;
249                 unsigned short length;
250                 char text[0];
251         } __packed * msg = ap_msg->message;
252         int size;
253
254         /* VUD.ciphertext */
255         msg->length = crt->inputdatalength + 2;
256         if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
257                 return -EFAULT;
258
259         /* Set up key which is located after the variable length text. */
260         size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
261         if (size < 0)
262                 return size;
263         size += sizeof(*msg) + crt->inputdatalength;    /* total size of msg */
264
265         /* message header, cprbx and f&r */
266         msg->hdr = static_type6_hdrX;
267         msg->hdr.ToCardLen1 = size -  sizeof(msg->hdr);
268         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
269
270         msg->cprbx = static_cprbx;
271         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
272         msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
273                 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
274
275         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
276                 static_pkd_fnr_MCL2 : static_pkd_fnr;
277
278         ap_msg->length = size;
279         return 0;
280 }
281
282 /**
283  * Convert a XCRB message to a type6 CPRB message.
284  *
285  * @zdev: crypto device pointer
286  * @ap_msg: pointer to AP message
287  * @xcRB: pointer to user input data
288  *
289  * Returns 0 on success or -EFAULT, -EINVAL.
290  */
291 struct type86_fmt2_msg {
292         struct type86_hdr hdr;
293         struct type86_fmt2_ext fmt2;
294 } __packed;
295
296 static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
297                                        struct ap_message *ap_msg,
298                                        struct ica_xcRB *xcRB)
299 {
300         static struct type6_hdr static_type6_hdrX = {
301                 .type           =  0x06,
302                 .offset1        =  0x00000058,
303         };
304         struct {
305                 struct type6_hdr hdr;
306                 struct CPRBX cprbx;
307         } __packed * msg = ap_msg->message;
308
309         int rcblen = CEIL4(xcRB->request_control_blk_length);
310         int replylen;
311         char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
312         char *function_code;
313
314         /* length checks */
315         ap_msg->length = sizeof(struct type6_hdr) +
316                 CEIL4(xcRB->request_control_blk_length) +
317                 xcRB->request_data_length;
318         if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE)
319                 return -EINVAL;
320         replylen = sizeof(struct type86_fmt2_msg) +
321                 CEIL4(xcRB->reply_control_blk_length) +
322                 xcRB->reply_data_length;
323         if (replylen > MSGTYPE06_MAX_MSG_SIZE)
324                 return -EINVAL;
325
326         /* prepare type6 header */
327         msg->hdr = static_type6_hdrX;
328         memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
329         msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
330         if (xcRB->request_data_length) {
331                 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
332                 msg->hdr.ToCardLen2 = xcRB->request_data_length;
333         }
334         msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
335         msg->hdr.FromCardLen2 = xcRB->reply_data_length;
336
337         /* prepare CPRB */
338         if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
339                     xcRB->request_control_blk_length))
340                 return -EFAULT;
341         if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
342             xcRB->request_control_blk_length)
343                 return -EINVAL;
344         function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
345         memcpy(msg->hdr.function_code, function_code,
346                sizeof(msg->hdr.function_code));
347
348         if (memcmp(function_code, "US", 2) == 0)
349                 ap_msg->special = 1;
350         else
351                 ap_msg->special = 0;
352
353         /* copy data block */
354         if (xcRB->request_data_length &&
355             copy_from_user(req_data, xcRB->request_data_address,
356                 xcRB->request_data_length))
357                 return -EFAULT;
358         return 0;
359 }
360
361 /**
362  * Copy results from a type 86 ICA reply message back to user space.
363  *
364  * @zdev: crypto device pointer
365  * @reply: reply AP message.
366  * @data: pointer to user output data
367  * @length: size of user output data
368  *
369  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
370  */
371 struct type86x_reply {
372         struct type86_hdr hdr;
373         struct type86_fmt2_ext fmt2;
374         struct CPRBX cprbx;
375         unsigned char pad[4];   /* 4 byte function code/rules block ? */
376         unsigned short length;
377         char text[0];
378 } __packed;
379
380 static int convert_type86_ica(struct zcrypt_device *zdev,
381                           struct ap_message *reply,
382                           char __user *outputdata,
383                           unsigned int outputdatalength)
384 {
385         static unsigned char static_pad[] = {
386                 0x00, 0x02,
387                 0x1B, 0x7B, 0x5D, 0xB5, 0x75, 0x01, 0x3D, 0xFD,
388                 0x8D, 0xD1, 0xC7, 0x03, 0x2D, 0x09, 0x23, 0x57,
389                 0x89, 0x49, 0xB9, 0x3F, 0xBB, 0x99, 0x41, 0x5B,
390                 0x75, 0x21, 0x7B, 0x9D, 0x3B, 0x6B, 0x51, 0x39,
391                 0xBB, 0x0D, 0x35, 0xB9, 0x89, 0x0F, 0x93, 0xA5,
392                 0x0B, 0x47, 0xF1, 0xD3, 0xBB, 0xCB, 0xF1, 0x9D,
393                 0x23, 0x73, 0x71, 0xFF, 0xF3, 0xF5, 0x45, 0xFB,
394                 0x61, 0x29, 0x23, 0xFD, 0xF1, 0x29, 0x3F, 0x7F,
395                 0x17, 0xB7, 0x1B, 0xA9, 0x19, 0xBD, 0x57, 0xA9,
396                 0xD7, 0x95, 0xA3, 0xCB, 0xED, 0x1D, 0xDB, 0x45,
397                 0x7D, 0x11, 0xD1, 0x51, 0x1B, 0xED, 0x71, 0xE9,
398                 0xB1, 0xD1, 0xAB, 0xAB, 0x21, 0x2B, 0x1B, 0x9F,
399                 0x3B, 0x9F, 0xF7, 0xF7, 0xBD, 0x63, 0xEB, 0xAD,
400                 0xDF, 0xB3, 0x6F, 0x5B, 0xDB, 0x8D, 0xA9, 0x5D,
401                 0xE3, 0x7D, 0x77, 0x49, 0x47, 0xF5, 0xA7, 0xFD,
402                 0xAB, 0x2F, 0x27, 0x35, 0x77, 0xD3, 0x49, 0xC9,
403                 0x09, 0xEB, 0xB1, 0xF9, 0xBF, 0x4B, 0xCB, 0x2B,
404                 0xEB, 0xEB, 0x05, 0xFF, 0x7D, 0xC7, 0x91, 0x8B,
405                 0x09, 0x83, 0xB9, 0xB9, 0x69, 0x33, 0x39, 0x6B,
406                 0x79, 0x75, 0x19, 0xBF, 0xBB, 0x07, 0x1D, 0xBD,
407                 0x29, 0xBF, 0x39, 0x95, 0x93, 0x1D, 0x35, 0xC7,
408                 0xC9, 0x4D, 0xE5, 0x97, 0x0B, 0x43, 0x9B, 0xF1,
409                 0x16, 0x93, 0x03, 0x1F, 0xA5, 0xFB, 0xDB, 0xF3,
410                 0x27, 0x4F, 0x27, 0x61, 0x05, 0x1F, 0xB9, 0x23,
411                 0x2F, 0xC3, 0x81, 0xA9, 0x23, 0x71, 0x55, 0x55,
412                 0xEB, 0xED, 0x41, 0xE5, 0xF3, 0x11, 0xF1, 0x43,
413                 0x69, 0x03, 0xBD, 0x0B, 0x37, 0x0F, 0x51, 0x8F,
414                 0x0B, 0xB5, 0x89, 0x5B, 0x67, 0xA9, 0xD9, 0x4F,
415                 0x01, 0xF9, 0x21, 0x77, 0x37, 0x73, 0x79, 0xC5,
416                 0x7F, 0x51, 0xC1, 0xCF, 0x97, 0xA1, 0x75, 0xAD,
417                 0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41,
418                 0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09
419         };
420         struct type86x_reply *msg = reply->message;
421         unsigned short service_rc, service_rs;
422         unsigned int reply_len, pad_len;
423         char *data;
424
425         service_rc = msg->cprbx.ccp_rtcode;
426         if (unlikely(service_rc != 0)) {
427                 service_rs = msg->cprbx.ccp_rscode;
428                 if (service_rc == 8 && service_rs == 66)
429                         return -EINVAL;
430                 if (service_rc == 8 && service_rs == 65)
431                         return -EINVAL;
432                 if (service_rc == 8 && service_rs == 770)
433                         return -EINVAL;
434                 if (service_rc == 8 && service_rs == 783) {
435                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
436                         return -EAGAIN;
437                 }
438                 if (service_rc == 12 && service_rs == 769)
439                         return -EINVAL;
440                 if (service_rc == 8 && service_rs == 72)
441                         return -EINVAL;
442                 zdev->online = 0;
443                 return -EAGAIN; /* repeat the request on a different device. */
444         }
445         data = msg->text;
446         reply_len = msg->length - 2;
447         if (reply_len > outputdatalength)
448                 return -EINVAL;
449         /*
450          * For all encipher requests, the length of the ciphertext (reply_len)
451          * will always equal the modulus length. For MEX decipher requests
452          * the output needs to get padded. Minimum pad size is 10.
453          *
454          * Currently, the cases where padding will be added is for:
455          * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
456          *   ZERO-PAD and CRT is only supported for PKD requests)
457          * - PCICC, always
458          */
459         pad_len = outputdatalength - reply_len;
460         if (pad_len > 0) {
461                 if (pad_len < 10)
462                         return -EINVAL;
463                 /* 'restore' padding left in the PCICC/PCIXCC card. */
464                 if (copy_to_user(outputdata, static_pad, pad_len - 1))
465                         return -EFAULT;
466                 if (put_user(0, outputdata + pad_len - 1))
467                         return -EFAULT;
468         }
469         /* Copy the crypto response to user space. */
470         if (copy_to_user(outputdata + pad_len, data, reply_len))
471                 return -EFAULT;
472         return 0;
473 }
474
475 /**
476  * Copy results from a type 86 XCRB reply message back to user space.
477  *
478  * @zdev: crypto device pointer
479  * @reply: reply AP message.
480  * @xcRB: pointer to XCRB
481  *
482  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
483  */
484 static int convert_type86_xcrb(struct zcrypt_device *zdev,
485                                struct ap_message *reply,
486                                struct ica_xcRB *xcRB)
487 {
488         struct type86_fmt2_msg *msg = reply->message;
489         char *data = reply->message;
490
491         /* Copy CPRB to user */
492         if (copy_to_user(xcRB->reply_control_blk_addr,
493                 data + msg->fmt2.offset1, msg->fmt2.count1))
494                 return -EFAULT;
495         xcRB->reply_control_blk_length = msg->fmt2.count1;
496
497         /* Copy data buffer to user */
498         if (msg->fmt2.count2)
499                 if (copy_to_user(xcRB->reply_data_addr,
500                         data + msg->fmt2.offset2, msg->fmt2.count2))
501                         return -EFAULT;
502         xcRB->reply_data_length = msg->fmt2.count2;
503         return 0;
504 }
505
506 static int convert_type86_rng(struct zcrypt_device *zdev,
507                           struct ap_message *reply,
508                           char *buffer)
509 {
510         struct {
511                 struct type86_hdr hdr;
512                 struct type86_fmt2_ext fmt2;
513                 struct CPRBX cprbx;
514         } __packed * msg = reply->message;
515         char *data = reply->message;
516
517         if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
518                 return -EINVAL;
519         memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
520         return msg->fmt2.count2;
521 }
522
523 static int convert_response_ica(struct zcrypt_device *zdev,
524                             struct ap_message *reply,
525                             char __user *outputdata,
526                             unsigned int outputdatalength)
527 {
528         struct type86x_reply *msg = reply->message;
529
530         /* Response type byte is the second byte in the response. */
531         switch (((unsigned char *) reply->message)[1]) {
532         case TYPE82_RSP_CODE:
533         case TYPE88_RSP_CODE:
534                 return convert_error(zdev, reply);
535         case TYPE86_RSP_CODE:
536                 if (msg->cprbx.ccp_rtcode &&
537                    (msg->cprbx.ccp_rscode == 0x14f) &&
538                    (outputdatalength > 256)) {
539                         if (zdev->max_exp_bit_length <= 17) {
540                                 zdev->max_exp_bit_length = 17;
541                                 return -EAGAIN;
542                         } else
543                                 return -EINVAL;
544                 }
545                 if (msg->hdr.reply_code)
546                         return convert_error(zdev, reply);
547                 if (msg->cprbx.cprb_ver_id == 0x02)
548                         return convert_type86_ica(zdev, reply,
549                                                   outputdata, outputdatalength);
550                 /* Fall through, no break, incorrect cprb version is an unknown
551                  * response */
552         default: /* Unknown response type, this should NEVER EVER happen */
553                 zdev->online = 0;
554                 return -EAGAIN; /* repeat the request on a different device. */
555         }
556 }
557
558 static int convert_response_xcrb(struct zcrypt_device *zdev,
559                             struct ap_message *reply,
560                             struct ica_xcRB *xcRB)
561 {
562         struct type86x_reply *msg = reply->message;
563
564         /* Response type byte is the second byte in the response. */
565         switch (((unsigned char *) reply->message)[1]) {
566         case TYPE82_RSP_CODE:
567         case TYPE88_RSP_CODE:
568                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
569                 return convert_error(zdev, reply);
570         case TYPE86_RSP_CODE:
571                 if (msg->hdr.reply_code) {
572                         memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
573                         return convert_error(zdev, reply);
574                 }
575                 if (msg->cprbx.cprb_ver_id == 0x02)
576                         return convert_type86_xcrb(zdev, reply, xcRB);
577                 /* Fall through, no break, incorrect cprb version is an unknown
578                  * response */
579         default: /* Unknown response type, this should NEVER EVER happen */
580                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
581                 zdev->online = 0;
582                 return -EAGAIN; /* repeat the request on a different device. */
583         }
584 }
585
586 static int convert_response_rng(struct zcrypt_device *zdev,
587                                  struct ap_message *reply,
588                                  char *data)
589 {
590         struct type86x_reply *msg = reply->message;
591
592         switch (msg->hdr.type) {
593         case TYPE82_RSP_CODE:
594         case TYPE88_RSP_CODE:
595                 return -EINVAL;
596         case TYPE86_RSP_CODE:
597                 if (msg->hdr.reply_code)
598                         return -EINVAL;
599                 if (msg->cprbx.cprb_ver_id == 0x02)
600                         return convert_type86_rng(zdev, reply, data);
601                 /* Fall through, no break, incorrect cprb version is an unknown
602                  * response */
603         default: /* Unknown response type, this should NEVER EVER happen */
604                 zdev->online = 0;
605                 return -EAGAIN; /* repeat the request on a different device. */
606         }
607 }
608
609 /**
610  * This function is called from the AP bus code after a crypto request
611  * "msg" has finished with the reply message "reply".
612  * It is called from tasklet context.
613  * @ap_dev: pointer to the AP device
614  * @msg: pointer to the AP message
615  * @reply: pointer to the AP reply message
616  */
617 static void zcrypt_msgtype6_receive(struct ap_device *ap_dev,
618                                   struct ap_message *msg,
619                                   struct ap_message *reply)
620 {
621         static struct error_hdr error_reply = {
622                 .type = TYPE82_RSP_CODE,
623                 .reply_code = REP82_ERROR_MACHINE_FAILURE,
624         };
625         struct response_type *resp_type =
626                 (struct response_type *) msg->private;
627         struct type86x_reply *t86r;
628         int length;
629
630         /* Copy the reply message to the request message buffer. */
631         if (IS_ERR(reply)) {
632                 memcpy(msg->message, &error_reply, sizeof(error_reply));
633                 goto out;
634         }
635         t86r = reply->message;
636         if (t86r->hdr.type == TYPE86_RSP_CODE &&
637                  t86r->cprbx.cprb_ver_id == 0x02) {
638                 switch (resp_type->type) {
639                 case PCIXCC_RESPONSE_TYPE_ICA:
640                         length = sizeof(struct type86x_reply)
641                                 + t86r->length - 2;
642                         length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
643                         memcpy(msg->message, reply->message, length);
644                         break;
645                 case PCIXCC_RESPONSE_TYPE_XCRB:
646                         length = t86r->fmt2.offset2 + t86r->fmt2.count2;
647                         length = min(MSGTYPE06_MAX_MSG_SIZE, length);
648                         memcpy(msg->message, reply->message, length);
649                         break;
650                 default:
651                         memcpy(msg->message, &error_reply,
652                                sizeof(error_reply));
653                 }
654         } else
655                 memcpy(msg->message, reply->message, sizeof(error_reply));
656 out:
657         complete(&(resp_type->work));
658 }
659
660 static atomic_t zcrypt_step = ATOMIC_INIT(0);
661
662 /**
663  * The request distributor calls this function if it picked the PCIXCC/CEX2C
664  * device to handle a modexpo request.
665  * @zdev: pointer to zcrypt_device structure that identifies the
666  *        PCIXCC/CEX2C device to the request distributor
667  * @mex: pointer to the modexpo request buffer
668  */
669 static long zcrypt_msgtype6_modexpo(struct zcrypt_device *zdev,
670                                   struct ica_rsa_modexpo *mex)
671 {
672         struct ap_message ap_msg;
673         struct response_type resp_type = {
674                 .type = PCIXCC_RESPONSE_TYPE_ICA,
675         };
676         int rc;
677
678         ap_init_message(&ap_msg);
679         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
680         if (!ap_msg.message)
681                 return -ENOMEM;
682         ap_msg.receive = zcrypt_msgtype6_receive;
683         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
684                                 atomic_inc_return(&zcrypt_step);
685         ap_msg.private = &resp_type;
686         rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
687         if (rc)
688                 goto out_free;
689         init_completion(&resp_type.work);
690         ap_queue_message(zdev->ap_dev, &ap_msg);
691         rc = wait_for_completion_interruptible(&resp_type.work);
692         if (rc == 0)
693                 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
694                                           mex->outputdatalength);
695         else
696                 /* Signal pending. */
697                 ap_cancel_message(zdev->ap_dev, &ap_msg);
698 out_free:
699         free_page((unsigned long) ap_msg.message);
700         return rc;
701 }
702
703 /**
704  * The request distributor calls this function if it picked the PCIXCC/CEX2C
705  * device to handle a modexpo_crt request.
706  * @zdev: pointer to zcrypt_device structure that identifies the
707  *        PCIXCC/CEX2C device to the request distributor
708  * @crt: pointer to the modexpoc_crt request buffer
709  */
710 static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_device *zdev,
711                                       struct ica_rsa_modexpo_crt *crt)
712 {
713         struct ap_message ap_msg;
714         struct response_type resp_type = {
715                 .type = PCIXCC_RESPONSE_TYPE_ICA,
716         };
717         int rc;
718
719         ap_init_message(&ap_msg);
720         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
721         if (!ap_msg.message)
722                 return -ENOMEM;
723         ap_msg.receive = zcrypt_msgtype6_receive;
724         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
725                                 atomic_inc_return(&zcrypt_step);
726         ap_msg.private = &resp_type;
727         rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
728         if (rc)
729                 goto out_free;
730         init_completion(&resp_type.work);
731         ap_queue_message(zdev->ap_dev, &ap_msg);
732         rc = wait_for_completion_interruptible(&resp_type.work);
733         if (rc == 0)
734                 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
735                                           crt->outputdatalength);
736         else
737                 /* Signal pending. */
738                 ap_cancel_message(zdev->ap_dev, &ap_msg);
739 out_free:
740         free_page((unsigned long) ap_msg.message);
741         return rc;
742 }
743
744 /**
745  * The request distributor calls this function if it picked the PCIXCC/CEX2C
746  * device to handle a send_cprb request.
747  * @zdev: pointer to zcrypt_device structure that identifies the
748  *        PCIXCC/CEX2C device to the request distributor
749  * @xcRB: pointer to the send_cprb request buffer
750  */
751 static long zcrypt_msgtype6_send_cprb(struct zcrypt_device *zdev,
752                                     struct ica_xcRB *xcRB)
753 {
754         struct ap_message ap_msg;
755         struct response_type resp_type = {
756                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
757         };
758         int rc;
759
760         ap_init_message(&ap_msg);
761         ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
762         if (!ap_msg.message)
763                 return -ENOMEM;
764         ap_msg.receive = zcrypt_msgtype6_receive;
765         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
766                                 atomic_inc_return(&zcrypt_step);
767         ap_msg.private = &resp_type;
768         rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
769         if (rc)
770                 goto out_free;
771         init_completion(&resp_type.work);
772         ap_queue_message(zdev->ap_dev, &ap_msg);
773         rc = wait_for_completion_interruptible(&resp_type.work);
774         if (rc == 0)
775                 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
776         else
777                 /* Signal pending. */
778                 ap_cancel_message(zdev->ap_dev, &ap_msg);
779 out_free:
780         kzfree(ap_msg.message);
781         return rc;
782 }
783
784 /**
785  * The request distributor calls this function if it picked the PCIXCC/CEX2C
786  * device to generate random data.
787  * @zdev: pointer to zcrypt_device structure that identifies the
788  *        PCIXCC/CEX2C device to the request distributor
789  * @buffer: pointer to a memory page to return random data
790  */
791
792 static long zcrypt_msgtype6_rng(struct zcrypt_device *zdev,
793                                     char *buffer)
794 {
795         struct ap_message ap_msg;
796         struct response_type resp_type = {
797                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
798         };
799         int rc;
800
801         ap_init_message(&ap_msg);
802         ap_msg.message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL);
803         if (!ap_msg.message)
804                 return -ENOMEM;
805         ap_msg.receive = zcrypt_msgtype6_receive;
806         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
807                                 atomic_inc_return(&zcrypt_step);
808         ap_msg.private = &resp_type;
809         rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
810         init_completion(&resp_type.work);
811         ap_queue_message(zdev->ap_dev, &ap_msg);
812         rc = wait_for_completion_interruptible(&resp_type.work);
813         if (rc == 0)
814                 rc = convert_response_rng(zdev, &ap_msg, buffer);
815         else
816                 /* Signal pending. */
817                 ap_cancel_message(zdev->ap_dev, &ap_msg);
818         kfree(ap_msg.message);
819         return rc;
820 }
821
822 /**
823  * The crypto operations for a PCIXCC/CEX2C card.
824  */
825 static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
826         .owner = THIS_MODULE,
827         .variant = MSGTYPE06_VARIANT_NORNG,
828         .rsa_modexpo = zcrypt_msgtype6_modexpo,
829         .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
830         .send_cprb = zcrypt_msgtype6_send_cprb,
831 };
832
833 static struct zcrypt_ops zcrypt_msgtype6_ops = {
834         .owner = THIS_MODULE,
835         .variant = MSGTYPE06_VARIANT_DEFAULT,
836         .rsa_modexpo = zcrypt_msgtype6_modexpo,
837         .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
838         .send_cprb = zcrypt_msgtype6_send_cprb,
839         .rng = zcrypt_msgtype6_rng,
840 };
841
842 int __init zcrypt_msgtype6_init(void)
843 {
844         zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
845         zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
846         return 0;
847 }
848
849 void __exit zcrypt_msgtype6_exit(void)
850 {
851         zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
852         zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
853 }
854
855 module_init(zcrypt_msgtype6_init);
856 module_exit(zcrypt_msgtype6_exit);