Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq
[linux-2.6] / drivers / s390 / crypto / zcrypt_pcixcc.c
1 /*
2  *  linux/drivers/s390/crypto/zcrypt_pcixcc.c
3  *
4  *  zcrypt 2.1.0
5  *
6  *  Copyright (C)  2001, 2006 IBM Corporation
7  *  Author(s): Robert Burroughs
8  *             Eric Rossman (edrossma@us.ibm.com)
9  *
10  *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11  *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
12  *                                Ralph Wuerthner <rwuerthn@de.ibm.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/err.h>
32 #include <linux/delay.h>
33 #include <asm/atomic.h>
34 #include <asm/uaccess.h>
35
36 #include "ap_bus.h"
37 #include "zcrypt_api.h"
38 #include "zcrypt_error.h"
39 #include "zcrypt_pcicc.h"
40 #include "zcrypt_pcixcc.h"
41 #include "zcrypt_cca_key.h"
42
43 #define PCIXCC_MIN_MOD_SIZE      16     /*  128 bits    */
44 #define PCIXCC_MIN_MOD_SIZE_OLD  64     /*  512 bits    */
45 #define PCIXCC_MAX_MOD_SIZE     256     /* 2048 bits    */
46
47 #define PCIXCC_MCL2_SPEED_RATING        7870    /* FIXME: needs finetuning */
48 #define PCIXCC_MCL3_SPEED_RATING        7870
49 #define CEX2C_SPEED_RATING              8540
50
51 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c  /* max size type6 v2 crt message */
52 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply      */
53
54 #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
55 #define PCIXCC_MAX_XCRB_RESPONSE_SIZE PCIXCC_MAX_XCRB_MESSAGE_SIZE
56 #define PCIXCC_MAX_XCRB_DATA_SIZE (11*1024)
57 #define PCIXCC_MAX_XCRB_REPLY_SIZE (5*1024)
58
59 #define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE
60
61 #define PCIXCC_CLEANUP_TIME     (15*HZ)
62
63 #define CEIL4(x) ((((x)+3)/4)*4)
64
65 struct response_type {
66         struct completion work;
67         int type;
68 };
69 #define PCIXCC_RESPONSE_TYPE_ICA  0
70 #define PCIXCC_RESPONSE_TYPE_XCRB 1
71
72 static struct ap_device_id zcrypt_pcixcc_ids[] = {
73         { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
74         { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
75         { /* end of list */ },
76 };
77
78 #ifndef CONFIG_ZCRYPT_MONOLITHIC
79 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
80 MODULE_AUTHOR("IBM Corporation");
81 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
82                    "Copyright 2001, 2006 IBM Corporation");
83 MODULE_LICENSE("GPL");
84 #endif
85
86 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
87 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
88 static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
89                                  struct ap_message *);
90
91 static struct ap_driver zcrypt_pcixcc_driver = {
92         .probe = zcrypt_pcixcc_probe,
93         .remove = zcrypt_pcixcc_remove,
94         .receive = zcrypt_pcixcc_receive,
95         .ids = zcrypt_pcixcc_ids,
96         .request_timeout = PCIXCC_CLEANUP_TIME,
97 };
98
99 /**
100  * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
101  * card in a type6 message. The 3 fields that must be filled in at execution
102  * time are  req_parml, rpl_parml and usage_domain.
103  * Everything about this interface is ascii/big-endian, since the
104  * device does *not* have 'Intel inside'.
105  *
106  * The CPRBX is followed immediately by the parm block.
107  * The parm block contains:
108  * - function code ('PD' 0x5044 or 'PK' 0x504B)
109  * - rule block (one of:)
110  *   + 0x000A 'PKCS-1.2' (MCL2 'PD')
111  *   + 0x000A 'ZERO-PAD' (MCL2 'PK')
112  *   + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
113  *   + 0x000A 'MRP     ' (MCL3 'PK' or CEX2C 'PK')
114  * - VUD block
115  */
116 static struct CPRBX static_cprbx = {
117         .cprb_len       =  0x00DC,
118         .cprb_ver_id    =  0x02,
119         .func_id        = {0x54,0x32},
120 };
121
122 /**
123  * Convert a ICAMEX message to a type6 MEX message.
124  *
125  * @zdev: crypto device pointer
126  * @ap_msg: pointer to AP message
127  * @mex: pointer to user input data
128  *
129  * Returns 0 on success or -EFAULT.
130  */
131 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
132                                        struct ap_message *ap_msg,
133                                        struct ica_rsa_modexpo *mex)
134 {
135         static struct type6_hdr static_type6_hdrX = {
136                 .type           =  0x06,
137                 .offset1        =  0x00000058,
138                 .agent_id       = {'C','A',},
139                 .function_code  = {'P','K'},
140         };
141         static struct function_and_rules_block static_pke_fnr = {
142                 .function_code  = {'P','K'},
143                 .ulen           = 10,
144                 .only_rule      = {'M','R','P',' ',' ',' ',' ',' '}
145         };
146         static struct function_and_rules_block static_pke_fnr_MCL2 = {
147                 .function_code  = {'P','K'},
148                 .ulen           = 10,
149                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
150         };
151         struct {
152                 struct type6_hdr hdr;
153                 struct CPRBX cprbx;
154                 struct function_and_rules_block fr;
155                 unsigned short length;
156                 char text[0];
157         } __attribute__((packed)) *msg = ap_msg->message;
158         int size;
159
160         /* VUD.ciphertext */
161         msg->length = mex->inputdatalength + 2;
162         if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
163                 return -EFAULT;
164
165         /* Set up key which is located after the variable length text. */
166         size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
167         if (size < 0)
168                 return size;
169         size += sizeof(*msg) + mex->inputdatalength;
170
171         /* message header, cprbx and f&r */
172         msg->hdr = static_type6_hdrX;
173         msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
174         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
175
176         msg->cprbx = static_cprbx;
177         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
178         msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
179
180         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
181                 static_pke_fnr_MCL2 : static_pke_fnr;
182
183         msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
184
185         ap_msg->length = size;
186         return 0;
187 }
188
189 /**
190  * Convert a ICACRT message to a type6 CRT message.
191  *
192  * @zdev: crypto device pointer
193  * @ap_msg: pointer to AP message
194  * @crt: pointer to user input data
195  *
196  * Returns 0 on success or -EFAULT.
197  */
198 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
199                                        struct ap_message *ap_msg,
200                                        struct ica_rsa_modexpo_crt *crt)
201 {
202         static struct type6_hdr static_type6_hdrX = {
203                 .type           =  0x06,
204                 .offset1        =  0x00000058,
205                 .agent_id       = {'C','A',},
206                 .function_code  = {'P','D'},
207         };
208         static struct function_and_rules_block static_pkd_fnr = {
209                 .function_code  = {'P','D'},
210                 .ulen           = 10,
211                 .only_rule      = {'Z','E','R','O','-','P','A','D'}
212         };
213
214         static struct function_and_rules_block static_pkd_fnr_MCL2 = {
215                 .function_code  = {'P','D'},
216                 .ulen           = 10,
217                 .only_rule      = {'P','K','C','S','-','1','.','2'}
218         };
219         struct {
220                 struct type6_hdr hdr;
221                 struct CPRBX cprbx;
222                 struct function_and_rules_block fr;
223                 unsigned short length;
224                 char text[0];
225         } __attribute__((packed)) *msg = ap_msg->message;
226         int size;
227
228         /* VUD.ciphertext */
229         msg->length = crt->inputdatalength + 2;
230         if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
231                 return -EFAULT;
232
233         /* Set up key which is located after the variable length text. */
234         size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
235         if (size < 0)
236                 return size;
237         size += sizeof(*msg) + crt->inputdatalength;    /* total size of msg */
238
239         /* message header, cprbx and f&r */
240         msg->hdr = static_type6_hdrX;
241         msg->hdr.ToCardLen1 = size -  sizeof(msg->hdr);
242         msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
243
244         msg->cprbx = static_cprbx;
245         msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
246         msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
247                 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
248
249         msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
250                 static_pkd_fnr_MCL2 : static_pkd_fnr;
251
252         ap_msg->length = size;
253         return 0;
254 }
255
256 /**
257  * Convert a XCRB message to a type6 CPRB message.
258  *
259  * @zdev: crypto device pointer
260  * @ap_msg: pointer to AP message
261  * @xcRB: pointer to user input data
262  *
263  * Returns 0 on success or -EFAULT.
264  */
265 struct type86_fmt2_msg {
266         struct type86_hdr hdr;
267         struct type86_fmt2_ext fmt2;
268 } __attribute__((packed));
269
270 static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
271                                        struct ap_message *ap_msg,
272                                        struct ica_xcRB *xcRB)
273 {
274         static struct type6_hdr static_type6_hdrX = {
275                 .type           =  0x06,
276                 .offset1        =  0x00000058,
277         };
278         struct {
279                 struct type6_hdr hdr;
280                 struct CPRBX cprbx;
281         } __attribute__((packed)) *msg = ap_msg->message;
282
283         int rcblen = CEIL4(xcRB->request_control_blk_length);
284         int replylen;
285         char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
286         char *function_code;
287
288         /* length checks */
289         ap_msg->length = sizeof(struct type6_hdr) +
290                 CEIL4(xcRB->request_control_blk_length) +
291                 xcRB->request_data_length;
292         if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) {
293                 PRINTK("Combined message is too large (%ld/%d/%d).\n",
294                     sizeof(struct type6_hdr),
295                     xcRB->request_control_blk_length,
296                     xcRB->request_data_length);
297                 return -EFAULT;
298         }
299         if (CEIL4(xcRB->reply_control_blk_length) >
300             PCIXCC_MAX_XCRB_REPLY_SIZE) {
301                 PDEBUG("Reply CPRB length is too large (%d).\n",
302                     xcRB->request_control_blk_length);
303                 return -EFAULT;
304         }
305         if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE) {
306                 PDEBUG("Reply data block length is too large (%d).\n",
307                     xcRB->reply_data_length);
308                 return -EFAULT;
309         }
310         replylen = CEIL4(xcRB->reply_control_blk_length) +
311                 CEIL4(xcRB->reply_data_length) +
312                 sizeof(struct type86_fmt2_msg);
313         if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
314                 PDEBUG("Reply CPRB + data block > PCIXCC_MAX_XCRB_RESPONSE_SIZE"
315                        " (%d/%d/%d).\n",
316                        sizeof(struct type86_fmt2_msg),
317                        xcRB->reply_control_blk_length,
318                        xcRB->reply_data_length);
319                 xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
320                         (sizeof(struct type86_fmt2_msg) +
321                             CEIL4(xcRB->reply_data_length));
322                 PDEBUG("Capping Reply CPRB length at %d\n",
323                        xcRB->reply_control_blk_length);
324         }
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                 PDEBUG("cprb_len too large (%d/%d)\n", msg->cprbx.cprb_len,
344                     xcRB->request_control_blk_length);
345                 return -EFAULT;
346         }
347         function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
348         memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
349
350         /* copy data block */
351         if (xcRB->request_data_length &&
352             copy_from_user(req_data, xcRB->request_data_address,
353                 xcRB->request_data_length))
354                 return -EFAULT;
355         return 0;
356 }
357
358 /**
359  * Copy results from a type 86 ICA reply message back to user space.
360  *
361  * @zdev: crypto device pointer
362  * @reply: reply AP message.
363  * @data: pointer to user output data
364  * @length: size of user output data
365  *
366  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
367  */
368 struct type86x_reply {
369         struct type86_hdr hdr;
370         struct type86_fmt2_ext fmt2;
371         struct CPRBX cprbx;
372         unsigned char pad[4];   /* 4 byte function code/rules block ? */
373         unsigned short length;
374         char text[0];
375 } __attribute__((packed));
376
377 static int convert_type86_ica(struct zcrypt_device *zdev,
378                           struct ap_message *reply,
379                           char __user *outputdata,
380                           unsigned int outputdatalength)
381 {
382         static unsigned char static_pad[] = {
383                 0x00,0x02,
384                 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
385                 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
386                 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
387                 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
388                 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
389                 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
390                 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
391                 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
392                 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
393                 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
394                 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
395                 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
396                 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
397                 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
398                 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
399                 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
400                 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
401                 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
402                 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
403                 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
404                 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
405                 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
406                 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
407                 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
408                 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
409                 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
410                 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
411                 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
412                 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
413                 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
414                 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
415                 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
416         };
417         struct type86x_reply *msg = reply->message;
418         unsigned short service_rc, service_rs;
419         unsigned int reply_len, pad_len;
420         char *data;
421
422         service_rc = msg->cprbx.ccp_rtcode;
423         if (unlikely(service_rc != 0)) {
424                 service_rs = msg->cprbx.ccp_rscode;
425                 if (service_rc == 8 && service_rs == 66) {
426                         PDEBUG("Bad block format on PCIXCC/CEX2C\n");
427                         return -EINVAL;
428                 }
429                 if (service_rc == 8 && service_rs == 65) {
430                         PDEBUG("Probably an even modulus on PCIXCC/CEX2C\n");
431                         return -EINVAL;
432                 }
433                 if (service_rc == 8 && service_rs == 770) {
434                         PDEBUG("Invalid key length on PCIXCC/CEX2C\n");
435                         return -EINVAL;
436                 }
437                 if (service_rc == 8 && service_rs == 783) {
438                         PDEBUG("Extended bitlengths not enabled on PCIXCC/CEX2C\n");
439                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
440                         return -EAGAIN;
441                 }
442                 if (service_rc == 12 && service_rs == 769) {
443                         PDEBUG("Invalid key on PCIXCC/CEX2C\n");
444                         return -EINVAL;
445                 }
446                 PRINTK("Unknown service rc/rs (PCIXCC/CEX2C): %d/%d\n",
447                        service_rc, service_rs);
448                 zdev->online = 0;
449                 return -EAGAIN; /* repeat the request on a different device. */
450         }
451         data = msg->text;
452         reply_len = msg->length - 2;
453         if (reply_len > outputdatalength)
454                 return -EINVAL;
455         /**
456          * For all encipher requests, the length of the ciphertext (reply_len)
457          * will always equal the modulus length. For MEX decipher requests
458          * the output needs to get padded. Minimum pad size is 10.
459          *
460          * Currently, the cases where padding will be added is for:
461          * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
462          *   ZERO-PAD and CRT is only supported for PKD requests)
463          * - PCICC, always
464          */
465         pad_len = outputdatalength - reply_len;
466         if (pad_len > 0) {
467                 if (pad_len < 10)
468                         return -EINVAL;
469                 /* 'restore' padding left in the PCICC/PCIXCC card. */
470                 if (copy_to_user(outputdata, static_pad, pad_len - 1))
471                         return -EFAULT;
472                 if (put_user(0, outputdata + pad_len - 1))
473                         return -EFAULT;
474         }
475         /* Copy the crypto response to user space. */
476         if (copy_to_user(outputdata + pad_len, data, reply_len))
477                 return -EFAULT;
478         return 0;
479 }
480
481 /**
482  * Copy results from a type 86 XCRB reply message back to user space.
483  *
484  * @zdev: crypto device pointer
485  * @reply: reply AP message.
486  * @xcRB: pointer to XCRB
487  *
488  * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
489  */
490 static int convert_type86_xcrb(struct zcrypt_device *zdev,
491                                struct ap_message *reply,
492                                struct ica_xcRB *xcRB)
493 {
494         struct type86_fmt2_msg *msg = reply->message;
495         char *data = reply->message;
496
497         /* Copy CPRB to user */
498         if (copy_to_user(xcRB->reply_control_blk_addr,
499                 data + msg->fmt2.offset1, msg->fmt2.count1))
500                 return -EFAULT;
501         xcRB->reply_control_blk_length = msg->fmt2.count1;
502
503         /* Copy data buffer to user */
504         if (msg->fmt2.count2)
505                 if (copy_to_user(xcRB->reply_data_addr,
506                         data + msg->fmt2.offset2, msg->fmt2.count2))
507                         return -EFAULT;
508         xcRB->reply_data_length = msg->fmt2.count2;
509         return 0;
510 }
511
512 static int convert_response_ica(struct zcrypt_device *zdev,
513                             struct ap_message *reply,
514                             char __user *outputdata,
515                             unsigned int outputdatalength)
516 {
517         struct type86x_reply *msg = reply->message;
518
519         /* Response type byte is the second byte in the response. */
520         switch (((unsigned char *) reply->message)[1]) {
521         case TYPE82_RSP_CODE:
522         case TYPE88_RSP_CODE:
523                 return convert_error(zdev, reply);
524         case TYPE86_RSP_CODE:
525                 if (msg->hdr.reply_code)
526                         return convert_error(zdev, reply);
527                 if (msg->cprbx.cprb_ver_id == 0x02)
528                         return convert_type86_ica(zdev, reply,
529                                                   outputdata, outputdatalength);
530                 /* no break, incorrect cprb version is an unknown response */
531         default: /* Unknown response type, this should NEVER EVER happen */
532                 PRINTK("Unrecognized Message Header: %08x%08x\n",
533                        *(unsigned int *) reply->message,
534                        *(unsigned int *) (reply->message+4));
535                 zdev->online = 0;
536                 return -EAGAIN; /* repeat the request on a different device. */
537         }
538 }
539
540 static int convert_response_xcrb(struct zcrypt_device *zdev,
541                             struct ap_message *reply,
542                             struct ica_xcRB *xcRB)
543 {
544         struct type86x_reply *msg = reply->message;
545
546         /* Response type byte is the second byte in the response. */
547         switch (((unsigned char *) reply->message)[1]) {
548         case TYPE82_RSP_CODE:
549         case TYPE88_RSP_CODE:
550                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
551                 return convert_error(zdev, reply);
552         case TYPE86_RSP_CODE:
553                 if (msg->hdr.reply_code) {
554                         memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
555                         return convert_error(zdev, reply);
556                 }
557                 if (msg->cprbx.cprb_ver_id == 0x02)
558                         return convert_type86_xcrb(zdev, reply, xcRB);
559                 /* no break, incorrect cprb version is an unknown response */
560         default: /* Unknown response type, this should NEVER EVER happen */
561                 PRINTK("Unrecognized Message Header: %08x%08x\n",
562                        *(unsigned int *) reply->message,
563                        *(unsigned int *) (reply->message+4));
564                 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
565                 zdev->online = 0;
566                 return -EAGAIN; /* repeat the request on a different device. */
567         }
568 }
569
570 /**
571  * This function is called from the AP bus code after a crypto request
572  * "msg" has finished with the reply message "reply".
573  * It is called from tasklet context.
574  * @ap_dev: pointer to the AP device
575  * @msg: pointer to the AP message
576  * @reply: pointer to the AP reply message
577  */
578 static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
579                                   struct ap_message *msg,
580                                   struct ap_message *reply)
581 {
582         static struct error_hdr error_reply = {
583                 .type = TYPE82_RSP_CODE,
584                 .reply_code = REP82_ERROR_MACHINE_FAILURE,
585         };
586         struct response_type *resp_type =
587                 (struct response_type *) msg->private;
588         struct type86x_reply *t86r = reply->message;
589         int length;
590
591         /* Copy the reply message to the request message buffer. */
592         if (IS_ERR(reply))
593                 memcpy(msg->message, &error_reply, sizeof(error_reply));
594         else if (t86r->hdr.type == TYPE86_RSP_CODE &&
595                  t86r->cprbx.cprb_ver_id == 0x02) {
596                 switch (resp_type->type) {
597                 case PCIXCC_RESPONSE_TYPE_ICA:
598                         length = sizeof(struct type86x_reply)
599                                 + t86r->length - 2;
600                         length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
601                         memcpy(msg->message, reply->message, length);
602                         break;
603                 case PCIXCC_RESPONSE_TYPE_XCRB:
604                         length = t86r->fmt2.offset2 + t86r->fmt2.count2;
605                         length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
606                         memcpy(msg->message, reply->message, length);
607                         break;
608                 default:
609                         PRINTK("Invalid internal response type: %i\n",
610                             resp_type->type);
611                         memcpy(msg->message, &error_reply,
612                             sizeof error_reply);
613                 }
614         } else
615                 memcpy(msg->message, reply->message, sizeof error_reply);
616         complete(&(resp_type->work));
617 }
618
619 static atomic_t zcrypt_step = ATOMIC_INIT(0);
620
621 /**
622  * The request distributor calls this function if it picked the PCIXCC/CEX2C
623  * device to handle a modexpo request.
624  * @zdev: pointer to zcrypt_device structure that identifies the
625  *        PCIXCC/CEX2C device to the request distributor
626  * @mex: pointer to the modexpo request buffer
627  */
628 static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
629                                   struct ica_rsa_modexpo *mex)
630 {
631         struct ap_message ap_msg;
632         struct response_type resp_type = {
633                 .type = PCIXCC_RESPONSE_TYPE_ICA,
634         };
635         int rc;
636
637         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
638         if (!ap_msg.message)
639                 return -ENOMEM;
640         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
641                                 atomic_inc_return(&zcrypt_step);
642         ap_msg.private = &resp_type;
643         rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
644         if (rc)
645                 goto out_free;
646         init_completion(&resp_type.work);
647         ap_queue_message(zdev->ap_dev, &ap_msg);
648         rc = wait_for_completion_interruptible(&resp_type.work);
649         if (rc == 0)
650                 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
651                                           mex->outputdatalength);
652         else
653                 /* Signal pending. */
654                 ap_cancel_message(zdev->ap_dev, &ap_msg);
655 out_free:
656         free_page((unsigned long) ap_msg.message);
657         return rc;
658 }
659
660 /**
661  * The request distributor calls this function if it picked the PCIXCC/CEX2C
662  * device to handle a modexpo_crt request.
663  * @zdev: pointer to zcrypt_device structure that identifies the
664  *        PCIXCC/CEX2C device to the request distributor
665  * @crt: pointer to the modexpoc_crt request buffer
666  */
667 static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
668                                       struct ica_rsa_modexpo_crt *crt)
669 {
670         struct ap_message ap_msg;
671         struct response_type resp_type = {
672                 .type = PCIXCC_RESPONSE_TYPE_ICA,
673         };
674         int rc;
675
676         ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
677         if (!ap_msg.message)
678                 return -ENOMEM;
679         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
680                                 atomic_inc_return(&zcrypt_step);
681         ap_msg.private = &resp_type;
682         rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
683         if (rc)
684                 goto out_free;
685         init_completion(&resp_type.work);
686         ap_queue_message(zdev->ap_dev, &ap_msg);
687         rc = wait_for_completion_interruptible(&resp_type.work);
688         if (rc == 0)
689                 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
690                                           crt->outputdatalength);
691         else
692                 /* Signal pending. */
693                 ap_cancel_message(zdev->ap_dev, &ap_msg);
694 out_free:
695         free_page((unsigned long) ap_msg.message);
696         return rc;
697 }
698
699 /**
700  * The request distributor calls this function if it picked the PCIXCC/CEX2C
701  * device to handle a send_cprb request.
702  * @zdev: pointer to zcrypt_device structure that identifies the
703  *        PCIXCC/CEX2C device to the request distributor
704  * @xcRB: pointer to the send_cprb request buffer
705  */
706 static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
707                                     struct ica_xcRB *xcRB)
708 {
709         struct ap_message ap_msg;
710         struct response_type resp_type = {
711                 .type = PCIXCC_RESPONSE_TYPE_XCRB,
712         };
713         int rc;
714
715         ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
716         if (!ap_msg.message)
717                 return -ENOMEM;
718         ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
719                                 atomic_inc_return(&zcrypt_step);
720         ap_msg.private = &resp_type;
721         rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
722         if (rc)
723                 goto out_free;
724         init_completion(&resp_type.work);
725         ap_queue_message(zdev->ap_dev, &ap_msg);
726         rc = wait_for_completion_interruptible(&resp_type.work);
727         if (rc == 0)
728                 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
729         else
730                 /* Signal pending. */
731                 ap_cancel_message(zdev->ap_dev, &ap_msg);
732 out_free:
733         memset(ap_msg.message, 0x0, ap_msg.length);
734         kfree(ap_msg.message);
735         return rc;
736 }
737
738 /**
739  * The crypto operations for a PCIXCC/CEX2C card.
740  */
741 static struct zcrypt_ops zcrypt_pcixcc_ops = {
742         .rsa_modexpo = zcrypt_pcixcc_modexpo,
743         .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
744         .send_cprb = zcrypt_pcixcc_send_cprb,
745 };
746
747 /**
748  * Micro-code detection function. Its sends a message to a pcixcc card
749  * to find out the microcode level.
750  * @ap_dev: pointer to the AP device.
751  */
752 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
753 {
754         static unsigned char msg[] = {
755                 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
756                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
757                 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
758                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
759                 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
760                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
761                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
762                 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
763                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
764                 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
765                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
766                 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
767                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
768                 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
769                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
770                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
771                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
772                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
773                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
774                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
775                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
776                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
777                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
778                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
779                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
780                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
781                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
782                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
783                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
784                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
785                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
786                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
787                 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
788                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
789                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
790                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
791                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
792                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
793                 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
794                 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
795                 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
796                 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
797                 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
798                 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
799                 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
800                 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
801                 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
802                 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
803                 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
804                 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
805                 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
806                 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
807                 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
808                 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
809                 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
810                 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
811                 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
812                 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
813                 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
814                 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
815                 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
816                 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
817                 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
818                 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
819                 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
820                 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
821                 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
822                 0xF1,0x3D,0x93,0x53
823         };
824         unsigned long long psmid;
825         struct CPRBX *cprbx;
826         char *reply;
827         int rc, i;
828
829         reply = (void *) get_zeroed_page(GFP_KERNEL);
830         if (!reply)
831                 return -ENOMEM;
832
833         rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
834         if (rc)
835                 goto out_free;
836
837         /* Wait for the test message to complete. */
838         for (i = 0; i < 6; i++) {
839                 mdelay(300);
840                 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
841                 if (rc == 0 && psmid == 0x0102030405060708ULL)
842                         break;
843         }
844
845         if (i >= 6) {
846                 /* Got no answer. */
847                 rc = -ENODEV;
848                 goto out_free;
849         }
850
851         cprbx = (struct CPRBX *) (reply + 48);
852         if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
853                 rc = ZCRYPT_PCIXCC_MCL2;
854         else
855                 rc = ZCRYPT_PCIXCC_MCL3;
856 out_free:
857         free_page((unsigned long) reply);
858         return rc;
859 }
860
861 /**
862  * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
863  * since the bus_match already checked the hardware type. The PCIXCC
864  * cards come in two flavours: micro code level 2 and micro code level 3.
865  * This is checked by sending a test message to the device.
866  * @ap_dev: pointer to the AP device.
867  */
868 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
869 {
870         struct zcrypt_device *zdev;
871         int rc;
872
873         zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
874         if (!zdev)
875                 return -ENOMEM;
876         zdev->ap_dev = ap_dev;
877         zdev->ops = &zcrypt_pcixcc_ops;
878         zdev->online = 1;
879         if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
880                 rc = zcrypt_pcixcc_mcl(ap_dev);
881                 if (rc < 0) {
882                         zcrypt_device_free(zdev);
883                         return rc;
884                 }
885                 zdev->user_space_type = rc;
886                 if (rc == ZCRYPT_PCIXCC_MCL2) {
887                         zdev->type_string = "PCIXCC_MCL2";
888                         zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
889                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
890                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
891                 } else {
892                         zdev->type_string = "PCIXCC_MCL3";
893                         zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
894                         zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
895                         zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
896                 }
897         } else {
898                 zdev->user_space_type = ZCRYPT_CEX2C;
899                 zdev->type_string = "CEX2C";
900                 zdev->speed_rating = CEX2C_SPEED_RATING;
901                 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
902                 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
903         }
904         ap_dev->reply = &zdev->reply;
905         ap_dev->private = zdev;
906         rc = zcrypt_device_register(zdev);
907         if (rc)
908                 goto out_free;
909         return 0;
910
911  out_free:
912         ap_dev->private = NULL;
913         zcrypt_device_free(zdev);
914         return rc;
915 }
916
917 /**
918  * This is called to remove the extended PCIXCC/CEX2C driver information
919  * if an AP device is removed.
920  */
921 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
922 {
923         struct zcrypt_device *zdev = ap_dev->private;
924
925         zcrypt_device_unregister(zdev);
926 }
927
928 int __init zcrypt_pcixcc_init(void)
929 {
930         return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
931 }
932
933 void zcrypt_pcixcc_exit(void)
934 {
935         ap_driver_unregister(&zcrypt_pcixcc_driver);
936 }
937
938 #ifndef CONFIG_ZCRYPT_MONOLITHIC
939 module_init(zcrypt_pcixcc_init);
940 module_exit(zcrypt_pcixcc_exit);
941 #endif