init from v2.6.32.60
[mach-moxart.git] / drivers / s390 / crypto / zcrypt_pcixcc.c
blob1f9e92387208f07ccc9a1440ddf1a76c2be53c02
1 /*
2 * linux/drivers/s390/crypto/zcrypt_pcixcc.c
4 * zcrypt 2.1.0
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
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>
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.
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.
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.
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>
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"
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 */
47 #define PCIXCC_MCL2_SPEED_RATING 7870 /* FIXME: needs finetuning */
48 #define PCIXCC_MCL3_SPEED_RATING 7870
49 #define CEX2C_SPEED_RATING 8540
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 */
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)
59 #define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE
61 #define PCIXCC_CLEANUP_TIME (15*HZ)
63 #define CEIL4(x) ((((x)+3)/4)*4)
65 struct response_type {
66 struct completion work;
67 int type;
69 #define PCIXCC_RESPONSE_TYPE_ICA 0
70 #define PCIXCC_RESPONSE_TYPE_XCRB 1
72 static struct ap_device_id zcrypt_pcixcc_ids[] = {
73 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
74 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
75 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) },
76 { /* end of list */ },
79 #ifndef CONFIG_ZCRYPT_MONOLITHIC
80 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
81 MODULE_AUTHOR("IBM Corporation");
82 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
83 "Copyright 2001, 2006 IBM Corporation");
84 MODULE_LICENSE("GPL");
85 #endif
87 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
88 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
89 static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
90 struct ap_message *);
92 static struct ap_driver zcrypt_pcixcc_driver = {
93 .probe = zcrypt_pcixcc_probe,
94 .remove = zcrypt_pcixcc_remove,
95 .receive = zcrypt_pcixcc_receive,
96 .ids = zcrypt_pcixcc_ids,
97 .request_timeout = PCIXCC_CLEANUP_TIME,
101 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
102 * card in a type6 message. The 3 fields that must be filled in at execution
103 * time are req_parml, rpl_parml and usage_domain.
104 * Everything about this interface is ascii/big-endian, since the
105 * device does *not* have 'Intel inside'.
107 * The CPRBX is followed immediately by the parm block.
108 * The parm block contains:
109 * - function code ('PD' 0x5044 or 'PK' 0x504B)
110 * - rule block (one of:)
111 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
112 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
113 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
114 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
115 * - VUD block
117 static struct CPRBX static_cprbx = {
118 .cprb_len = 0x00DC,
119 .cprb_ver_id = 0x02,
120 .func_id = {0x54,0x32},
124 * Convert a ICAMEX message to a type6 MEX message.
126 * @zdev: crypto device pointer
127 * @ap_msg: pointer to AP message
128 * @mex: pointer to user input data
130 * Returns 0 on success or -EFAULT.
132 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
133 struct ap_message *ap_msg,
134 struct ica_rsa_modexpo *mex)
136 static struct type6_hdr static_type6_hdrX = {
137 .type = 0x06,
138 .offset1 = 0x00000058,
139 .agent_id = {'C','A',},
140 .function_code = {'P','K'},
142 static struct function_and_rules_block static_pke_fnr = {
143 .function_code = {'P','K'},
144 .ulen = 10,
145 .only_rule = {'M','R','P',' ',' ',' ',' ',' '}
147 static struct function_and_rules_block static_pke_fnr_MCL2 = {
148 .function_code = {'P','K'},
149 .ulen = 10,
150 .only_rule = {'Z','E','R','O','-','P','A','D'}
152 struct {
153 struct type6_hdr hdr;
154 struct CPRBX cprbx;
155 struct function_and_rules_block fr;
156 unsigned short length;
157 char text[0];
158 } __attribute__((packed)) *msg = ap_msg->message;
159 int size;
161 /* VUD.ciphertext */
162 msg->length = mex->inputdatalength + 2;
163 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
164 return -EFAULT;
166 /* Set up key which is located after the variable length text. */
167 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
168 if (size < 0)
169 return size;
170 size += sizeof(*msg) + mex->inputdatalength;
172 /* message header, cprbx and f&r */
173 msg->hdr = static_type6_hdrX;
174 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
175 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
177 msg->cprbx = static_cprbx;
178 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
179 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
181 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
182 static_pke_fnr_MCL2 : static_pke_fnr;
184 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
186 ap_msg->length = size;
187 return 0;
191 * Convert a ICACRT message to a type6 CRT message.
193 * @zdev: crypto device pointer
194 * @ap_msg: pointer to AP message
195 * @crt: pointer to user input data
197 * Returns 0 on success or -EFAULT.
199 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
200 struct ap_message *ap_msg,
201 struct ica_rsa_modexpo_crt *crt)
203 static struct type6_hdr static_type6_hdrX = {
204 .type = 0x06,
205 .offset1 = 0x00000058,
206 .agent_id = {'C','A',},
207 .function_code = {'P','D'},
209 static struct function_and_rules_block static_pkd_fnr = {
210 .function_code = {'P','D'},
211 .ulen = 10,
212 .only_rule = {'Z','E','R','O','-','P','A','D'}
215 static struct function_and_rules_block static_pkd_fnr_MCL2 = {
216 .function_code = {'P','D'},
217 .ulen = 10,
218 .only_rule = {'P','K','C','S','-','1','.','2'}
220 struct {
221 struct type6_hdr hdr;
222 struct CPRBX cprbx;
223 struct function_and_rules_block fr;
224 unsigned short length;
225 char text[0];
226 } __attribute__((packed)) *msg = ap_msg->message;
227 int size;
229 /* VUD.ciphertext */
230 msg->length = crt->inputdatalength + 2;
231 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
232 return -EFAULT;
234 /* Set up key which is located after the variable length text. */
235 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
236 if (size < 0)
237 return size;
238 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
240 /* message header, cprbx and f&r */
241 msg->hdr = static_type6_hdrX;
242 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
243 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
245 msg->cprbx = static_cprbx;
246 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
247 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
248 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
250 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
251 static_pkd_fnr_MCL2 : static_pkd_fnr;
253 ap_msg->length = size;
254 return 0;
258 * Convert a XCRB message to a type6 CPRB message.
260 * @zdev: crypto device pointer
261 * @ap_msg: pointer to AP message
262 * @xcRB: pointer to user input data
264 * Returns 0 on success or -EFAULT.
266 struct type86_fmt2_msg {
267 struct type86_hdr hdr;
268 struct type86_fmt2_ext fmt2;
269 } __attribute__((packed));
271 static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
272 struct ap_message *ap_msg,
273 struct ica_xcRB *xcRB)
275 static struct type6_hdr static_type6_hdrX = {
276 .type = 0x06,
277 .offset1 = 0x00000058,
279 struct {
280 struct type6_hdr hdr;
281 struct CPRBX cprbx;
282 } __attribute__((packed)) *msg = ap_msg->message;
284 int rcblen = CEIL4(xcRB->request_control_blk_length);
285 int replylen;
286 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
287 char *function_code;
289 /* length checks */
290 ap_msg->length = sizeof(struct type6_hdr) +
291 CEIL4(xcRB->request_control_blk_length) +
292 xcRB->request_data_length;
293 if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
294 return -EFAULT;
295 if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE)
296 return -EFAULT;
297 if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE)
298 return -EFAULT;
299 replylen = CEIL4(xcRB->reply_control_blk_length) +
300 CEIL4(xcRB->reply_data_length) +
301 sizeof(struct type86_fmt2_msg);
302 if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
303 xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
304 (sizeof(struct type86_fmt2_msg) +
305 CEIL4(xcRB->reply_data_length));
308 /* prepare type6 header */
309 msg->hdr = static_type6_hdrX;
310 memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
311 msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
312 if (xcRB->request_data_length) {
313 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
314 msg->hdr.ToCardLen2 = xcRB->request_data_length;
316 msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
317 msg->hdr.FromCardLen2 = xcRB->reply_data_length;
319 /* prepare CPRB */
320 if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
321 xcRB->request_control_blk_length))
322 return -EFAULT;
323 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
324 xcRB->request_control_blk_length)
325 return -EFAULT;
326 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
327 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
329 /* copy data block */
330 if (xcRB->request_data_length &&
331 copy_from_user(req_data, xcRB->request_data_address,
332 xcRB->request_data_length))
333 return -EFAULT;
334 return 0;
338 * Prepare a type6 CPRB message for random number generation
340 * @ap_dev: AP device pointer
341 * @ap_msg: pointer to AP message
343 static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
344 struct ap_message *ap_msg,
345 unsigned random_number_length)
347 struct {
348 struct type6_hdr hdr;
349 struct CPRBX cprbx;
350 char function_code[2];
351 short int rule_length;
352 char rule[8];
353 short int verb_length;
354 short int key_length;
355 } __attribute__((packed)) *msg = ap_msg->message;
356 static struct type6_hdr static_type6_hdrX = {
357 .type = 0x06,
358 .offset1 = 0x00000058,
359 .agent_id = {'C', 'A'},
360 .function_code = {'R', 'L'},
361 .ToCardLen1 = sizeof *msg - sizeof(msg->hdr),
362 .FromCardLen1 = sizeof *msg - sizeof(msg->hdr),
364 static struct CPRBX local_cprbx = {
365 .cprb_len = 0x00dc,
366 .cprb_ver_id = 0x02,
367 .func_id = {0x54, 0x32},
368 .req_parml = sizeof *msg - sizeof(msg->hdr) -
369 sizeof(msg->cprbx),
370 .rpl_msgbl = sizeof *msg - sizeof(msg->hdr),
373 msg->hdr = static_type6_hdrX;
374 msg->hdr.FromCardLen2 = random_number_length,
375 msg->cprbx = local_cprbx;
376 msg->cprbx.rpl_datal = random_number_length,
377 msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
378 memcpy(msg->function_code, msg->hdr.function_code, 0x02);
379 msg->rule_length = 0x0a;
380 memcpy(msg->rule, "RANDOM ", 8);
381 msg->verb_length = 0x02;
382 msg->key_length = 0x02;
383 ap_msg->length = sizeof *msg;
387 * Copy results from a type 86 ICA reply message back to user space.
389 * @zdev: crypto device pointer
390 * @reply: reply AP message.
391 * @data: pointer to user output data
392 * @length: size of user output data
394 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
396 struct type86x_reply {
397 struct type86_hdr hdr;
398 struct type86_fmt2_ext fmt2;
399 struct CPRBX cprbx;
400 unsigned char pad[4]; /* 4 byte function code/rules block ? */
401 unsigned short length;
402 char text[0];
403 } __attribute__((packed));
405 static int convert_type86_ica(struct zcrypt_device *zdev,
406 struct ap_message *reply,
407 char __user *outputdata,
408 unsigned int outputdatalength)
410 static unsigned char static_pad[] = {
411 0x00,0x02,
412 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
413 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
414 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
415 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
416 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
417 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
418 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
419 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
420 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
421 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
422 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
423 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
424 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
425 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
426 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
427 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
428 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
429 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
430 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
431 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
432 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
433 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
434 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
435 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
436 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
437 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
438 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
439 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
440 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
441 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
442 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
443 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
445 struct type86x_reply *msg = reply->message;
446 unsigned short service_rc, service_rs;
447 unsigned int reply_len, pad_len;
448 char *data;
450 service_rc = msg->cprbx.ccp_rtcode;
451 if (unlikely(service_rc != 0)) {
452 service_rs = msg->cprbx.ccp_rscode;
453 if (service_rc == 8 && service_rs == 66)
454 return -EINVAL;
455 if (service_rc == 8 && service_rs == 65)
456 return -EINVAL;
457 if (service_rc == 8 && service_rs == 770)
458 return -EINVAL;
459 if (service_rc == 8 && service_rs == 783) {
460 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
461 return -EAGAIN;
463 if (service_rc == 12 && service_rs == 769)
464 return -EINVAL;
465 if (service_rc == 8 && service_rs == 72)
466 return -EINVAL;
467 zdev->online = 0;
468 return -EAGAIN; /* repeat the request on a different device. */
470 data = msg->text;
471 reply_len = msg->length - 2;
472 if (reply_len > outputdatalength)
473 return -EINVAL;
475 * For all encipher requests, the length of the ciphertext (reply_len)
476 * will always equal the modulus length. For MEX decipher requests
477 * the output needs to get padded. Minimum pad size is 10.
479 * Currently, the cases where padding will be added is for:
480 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
481 * ZERO-PAD and CRT is only supported for PKD requests)
482 * - PCICC, always
484 pad_len = outputdatalength - reply_len;
485 if (pad_len > 0) {
486 if (pad_len < 10)
487 return -EINVAL;
488 /* 'restore' padding left in the PCICC/PCIXCC card. */
489 if (copy_to_user(outputdata, static_pad, pad_len - 1))
490 return -EFAULT;
491 if (put_user(0, outputdata + pad_len - 1))
492 return -EFAULT;
494 /* Copy the crypto response to user space. */
495 if (copy_to_user(outputdata + pad_len, data, reply_len))
496 return -EFAULT;
497 return 0;
501 * Copy results from a type 86 XCRB reply message back to user space.
503 * @zdev: crypto device pointer
504 * @reply: reply AP message.
505 * @xcRB: pointer to XCRB
507 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
509 static int convert_type86_xcrb(struct zcrypt_device *zdev,
510 struct ap_message *reply,
511 struct ica_xcRB *xcRB)
513 struct type86_fmt2_msg *msg = reply->message;
514 char *data = reply->message;
516 /* Copy CPRB to user */
517 if (copy_to_user(xcRB->reply_control_blk_addr,
518 data + msg->fmt2.offset1, msg->fmt2.count1))
519 return -EFAULT;
520 xcRB->reply_control_blk_length = msg->fmt2.count1;
522 /* Copy data buffer to user */
523 if (msg->fmt2.count2)
524 if (copy_to_user(xcRB->reply_data_addr,
525 data + msg->fmt2.offset2, msg->fmt2.count2))
526 return -EFAULT;
527 xcRB->reply_data_length = msg->fmt2.count2;
528 return 0;
531 static int convert_type86_rng(struct zcrypt_device *zdev,
532 struct ap_message *reply,
533 char *buffer)
535 struct {
536 struct type86_hdr hdr;
537 struct type86_fmt2_ext fmt2;
538 struct CPRBX cprbx;
539 } __attribute__((packed)) *msg = reply->message;
540 char *data = reply->message;
542 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
543 return -EINVAL;
544 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
545 return msg->fmt2.count2;
548 static int convert_response_ica(struct zcrypt_device *zdev,
549 struct ap_message *reply,
550 char __user *outputdata,
551 unsigned int outputdatalength)
553 struct type86x_reply *msg = reply->message;
555 /* Response type byte is the second byte in the response. */
556 switch (((unsigned char *) reply->message)[1]) {
557 case TYPE82_RSP_CODE:
558 case TYPE88_RSP_CODE:
559 return convert_error(zdev, reply);
560 case TYPE86_RSP_CODE:
561 if (msg->hdr.reply_code)
562 return convert_error(zdev, reply);
563 if (msg->cprbx.cprb_ver_id == 0x02)
564 return convert_type86_ica(zdev, reply,
565 outputdata, outputdatalength);
566 /* Fall through, no break, incorrect cprb version is an unknown
567 * response */
568 default: /* Unknown response type, this should NEVER EVER happen */
569 zdev->online = 0;
570 return -EAGAIN; /* repeat the request on a different device. */
574 static int convert_response_xcrb(struct zcrypt_device *zdev,
575 struct ap_message *reply,
576 struct ica_xcRB *xcRB)
578 struct type86x_reply *msg = reply->message;
580 /* Response type byte is the second byte in the response. */
581 switch (((unsigned char *) reply->message)[1]) {
582 case TYPE82_RSP_CODE:
583 case TYPE88_RSP_CODE:
584 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
585 return convert_error(zdev, reply);
586 case TYPE86_RSP_CODE:
587 if (msg->hdr.reply_code) {
588 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
589 return convert_error(zdev, reply);
591 if (msg->cprbx.cprb_ver_id == 0x02)
592 return convert_type86_xcrb(zdev, reply, xcRB);
593 /* Fall through, no break, incorrect cprb version is an unknown
594 * response */
595 default: /* Unknown response type, this should NEVER EVER happen */
596 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
597 zdev->online = 0;
598 return -EAGAIN; /* repeat the request on a different device. */
602 static int convert_response_rng(struct zcrypt_device *zdev,
603 struct ap_message *reply,
604 char *data)
606 struct type86x_reply *msg = reply->message;
608 switch (msg->hdr.type) {
609 case TYPE82_RSP_CODE:
610 case TYPE88_RSP_CODE:
611 return -EINVAL;
612 case TYPE86_RSP_CODE:
613 if (msg->hdr.reply_code)
614 return -EINVAL;
615 if (msg->cprbx.cprb_ver_id == 0x02)
616 return convert_type86_rng(zdev, reply, data);
617 /* Fall through, no break, incorrect cprb version is an unknown
618 * response */
619 default: /* Unknown response type, this should NEVER EVER happen */
620 zdev->online = 0;
621 return -EAGAIN; /* repeat the request on a different device. */
626 * This function is called from the AP bus code after a crypto request
627 * "msg" has finished with the reply message "reply".
628 * It is called from tasklet context.
629 * @ap_dev: pointer to the AP device
630 * @msg: pointer to the AP message
631 * @reply: pointer to the AP reply message
633 static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
634 struct ap_message *msg,
635 struct ap_message *reply)
637 static struct error_hdr error_reply = {
638 .type = TYPE82_RSP_CODE,
639 .reply_code = REP82_ERROR_MACHINE_FAILURE,
641 struct response_type *resp_type =
642 (struct response_type *) msg->private;
643 struct type86x_reply *t86r;
644 int length;
646 /* Copy the reply message to the request message buffer. */
647 if (IS_ERR(reply)) {
648 memcpy(msg->message, &error_reply, sizeof(error_reply));
649 goto out;
651 t86r = reply->message;
652 if (t86r->hdr.type == TYPE86_RSP_CODE &&
653 t86r->cprbx.cprb_ver_id == 0x02) {
654 switch (resp_type->type) {
655 case PCIXCC_RESPONSE_TYPE_ICA:
656 length = sizeof(struct type86x_reply)
657 + t86r->length - 2;
658 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
659 memcpy(msg->message, reply->message, length);
660 break;
661 case PCIXCC_RESPONSE_TYPE_XCRB:
662 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
663 length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
664 memcpy(msg->message, reply->message, length);
665 break;
666 default:
667 memcpy(msg->message, &error_reply, sizeof error_reply);
669 } else
670 memcpy(msg->message, reply->message, sizeof error_reply);
671 out:
672 complete(&(resp_type->work));
675 static atomic_t zcrypt_step = ATOMIC_INIT(0);
678 * The request distributor calls this function if it picked the PCIXCC/CEX2C
679 * device to handle a modexpo request.
680 * @zdev: pointer to zcrypt_device structure that identifies the
681 * PCIXCC/CEX2C device to the request distributor
682 * @mex: pointer to the modexpo request buffer
684 static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
685 struct ica_rsa_modexpo *mex)
687 struct ap_message ap_msg;
688 struct response_type resp_type = {
689 .type = PCIXCC_RESPONSE_TYPE_ICA,
691 int rc;
693 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
694 if (!ap_msg.message)
695 return -ENOMEM;
696 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
697 atomic_inc_return(&zcrypt_step);
698 ap_msg.private = &resp_type;
699 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
700 if (rc)
701 goto out_free;
702 init_completion(&resp_type.work);
703 ap_queue_message(zdev->ap_dev, &ap_msg);
704 rc = wait_for_completion_interruptible(&resp_type.work);
705 if (rc == 0)
706 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
707 mex->outputdatalength);
708 else
709 /* Signal pending. */
710 ap_cancel_message(zdev->ap_dev, &ap_msg);
711 out_free:
712 free_page((unsigned long) ap_msg.message);
713 return rc;
717 * The request distributor calls this function if it picked the PCIXCC/CEX2C
718 * device to handle a modexpo_crt request.
719 * @zdev: pointer to zcrypt_device structure that identifies the
720 * PCIXCC/CEX2C device to the request distributor
721 * @crt: pointer to the modexpoc_crt request buffer
723 static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
724 struct ica_rsa_modexpo_crt *crt)
726 struct ap_message ap_msg;
727 struct response_type resp_type = {
728 .type = PCIXCC_RESPONSE_TYPE_ICA,
730 int rc;
732 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
733 if (!ap_msg.message)
734 return -ENOMEM;
735 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
736 atomic_inc_return(&zcrypt_step);
737 ap_msg.private = &resp_type;
738 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
739 if (rc)
740 goto out_free;
741 init_completion(&resp_type.work);
742 ap_queue_message(zdev->ap_dev, &ap_msg);
743 rc = wait_for_completion_interruptible(&resp_type.work);
744 if (rc == 0)
745 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
746 crt->outputdatalength);
747 else
748 /* Signal pending. */
749 ap_cancel_message(zdev->ap_dev, &ap_msg);
750 out_free:
751 free_page((unsigned long) ap_msg.message);
752 return rc;
756 * The request distributor calls this function if it picked the PCIXCC/CEX2C
757 * device to handle a send_cprb request.
758 * @zdev: pointer to zcrypt_device structure that identifies the
759 * PCIXCC/CEX2C device to the request distributor
760 * @xcRB: pointer to the send_cprb request buffer
762 static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
763 struct ica_xcRB *xcRB)
765 struct ap_message ap_msg;
766 struct response_type resp_type = {
767 .type = PCIXCC_RESPONSE_TYPE_XCRB,
769 int rc;
771 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
772 if (!ap_msg.message)
773 return -ENOMEM;
774 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
775 atomic_inc_return(&zcrypt_step);
776 ap_msg.private = &resp_type;
777 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
778 if (rc)
779 goto out_free;
780 init_completion(&resp_type.work);
781 ap_queue_message(zdev->ap_dev, &ap_msg);
782 rc = wait_for_completion_interruptible(&resp_type.work);
783 if (rc == 0)
784 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
785 else
786 /* Signal pending. */
787 ap_cancel_message(zdev->ap_dev, &ap_msg);
788 out_free:
789 kzfree(ap_msg.message);
790 return rc;
794 * The request distributor calls this function if it picked the PCIXCC/CEX2C
795 * device to generate random data.
796 * @zdev: pointer to zcrypt_device structure that identifies the
797 * PCIXCC/CEX2C device to the request distributor
798 * @buffer: pointer to a memory page to return random data
801 static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
802 char *buffer)
804 struct ap_message ap_msg;
805 struct response_type resp_type = {
806 .type = PCIXCC_RESPONSE_TYPE_XCRB,
808 int rc;
810 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
811 if (!ap_msg.message)
812 return -ENOMEM;
813 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
814 atomic_inc_return(&zcrypt_step);
815 ap_msg.private = &resp_type;
816 rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
817 init_completion(&resp_type.work);
818 ap_queue_message(zdev->ap_dev, &ap_msg);
819 rc = wait_for_completion_interruptible(&resp_type.work);
820 if (rc == 0)
821 rc = convert_response_rng(zdev, &ap_msg, buffer);
822 else
823 /* Signal pending. */
824 ap_cancel_message(zdev->ap_dev, &ap_msg);
825 kfree(ap_msg.message);
826 return rc;
830 * The crypto operations for a PCIXCC/CEX2C card.
832 static struct zcrypt_ops zcrypt_pcixcc_ops = {
833 .rsa_modexpo = zcrypt_pcixcc_modexpo,
834 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
835 .send_cprb = zcrypt_pcixcc_send_cprb,
838 static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
839 .rsa_modexpo = zcrypt_pcixcc_modexpo,
840 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
841 .send_cprb = zcrypt_pcixcc_send_cprb,
842 .rng = zcrypt_pcixcc_rng,
846 * Micro-code detection function. Its sends a message to a pcixcc card
847 * to find out the microcode level.
848 * @ap_dev: pointer to the AP device.
850 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
852 static unsigned char msg[] = {
853 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
854 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
855 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
856 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
857 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
858 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
859 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
860 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
861 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
862 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
863 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
864 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
865 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
866 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
867 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
868 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
869 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
870 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
871 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
872 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
873 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
874 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
875 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
876 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
877 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
878 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
879 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
880 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
881 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
882 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
883 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
884 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
885 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
886 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
887 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
888 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
889 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
890 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
891 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
892 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
893 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
894 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
895 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
896 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
897 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
898 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
899 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
900 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
901 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
902 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
903 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
904 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
905 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
906 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
907 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
908 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
909 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
910 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
911 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
912 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
913 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
914 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
915 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
916 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
917 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
918 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
919 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
920 0xF1,0x3D,0x93,0x53
922 unsigned long long psmid;
923 struct CPRBX *cprbx;
924 char *reply;
925 int rc, i;
927 reply = (void *) get_zeroed_page(GFP_KERNEL);
928 if (!reply)
929 return -ENOMEM;
931 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
932 if (rc)
933 goto out_free;
935 /* Wait for the test message to complete. */
936 for (i = 0; i < 6; i++) {
937 mdelay(300);
938 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
939 if (rc == 0 && psmid == 0x0102030405060708ULL)
940 break;
943 if (i >= 6) {
944 /* Got no answer. */
945 rc = -ENODEV;
946 goto out_free;
949 cprbx = (struct CPRBX *) (reply + 48);
950 if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
951 rc = ZCRYPT_PCIXCC_MCL2;
952 else
953 rc = ZCRYPT_PCIXCC_MCL3;
954 out_free:
955 free_page((unsigned long) reply);
956 return rc;
960 * Large random number detection function. Its sends a message to a pcixcc
961 * card to find out if large random numbers are supported.
962 * @ap_dev: pointer to the AP device.
964 * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
966 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
968 struct ap_message ap_msg;
969 unsigned long long psmid;
970 struct {
971 struct type86_hdr hdr;
972 struct type86_fmt2_ext fmt2;
973 struct CPRBX cprbx;
974 } __attribute__((packed)) *reply;
975 int rc, i;
977 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
978 if (!ap_msg.message)
979 return -ENOMEM;
981 rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
982 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
983 ap_msg.length);
984 if (rc)
985 goto out_free;
987 /* Wait for the test message to complete. */
988 for (i = 0; i < 2 * HZ; i++) {
989 msleep(1000 / HZ);
990 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
991 if (rc == 0 && psmid == 0x0102030405060708ULL)
992 break;
995 if (i >= 2 * HZ) {
996 /* Got no answer. */
997 rc = -ENODEV;
998 goto out_free;
1001 reply = ap_msg.message;
1002 if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1003 rc = 1;
1004 else
1005 rc = 0;
1006 out_free:
1007 free_page((unsigned long) ap_msg.message);
1008 return rc;
1012 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
1013 * since the bus_match already checked the hardware type. The PCIXCC
1014 * cards come in two flavours: micro code level 2 and micro code level 3.
1015 * This is checked by sending a test message to the device.
1016 * @ap_dev: pointer to the AP device.
1018 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1020 struct zcrypt_device *zdev;
1021 int rc;
1023 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
1024 if (!zdev)
1025 return -ENOMEM;
1026 zdev->ap_dev = ap_dev;
1027 zdev->online = 1;
1028 if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) {
1029 rc = zcrypt_pcixcc_mcl(ap_dev);
1030 if (rc < 0) {
1031 zcrypt_device_free(zdev);
1032 return rc;
1034 zdev->user_space_type = rc;
1035 if (rc == ZCRYPT_PCIXCC_MCL2) {
1036 zdev->type_string = "PCIXCC_MCL2";
1037 zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
1038 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
1039 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1040 } else {
1041 zdev->type_string = "PCIXCC_MCL3";
1042 zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
1043 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1044 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1046 } else {
1047 zdev->user_space_type = ZCRYPT_CEX2C;
1048 zdev->type_string = "CEX2C";
1049 zdev->speed_rating = CEX2C_SPEED_RATING;
1050 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1051 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1053 rc = zcrypt_pcixcc_rng_supported(ap_dev);
1054 if (rc < 0) {
1055 zcrypt_device_free(zdev);
1056 return rc;
1058 if (rc)
1059 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1060 else
1061 zdev->ops = &zcrypt_pcixcc_ops;
1062 ap_dev->reply = &zdev->reply;
1063 ap_dev->private = zdev;
1064 rc = zcrypt_device_register(zdev);
1065 if (rc)
1066 goto out_free;
1067 return 0;
1069 out_free:
1070 ap_dev->private = NULL;
1071 zcrypt_device_free(zdev);
1072 return rc;
1076 * This is called to remove the extended PCIXCC/CEX2C driver information
1077 * if an AP device is removed.
1079 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
1081 struct zcrypt_device *zdev = ap_dev->private;
1083 zcrypt_device_unregister(zdev);
1086 int __init zcrypt_pcixcc_init(void)
1088 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
1091 void zcrypt_pcixcc_exit(void)
1093 ap_driver_unregister(&zcrypt_pcixcc_driver);
1096 #ifndef CONFIG_ZCRYPT_MONOLITHIC
1097 module_init(zcrypt_pcixcc_init);
1098 module_exit(zcrypt_pcixcc_exit);
1099 #endif