mm/vmstat.c: remove debug fs entries on failure of file creation and made extfrag_deb...
[linux-2.6/libata-dev.git] / drivers / s390 / crypto / zcrypt_pcixcc.c
blobf7cc43401816d503e33ec3fb75b628c60b9ad400
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 <linux/slab.h>
34 #include <linux/atomic.h>
35 #include <asm/uaccess.h>
37 #include "ap_bus.h"
38 #include "zcrypt_api.h"
39 #include "zcrypt_error.h"
40 #include "zcrypt_pcicc.h"
41 #include "zcrypt_pcixcc.h"
42 #include "zcrypt_cca_key.h"
44 #define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
45 #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
46 #define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */
47 #define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE
48 #define CEX3C_MAX_MOD_SIZE 512 /* 4096 bits */
50 #define PCIXCC_MCL2_SPEED_RATING 7870
51 #define PCIXCC_MCL3_SPEED_RATING 7870
52 #define CEX2C_SPEED_RATING 7000
53 #define CEX3C_SPEED_RATING 6500
55 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */
56 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
58 #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
60 #define PCIXCC_CLEANUP_TIME (15*HZ)
62 #define CEIL4(x) ((((x)+3)/4)*4)
64 struct response_type {
65 struct completion work;
66 int type;
68 #define PCIXCC_RESPONSE_TYPE_ICA 0
69 #define PCIXCC_RESPONSE_TYPE_XCRB 1
71 static struct ap_device_id zcrypt_pcixcc_ids[] = {
72 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) },
73 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) },
74 { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) },
75 { /* end of list */ },
78 MODULE_DEVICE_TABLE(ap, zcrypt_pcixcc_ids);
79 MODULE_AUTHOR("IBM Corporation");
80 MODULE_DESCRIPTION("PCIXCC Cryptographic Coprocessor device driver, "
81 "Copyright 2001, 2006 IBM Corporation");
82 MODULE_LICENSE("GPL");
84 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev);
85 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev);
86 static void zcrypt_pcixcc_receive(struct ap_device *, struct ap_message *,
87 struct ap_message *);
89 static struct ap_driver zcrypt_pcixcc_driver = {
90 .probe = zcrypt_pcixcc_probe,
91 .remove = zcrypt_pcixcc_remove,
92 .ids = zcrypt_pcixcc_ids,
93 .request_timeout = PCIXCC_CLEANUP_TIME,
96 /**
97 * The following is used to initialize the CPRBX passed to the PCIXCC/CEX2C
98 * card in a type6 message. The 3 fields that must be filled in at execution
99 * time are req_parml, rpl_parml and usage_domain.
100 * Everything about this interface is ascii/big-endian, since the
101 * device does *not* have 'Intel inside'.
103 * The CPRBX is followed immediately by the parm block.
104 * The parm block contains:
105 * - function code ('PD' 0x5044 or 'PK' 0x504B)
106 * - rule block (one of:)
107 * + 0x000A 'PKCS-1.2' (MCL2 'PD')
108 * + 0x000A 'ZERO-PAD' (MCL2 'PK')
109 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD')
110 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK')
111 * - VUD block
113 static struct CPRBX static_cprbx = {
114 .cprb_len = 0x00DC,
115 .cprb_ver_id = 0x02,
116 .func_id = {0x54,0x32},
120 * Convert a ICAMEX message to a type6 MEX message.
122 * @zdev: crypto device pointer
123 * @ap_msg: pointer to AP message
124 * @mex: pointer to user input data
126 * Returns 0 on success or -EFAULT.
128 static int ICAMEX_msg_to_type6MEX_msgX(struct zcrypt_device *zdev,
129 struct ap_message *ap_msg,
130 struct ica_rsa_modexpo *mex)
132 static struct type6_hdr static_type6_hdrX = {
133 .type = 0x06,
134 .offset1 = 0x00000058,
135 .agent_id = {'C','A',},
136 .function_code = {'P','K'},
138 static struct function_and_rules_block static_pke_fnr = {
139 .function_code = {'P','K'},
140 .ulen = 10,
141 .only_rule = {'M','R','P',' ',' ',' ',' ',' '}
143 static struct function_and_rules_block static_pke_fnr_MCL2 = {
144 .function_code = {'P','K'},
145 .ulen = 10,
146 .only_rule = {'Z','E','R','O','-','P','A','D'}
148 struct {
149 struct type6_hdr hdr;
150 struct CPRBX cprbx;
151 struct function_and_rules_block fr;
152 unsigned short length;
153 char text[0];
154 } __attribute__((packed)) *msg = ap_msg->message;
155 int size;
157 /* VUD.ciphertext */
158 msg->length = mex->inputdatalength + 2;
159 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
160 return -EFAULT;
162 /* Set up key which is located after the variable length text. */
163 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->inputdatalength, 1);
164 if (size < 0)
165 return size;
166 size += sizeof(*msg) + mex->inputdatalength;
168 /* message header, cprbx and f&r */
169 msg->hdr = static_type6_hdrX;
170 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
171 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
173 msg->cprbx = static_cprbx;
174 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
175 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
177 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
178 static_pke_fnr_MCL2 : static_pke_fnr;
180 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
182 ap_msg->length = size;
183 return 0;
187 * Convert a ICACRT message to a type6 CRT message.
189 * @zdev: crypto device pointer
190 * @ap_msg: pointer to AP message
191 * @crt: pointer to user input data
193 * Returns 0 on success or -EFAULT.
195 static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
196 struct ap_message *ap_msg,
197 struct ica_rsa_modexpo_crt *crt)
199 static struct type6_hdr static_type6_hdrX = {
200 .type = 0x06,
201 .offset1 = 0x00000058,
202 .agent_id = {'C','A',},
203 .function_code = {'P','D'},
205 static struct function_and_rules_block static_pkd_fnr = {
206 .function_code = {'P','D'},
207 .ulen = 10,
208 .only_rule = {'Z','E','R','O','-','P','A','D'}
211 static struct function_and_rules_block static_pkd_fnr_MCL2 = {
212 .function_code = {'P','D'},
213 .ulen = 10,
214 .only_rule = {'P','K','C','S','-','1','.','2'}
216 struct {
217 struct type6_hdr hdr;
218 struct CPRBX cprbx;
219 struct function_and_rules_block fr;
220 unsigned short length;
221 char text[0];
222 } __attribute__((packed)) *msg = ap_msg->message;
223 int size;
225 /* VUD.ciphertext */
226 msg->length = crt->inputdatalength + 2;
227 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
228 return -EFAULT;
230 /* Set up key which is located after the variable length text. */
231 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength, 1);
232 if (size < 0)
233 return size;
234 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */
236 /* message header, cprbx and f&r */
237 msg->hdr = static_type6_hdrX;
238 msg->hdr.ToCardLen1 = size - sizeof(msg->hdr);
239 msg->hdr.FromCardLen1 = PCIXCC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
241 msg->cprbx = static_cprbx;
242 msg->cprbx.domain = AP_QID_QUEUE(zdev->ap_dev->qid);
243 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
244 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
246 msg->fr = (zdev->user_space_type == ZCRYPT_PCIXCC_MCL2) ?
247 static_pkd_fnr_MCL2 : static_pkd_fnr;
249 ap_msg->length = size;
250 return 0;
254 * Convert a XCRB message to a type6 CPRB message.
256 * @zdev: crypto device pointer
257 * @ap_msg: pointer to AP message
258 * @xcRB: pointer to user input data
260 * Returns 0 on success or -EFAULT, -EINVAL.
262 struct type86_fmt2_msg {
263 struct type86_hdr hdr;
264 struct type86_fmt2_ext fmt2;
265 } __attribute__((packed));
267 static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
268 struct ap_message *ap_msg,
269 struct ica_xcRB *xcRB)
271 static struct type6_hdr static_type6_hdrX = {
272 .type = 0x06,
273 .offset1 = 0x00000058,
275 struct {
276 struct type6_hdr hdr;
277 struct CPRBX cprbx;
278 } __attribute__((packed)) *msg = ap_msg->message;
280 int rcblen = CEIL4(xcRB->request_control_blk_length);
281 int replylen;
282 char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen;
283 char *function_code;
285 /* length checks */
286 ap_msg->length = sizeof(struct type6_hdr) +
287 CEIL4(xcRB->request_control_blk_length) +
288 xcRB->request_data_length;
289 if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
290 return -EINVAL;
291 replylen = sizeof(struct type86_fmt2_msg) +
292 CEIL4(xcRB->reply_control_blk_length) +
293 xcRB->reply_data_length;
294 if (replylen > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
295 return -EINVAL;
297 /* prepare type6 header */
298 msg->hdr = static_type6_hdrX;
299 memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID));
300 msg->hdr.ToCardLen1 = xcRB->request_control_blk_length;
301 if (xcRB->request_data_length) {
302 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
303 msg->hdr.ToCardLen2 = xcRB->request_data_length;
305 msg->hdr.FromCardLen1 = xcRB->reply_control_blk_length;
306 msg->hdr.FromCardLen2 = xcRB->reply_data_length;
308 /* prepare CPRB */
309 if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr,
310 xcRB->request_control_blk_length))
311 return -EFAULT;
312 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
313 xcRB->request_control_blk_length)
314 return -EINVAL;
315 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
316 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
318 if (memcmp(function_code, "US", 2) == 0)
319 ap_msg->special = 1;
320 else
321 ap_msg->special = 0;
323 /* copy data block */
324 if (xcRB->request_data_length &&
325 copy_from_user(req_data, xcRB->request_data_address,
326 xcRB->request_data_length))
327 return -EFAULT;
328 return 0;
332 * Prepare a type6 CPRB message for random number generation
334 * @ap_dev: AP device pointer
335 * @ap_msg: pointer to AP message
337 static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
338 struct ap_message *ap_msg,
339 unsigned random_number_length)
341 struct {
342 struct type6_hdr hdr;
343 struct CPRBX cprbx;
344 char function_code[2];
345 short int rule_length;
346 char rule[8];
347 short int verb_length;
348 short int key_length;
349 } __attribute__((packed)) *msg = ap_msg->message;
350 static struct type6_hdr static_type6_hdrX = {
351 .type = 0x06,
352 .offset1 = 0x00000058,
353 .agent_id = {'C', 'A'},
354 .function_code = {'R', 'L'},
355 .ToCardLen1 = sizeof *msg - sizeof(msg->hdr),
356 .FromCardLen1 = sizeof *msg - sizeof(msg->hdr),
358 static struct CPRBX local_cprbx = {
359 .cprb_len = 0x00dc,
360 .cprb_ver_id = 0x02,
361 .func_id = {0x54, 0x32},
362 .req_parml = sizeof *msg - sizeof(msg->hdr) -
363 sizeof(msg->cprbx),
364 .rpl_msgbl = sizeof *msg - sizeof(msg->hdr),
367 msg->hdr = static_type6_hdrX;
368 msg->hdr.FromCardLen2 = random_number_length,
369 msg->cprbx = local_cprbx;
370 msg->cprbx.rpl_datal = random_number_length,
371 msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
372 memcpy(msg->function_code, msg->hdr.function_code, 0x02);
373 msg->rule_length = 0x0a;
374 memcpy(msg->rule, "RANDOM ", 8);
375 msg->verb_length = 0x02;
376 msg->key_length = 0x02;
377 ap_msg->length = sizeof *msg;
381 * Copy results from a type 86 ICA reply message back to user space.
383 * @zdev: crypto device pointer
384 * @reply: reply AP message.
385 * @data: pointer to user output data
386 * @length: size of user output data
388 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
390 struct type86x_reply {
391 struct type86_hdr hdr;
392 struct type86_fmt2_ext fmt2;
393 struct CPRBX cprbx;
394 unsigned char pad[4]; /* 4 byte function code/rules block ? */
395 unsigned short length;
396 char text[0];
397 } __attribute__((packed));
399 static int convert_type86_ica(struct zcrypt_device *zdev,
400 struct ap_message *reply,
401 char __user *outputdata,
402 unsigned int outputdatalength)
404 static unsigned char static_pad[] = {
405 0x00,0x02,
406 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
407 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
408 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
409 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
410 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
411 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
412 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
413 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
414 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
415 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
416 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
417 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
418 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
419 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
420 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
421 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
422 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
423 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
424 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
425 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
426 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
427 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
428 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
429 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
430 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
431 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
432 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
433 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
434 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
435 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
436 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
437 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
439 struct type86x_reply *msg = reply->message;
440 unsigned short service_rc, service_rs;
441 unsigned int reply_len, pad_len;
442 char *data;
444 service_rc = msg->cprbx.ccp_rtcode;
445 if (unlikely(service_rc != 0)) {
446 service_rs = msg->cprbx.ccp_rscode;
447 if (service_rc == 8 && service_rs == 66)
448 return -EINVAL;
449 if (service_rc == 8 && service_rs == 65)
450 return -EINVAL;
451 if (service_rc == 8 && service_rs == 770)
452 return -EINVAL;
453 if (service_rc == 8 && service_rs == 783) {
454 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
455 return -EAGAIN;
457 if (service_rc == 12 && service_rs == 769)
458 return -EINVAL;
459 if (service_rc == 8 && service_rs == 72)
460 return -EINVAL;
461 zdev->online = 0;
462 return -EAGAIN; /* repeat the request on a different device. */
464 data = msg->text;
465 reply_len = msg->length - 2;
466 if (reply_len > outputdatalength)
467 return -EINVAL;
469 * For all encipher requests, the length of the ciphertext (reply_len)
470 * will always equal the modulus length. For MEX decipher requests
471 * the output needs to get padded. Minimum pad size is 10.
473 * Currently, the cases where padding will be added is for:
474 * - PCIXCC_MCL2 using a CRT form token (since PKD didn't support
475 * ZERO-PAD and CRT is only supported for PKD requests)
476 * - PCICC, always
478 pad_len = outputdatalength - reply_len;
479 if (pad_len > 0) {
480 if (pad_len < 10)
481 return -EINVAL;
482 /* 'restore' padding left in the PCICC/PCIXCC card. */
483 if (copy_to_user(outputdata, static_pad, pad_len - 1))
484 return -EFAULT;
485 if (put_user(0, outputdata + pad_len - 1))
486 return -EFAULT;
488 /* Copy the crypto response to user space. */
489 if (copy_to_user(outputdata + pad_len, data, reply_len))
490 return -EFAULT;
491 return 0;
495 * Copy results from a type 86 XCRB reply message back to user space.
497 * @zdev: crypto device pointer
498 * @reply: reply AP message.
499 * @xcRB: pointer to XCRB
501 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error.
503 static int convert_type86_xcrb(struct zcrypt_device *zdev,
504 struct ap_message *reply,
505 struct ica_xcRB *xcRB)
507 struct type86_fmt2_msg *msg = reply->message;
508 char *data = reply->message;
510 /* Copy CPRB to user */
511 if (copy_to_user(xcRB->reply_control_blk_addr,
512 data + msg->fmt2.offset1, msg->fmt2.count1))
513 return -EFAULT;
514 xcRB->reply_control_blk_length = msg->fmt2.count1;
516 /* Copy data buffer to user */
517 if (msg->fmt2.count2)
518 if (copy_to_user(xcRB->reply_data_addr,
519 data + msg->fmt2.offset2, msg->fmt2.count2))
520 return -EFAULT;
521 xcRB->reply_data_length = msg->fmt2.count2;
522 return 0;
525 static int convert_type86_rng(struct zcrypt_device *zdev,
526 struct ap_message *reply,
527 char *buffer)
529 struct {
530 struct type86_hdr hdr;
531 struct type86_fmt2_ext fmt2;
532 struct CPRBX cprbx;
533 } __attribute__((packed)) *msg = reply->message;
534 char *data = reply->message;
536 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
537 return -EINVAL;
538 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
539 return msg->fmt2.count2;
542 static int convert_response_ica(struct zcrypt_device *zdev,
543 struct ap_message *reply,
544 char __user *outputdata,
545 unsigned int outputdatalength)
547 struct type86x_reply *msg = reply->message;
549 /* Response type byte is the second byte in the response. */
550 switch (((unsigned char *) reply->message)[1]) {
551 case TYPE82_RSP_CODE:
552 case TYPE88_RSP_CODE:
553 return convert_error(zdev, reply);
554 case TYPE86_RSP_CODE:
555 if (msg->cprbx.ccp_rtcode &&
556 (msg->cprbx.ccp_rscode == 0x14f) &&
557 (outputdatalength > 256)) {
558 if (zdev->max_exp_bit_length <= 17) {
559 zdev->max_exp_bit_length = 17;
560 return -EAGAIN;
561 } else
562 return -EINVAL;
564 if (msg->hdr.reply_code)
565 return convert_error(zdev, reply);
566 if (msg->cprbx.cprb_ver_id == 0x02)
567 return convert_type86_ica(zdev, reply,
568 outputdata, outputdatalength);
569 /* Fall through, no break, incorrect cprb version is an unknown
570 * response */
571 default: /* Unknown response type, this should NEVER EVER happen */
572 zdev->online = 0;
573 return -EAGAIN; /* repeat the request on a different device. */
577 static int convert_response_xcrb(struct zcrypt_device *zdev,
578 struct ap_message *reply,
579 struct ica_xcRB *xcRB)
581 struct type86x_reply *msg = reply->message;
583 /* Response type byte is the second byte in the response. */
584 switch (((unsigned char *) reply->message)[1]) {
585 case TYPE82_RSP_CODE:
586 case TYPE88_RSP_CODE:
587 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
588 return convert_error(zdev, reply);
589 case TYPE86_RSP_CODE:
590 if (msg->hdr.reply_code) {
591 memcpy(&(xcRB->status), msg->fmt2.apfs, sizeof(u32));
592 return convert_error(zdev, reply);
594 if (msg->cprbx.cprb_ver_id == 0x02)
595 return convert_type86_xcrb(zdev, reply, xcRB);
596 /* Fall through, no break, incorrect cprb version is an unknown
597 * response */
598 default: /* Unknown response type, this should NEVER EVER happen */
599 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
600 zdev->online = 0;
601 return -EAGAIN; /* repeat the request on a different device. */
605 static int convert_response_rng(struct zcrypt_device *zdev,
606 struct ap_message *reply,
607 char *data)
609 struct type86x_reply *msg = reply->message;
611 switch (msg->hdr.type) {
612 case TYPE82_RSP_CODE:
613 case TYPE88_RSP_CODE:
614 return -EINVAL;
615 case TYPE86_RSP_CODE:
616 if (msg->hdr.reply_code)
617 return -EINVAL;
618 if (msg->cprbx.cprb_ver_id == 0x02)
619 return convert_type86_rng(zdev, reply, data);
620 /* Fall through, no break, incorrect cprb version is an unknown
621 * response */
622 default: /* Unknown response type, this should NEVER EVER happen */
623 zdev->online = 0;
624 return -EAGAIN; /* repeat the request on a different device. */
629 * This function is called from the AP bus code after a crypto request
630 * "msg" has finished with the reply message "reply".
631 * It is called from tasklet context.
632 * @ap_dev: pointer to the AP device
633 * @msg: pointer to the AP message
634 * @reply: pointer to the AP reply message
636 static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
637 struct ap_message *msg,
638 struct ap_message *reply)
640 static struct error_hdr error_reply = {
641 .type = TYPE82_RSP_CODE,
642 .reply_code = REP82_ERROR_MACHINE_FAILURE,
644 struct response_type *resp_type =
645 (struct response_type *) msg->private;
646 struct type86x_reply *t86r;
647 int length;
649 /* Copy the reply message to the request message buffer. */
650 if (IS_ERR(reply)) {
651 memcpy(msg->message, &error_reply, sizeof(error_reply));
652 goto out;
654 t86r = reply->message;
655 if (t86r->hdr.type == TYPE86_RSP_CODE &&
656 t86r->cprbx.cprb_ver_id == 0x02) {
657 switch (resp_type->type) {
658 case PCIXCC_RESPONSE_TYPE_ICA:
659 length = sizeof(struct type86x_reply)
660 + t86r->length - 2;
661 length = min(PCIXCC_MAX_ICA_RESPONSE_SIZE, length);
662 memcpy(msg->message, reply->message, length);
663 break;
664 case PCIXCC_RESPONSE_TYPE_XCRB:
665 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
666 length = min(PCIXCC_MAX_XCRB_MESSAGE_SIZE, length);
667 memcpy(msg->message, reply->message, length);
668 break;
669 default:
670 memcpy(msg->message, &error_reply, sizeof error_reply);
672 } else
673 memcpy(msg->message, reply->message, sizeof error_reply);
674 out:
675 complete(&(resp_type->work));
678 static atomic_t zcrypt_step = ATOMIC_INIT(0);
681 * The request distributor calls this function if it picked the PCIXCC/CEX2C
682 * device to handle a modexpo request.
683 * @zdev: pointer to zcrypt_device structure that identifies the
684 * PCIXCC/CEX2C device to the request distributor
685 * @mex: pointer to the modexpo request buffer
687 static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev,
688 struct ica_rsa_modexpo *mex)
690 struct ap_message ap_msg;
691 struct response_type resp_type = {
692 .type = PCIXCC_RESPONSE_TYPE_ICA,
694 int rc;
696 ap_init_message(&ap_msg);
697 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
698 if (!ap_msg.message)
699 return -ENOMEM;
700 ap_msg.receive = zcrypt_pcixcc_receive;
701 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
702 atomic_inc_return(&zcrypt_step);
703 ap_msg.private = &resp_type;
704 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
705 if (rc)
706 goto out_free;
707 init_completion(&resp_type.work);
708 ap_queue_message(zdev->ap_dev, &ap_msg);
709 rc = wait_for_completion_interruptible(&resp_type.work);
710 if (rc == 0)
711 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
712 mex->outputdatalength);
713 else
714 /* Signal pending. */
715 ap_cancel_message(zdev->ap_dev, &ap_msg);
716 out_free:
717 free_page((unsigned long) ap_msg.message);
718 return rc;
722 * The request distributor calls this function if it picked the PCIXCC/CEX2C
723 * device to handle a modexpo_crt request.
724 * @zdev: pointer to zcrypt_device structure that identifies the
725 * PCIXCC/CEX2C device to the request distributor
726 * @crt: pointer to the modexpoc_crt request buffer
728 static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev,
729 struct ica_rsa_modexpo_crt *crt)
731 struct ap_message ap_msg;
732 struct response_type resp_type = {
733 .type = PCIXCC_RESPONSE_TYPE_ICA,
735 int rc;
737 ap_init_message(&ap_msg);
738 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
739 if (!ap_msg.message)
740 return -ENOMEM;
741 ap_msg.receive = zcrypt_pcixcc_receive;
742 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
743 atomic_inc_return(&zcrypt_step);
744 ap_msg.private = &resp_type;
745 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
746 if (rc)
747 goto out_free;
748 init_completion(&resp_type.work);
749 ap_queue_message(zdev->ap_dev, &ap_msg);
750 rc = wait_for_completion_interruptible(&resp_type.work);
751 if (rc == 0)
752 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
753 crt->outputdatalength);
754 else
755 /* Signal pending. */
756 ap_cancel_message(zdev->ap_dev, &ap_msg);
757 out_free:
758 free_page((unsigned long) ap_msg.message);
759 return rc;
763 * The request distributor calls this function if it picked the PCIXCC/CEX2C
764 * device to handle a send_cprb request.
765 * @zdev: pointer to zcrypt_device structure that identifies the
766 * PCIXCC/CEX2C device to the request distributor
767 * @xcRB: pointer to the send_cprb request buffer
769 static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
770 struct ica_xcRB *xcRB)
772 struct ap_message ap_msg;
773 struct response_type resp_type = {
774 .type = PCIXCC_RESPONSE_TYPE_XCRB,
776 int rc;
778 ap_init_message(&ap_msg);
779 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
780 if (!ap_msg.message)
781 return -ENOMEM;
782 ap_msg.receive = zcrypt_pcixcc_receive;
783 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
784 atomic_inc_return(&zcrypt_step);
785 ap_msg.private = &resp_type;
786 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
787 if (rc)
788 goto out_free;
789 init_completion(&resp_type.work);
790 ap_queue_message(zdev->ap_dev, &ap_msg);
791 rc = wait_for_completion_interruptible(&resp_type.work);
792 if (rc == 0)
793 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
794 else
795 /* Signal pending. */
796 ap_cancel_message(zdev->ap_dev, &ap_msg);
797 out_free:
798 kzfree(ap_msg.message);
799 return rc;
803 * The request distributor calls this function if it picked the PCIXCC/CEX2C
804 * device to generate random data.
805 * @zdev: pointer to zcrypt_device structure that identifies the
806 * PCIXCC/CEX2C device to the request distributor
807 * @buffer: pointer to a memory page to return random data
810 static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev,
811 char *buffer)
813 struct ap_message ap_msg;
814 struct response_type resp_type = {
815 .type = PCIXCC_RESPONSE_TYPE_XCRB,
817 int rc;
819 ap_init_message(&ap_msg);
820 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL);
821 if (!ap_msg.message)
822 return -ENOMEM;
823 ap_msg.receive = zcrypt_pcixcc_receive;
824 ap_msg.psmid = (((unsigned long long) current->pid) << 32) +
825 atomic_inc_return(&zcrypt_step);
826 ap_msg.private = &resp_type;
827 rng_type6CPRB_msgX(zdev->ap_dev, &ap_msg, ZCRYPT_RNG_BUFFER_SIZE);
828 init_completion(&resp_type.work);
829 ap_queue_message(zdev->ap_dev, &ap_msg);
830 rc = wait_for_completion_interruptible(&resp_type.work);
831 if (rc == 0)
832 rc = convert_response_rng(zdev, &ap_msg, buffer);
833 else
834 /* Signal pending. */
835 ap_cancel_message(zdev->ap_dev, &ap_msg);
836 kfree(ap_msg.message);
837 return rc;
841 * The crypto operations for a PCIXCC/CEX2C card.
843 static struct zcrypt_ops zcrypt_pcixcc_ops = {
844 .rsa_modexpo = zcrypt_pcixcc_modexpo,
845 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
846 .send_cprb = zcrypt_pcixcc_send_cprb,
849 static struct zcrypt_ops zcrypt_pcixcc_with_rng_ops = {
850 .rsa_modexpo = zcrypt_pcixcc_modexpo,
851 .rsa_modexpo_crt = zcrypt_pcixcc_modexpo_crt,
852 .send_cprb = zcrypt_pcixcc_send_cprb,
853 .rng = zcrypt_pcixcc_rng,
857 * Micro-code detection function. Its sends a message to a pcixcc card
858 * to find out the microcode level.
859 * @ap_dev: pointer to the AP device.
861 static int zcrypt_pcixcc_mcl(struct ap_device *ap_dev)
863 static unsigned char msg[] = {
864 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
865 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
866 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
867 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
868 0x43,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
869 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
870 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x00,
871 0x00,0x00,0x01,0xC4,0x00,0x00,0x00,0x00,
872 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
873 0x00,0x00,0x07,0x24,0x00,0x00,0x00,0x00,
874 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
875 0x00,0xDC,0x02,0x00,0x00,0x00,0x54,0x32,
876 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE8,
877 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x24,
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,0x00,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,0x00,0x00,0x00,0x00,
892 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
893 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
894 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
895 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
896 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
897 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
898 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
899 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
900 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
901 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
902 0x00,0x00,0x00,0x00,0x50,0x4B,0x00,0x0A,
903 0x4D,0x52,0x50,0x20,0x20,0x20,0x20,0x20,
904 0x00,0x42,0x00,0x01,0x02,0x03,0x04,0x05,
905 0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
906 0x0E,0x0F,0x00,0x11,0x22,0x33,0x44,0x55,
907 0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,
908 0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,
909 0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,
910 0x11,0x00,0x01,0x23,0x45,0x67,0x89,0xAB,
911 0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,
912 0x32,0x10,0x00,0x9A,0x00,0x98,0x00,0x00,
913 0x1E,0x00,0x00,0x94,0x00,0x00,0x00,0x00,
914 0x04,0x00,0x00,0x8C,0x00,0x00,0x00,0x40,
915 0x02,0x00,0x00,0x40,0xBA,0xE8,0x23,0x3C,
916 0x75,0xF3,0x91,0x61,0xD6,0x73,0x39,0xCF,
917 0x7B,0x6D,0x8E,0x61,0x97,0x63,0x9E,0xD9,
918 0x60,0x55,0xD6,0xC7,0xEF,0xF8,0x1E,0x63,
919 0x95,0x17,0xCC,0x28,0x45,0x60,0x11,0xC5,
920 0xC4,0x4E,0x66,0xC6,0xE6,0xC3,0xDE,0x8A,
921 0x19,0x30,0xCF,0x0E,0xD7,0xAA,0xDB,0x01,
922 0xD8,0x00,0xBB,0x8F,0x39,0x9F,0x64,0x28,
923 0xF5,0x7A,0x77,0x49,0xCC,0x6B,0xA3,0x91,
924 0x97,0x70,0xE7,0x60,0x1E,0x39,0xE1,0xE5,
925 0x33,0xE1,0x15,0x63,0x69,0x08,0x80,0x4C,
926 0x67,0xC4,0x41,0x8F,0x48,0xDF,0x26,0x98,
927 0xF1,0xD5,0x8D,0x88,0xD9,0x6A,0xA4,0x96,
928 0xC5,0x84,0xD9,0x30,0x49,0x67,0x7D,0x19,
929 0xB1,0xB3,0x45,0x4D,0xB2,0x53,0x9A,0x47,
930 0x3C,0x7C,0x55,0xBF,0xCC,0x85,0x00,0x36,
931 0xF1,0x3D,0x93,0x53
933 unsigned long long psmid;
934 struct CPRBX *cprbx;
935 char *reply;
936 int rc, i;
938 reply = (void *) get_zeroed_page(GFP_KERNEL);
939 if (!reply)
940 return -ENOMEM;
942 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, msg, sizeof(msg));
943 if (rc)
944 goto out_free;
946 /* Wait for the test message to complete. */
947 for (i = 0; i < 6; i++) {
948 mdelay(300);
949 rc = ap_recv(ap_dev->qid, &psmid, reply, 4096);
950 if (rc == 0 && psmid == 0x0102030405060708ULL)
951 break;
954 if (i >= 6) {
955 /* Got no answer. */
956 rc = -ENODEV;
957 goto out_free;
960 cprbx = (struct CPRBX *) (reply + 48);
961 if (cprbx->ccp_rtcode == 8 && cprbx->ccp_rscode == 33)
962 rc = ZCRYPT_PCIXCC_MCL2;
963 else
964 rc = ZCRYPT_PCIXCC_MCL3;
965 out_free:
966 free_page((unsigned long) reply);
967 return rc;
971 * Large random number detection function. Its sends a message to a pcixcc
972 * card to find out if large random numbers are supported.
973 * @ap_dev: pointer to the AP device.
975 * Returns 1 if large random numbers are supported, 0 if not and < 0 on error.
977 static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev)
979 struct ap_message ap_msg;
980 unsigned long long psmid;
981 struct {
982 struct type86_hdr hdr;
983 struct type86_fmt2_ext fmt2;
984 struct CPRBX cprbx;
985 } __attribute__((packed)) *reply;
986 int rc, i;
988 ap_init_message(&ap_msg);
989 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL);
990 if (!ap_msg.message)
991 return -ENOMEM;
993 rng_type6CPRB_msgX(ap_dev, &ap_msg, 4);
994 rc = ap_send(ap_dev->qid, 0x0102030405060708ULL, ap_msg.message,
995 ap_msg.length);
996 if (rc)
997 goto out_free;
999 /* Wait for the test message to complete. */
1000 for (i = 0; i < 2 * HZ; i++) {
1001 msleep(1000 / HZ);
1002 rc = ap_recv(ap_dev->qid, &psmid, ap_msg.message, 4096);
1003 if (rc == 0 && psmid == 0x0102030405060708ULL)
1004 break;
1007 if (i >= 2 * HZ) {
1008 /* Got no answer. */
1009 rc = -ENODEV;
1010 goto out_free;
1013 reply = ap_msg.message;
1014 if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0)
1015 rc = 1;
1016 else
1017 rc = 0;
1018 out_free:
1019 free_page((unsigned long) ap_msg.message);
1020 return rc;
1024 * Probe function for PCIXCC/CEX2C cards. It always accepts the AP device
1025 * since the bus_match already checked the hardware type. The PCIXCC
1026 * cards come in two flavours: micro code level 2 and micro code level 3.
1027 * This is checked by sending a test message to the device.
1028 * @ap_dev: pointer to the AP device.
1030 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
1032 struct zcrypt_device *zdev;
1033 int rc = 0;
1035 zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE);
1036 if (!zdev)
1037 return -ENOMEM;
1038 zdev->ap_dev = ap_dev;
1039 zdev->online = 1;
1040 switch (ap_dev->device_type) {
1041 case AP_DEVICE_TYPE_PCIXCC:
1042 rc = zcrypt_pcixcc_mcl(ap_dev);
1043 if (rc < 0) {
1044 zcrypt_device_free(zdev);
1045 return rc;
1047 zdev->user_space_type = rc;
1048 if (rc == ZCRYPT_PCIXCC_MCL2) {
1049 zdev->type_string = "PCIXCC_MCL2";
1050 zdev->speed_rating = PCIXCC_MCL2_SPEED_RATING;
1051 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE_OLD;
1052 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1053 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
1054 } else {
1055 zdev->type_string = "PCIXCC_MCL3";
1056 zdev->speed_rating = PCIXCC_MCL3_SPEED_RATING;
1057 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1058 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1059 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
1061 break;
1062 case AP_DEVICE_TYPE_CEX2C:
1063 zdev->user_space_type = ZCRYPT_CEX2C;
1064 zdev->type_string = "CEX2C";
1065 zdev->speed_rating = CEX2C_SPEED_RATING;
1066 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE;
1067 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE;
1068 zdev->max_exp_bit_length = PCIXCC_MAX_MOD_SIZE;
1069 break;
1070 case AP_DEVICE_TYPE_CEX3C:
1071 zdev->user_space_type = ZCRYPT_CEX3C;
1072 zdev->type_string = "CEX3C";
1073 zdev->speed_rating = CEX3C_SPEED_RATING;
1074 zdev->min_mod_size = CEX3C_MIN_MOD_SIZE;
1075 zdev->max_mod_size = CEX3C_MAX_MOD_SIZE;
1076 zdev->max_exp_bit_length = CEX3C_MAX_MOD_SIZE;
1077 break;
1078 default:
1079 goto out_free;
1082 rc = zcrypt_pcixcc_rng_supported(ap_dev);
1083 if (rc < 0) {
1084 zcrypt_device_free(zdev);
1085 return rc;
1087 if (rc)
1088 zdev->ops = &zcrypt_pcixcc_with_rng_ops;
1089 else
1090 zdev->ops = &zcrypt_pcixcc_ops;
1091 ap_dev->reply = &zdev->reply;
1092 ap_dev->private = zdev;
1093 rc = zcrypt_device_register(zdev);
1094 if (rc)
1095 goto out_free;
1096 return 0;
1098 out_free:
1099 ap_dev->private = NULL;
1100 zcrypt_device_free(zdev);
1101 return rc;
1105 * This is called to remove the extended PCIXCC/CEX2C driver information
1106 * if an AP device is removed.
1108 static void zcrypt_pcixcc_remove(struct ap_device *ap_dev)
1110 struct zcrypt_device *zdev = ap_dev->private;
1112 zcrypt_device_unregister(zdev);
1115 int __init zcrypt_pcixcc_init(void)
1117 return ap_driver_register(&zcrypt_pcixcc_driver, THIS_MODULE, "pcixcc");
1120 void zcrypt_pcixcc_exit(void)
1122 ap_driver_unregister(&zcrypt_pcixcc_driver);
1125 module_init(zcrypt_pcixcc_init);
1126 module_exit(zcrypt_pcixcc_exit);