2 * linux/drivers/s390/crypto/zcrypt_pcixcc.c
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)
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>
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
;
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
*,
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
,
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')
113 static struct CPRBX static_cprbx
= {
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
= {
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'},
141 .only_rule
= {'M','R','P',' ',' ',' ',' ',' '}
143 static struct function_and_rules_block static_pke_fnr_MCL2
= {
144 .function_code
= {'P','K'},
146 .only_rule
= {'Z','E','R','O','-','P','A','D'}
149 struct type6_hdr hdr
;
151 struct function_and_rules_block fr
;
152 unsigned short length
;
154 } __attribute__((packed
)) *msg
= ap_msg
->message
;
158 msg
->length
= mex
->inputdatalength
+ 2;
159 if (copy_from_user(msg
->text
, mex
->inputdata
, mex
->inputdatalength
))
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);
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
;
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
= {
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'},
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'},
214 .only_rule
= {'P','K','C','S','-','1','.','2'}
217 struct type6_hdr hdr
;
219 struct function_and_rules_block fr
;
220 unsigned short length
;
222 } __attribute__((packed
)) *msg
= ap_msg
->message
;
226 msg
->length
= crt
->inputdatalength
+ 2;
227 if (copy_from_user(msg
->text
, crt
->inputdata
, crt
->inputdatalength
))
230 /* Set up key which is located after the variable length text. */
231 size
= zcrypt_type6_crt_key(crt
, msg
->text
+ crt
->inputdatalength
, 1);
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
;
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
= {
273 .offset1
= 0x00000058,
276 struct type6_hdr hdr
;
278 } __attribute__((packed
)) *msg
= ap_msg
->message
;
280 int rcblen
= CEIL4(xcRB
->request_control_blk_length
);
282 char *req_data
= ap_msg
->message
+ sizeof(struct type6_hdr
) + rcblen
;
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
)
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
)
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
;
309 if (copy_from_user(&(msg
->cprbx
), xcRB
->request_control_blk_addr
,
310 xcRB
->request_control_blk_length
))
312 if (msg
->cprbx
.cprb_len
+ sizeof(msg
->hdr
.function_code
) >
313 xcRB
->request_control_blk_length
)
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)
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
))
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
)
342 struct type6_hdr hdr
;
344 char function_code
[2];
345 short int rule_length
;
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
= {
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
= {
361 .func_id
= {0x54, 0x32},
362 .req_parml
= sizeof *msg
- sizeof(msg
->hdr
) -
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
;
394 unsigned char pad
[4]; /* 4 byte function code/rules block ? */
395 unsigned short length
;
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
[] = {
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
;
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)
449 if (service_rc
== 8 && service_rs
== 65)
451 if (service_rc
== 8 && service_rs
== 770)
453 if (service_rc
== 8 && service_rs
== 783) {
454 zdev
->min_mod_size
= PCIXCC_MIN_MOD_SIZE_OLD
;
457 if (service_rc
== 12 && service_rs
== 769)
459 if (service_rc
== 8 && service_rs
== 72)
462 return -EAGAIN
; /* repeat the request on a different device. */
465 reply_len
= msg
->length
- 2;
466 if (reply_len
> outputdatalength
)
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)
478 pad_len
= outputdatalength
- reply_len
;
482 /* 'restore' padding left in the PCICC/PCIXCC card. */
483 if (copy_to_user(outputdata
, static_pad
, pad_len
- 1))
485 if (put_user(0, outputdata
+ pad_len
- 1))
488 /* Copy the crypto response to user space. */
489 if (copy_to_user(outputdata
+ pad_len
, data
, reply_len
))
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
))
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
))
521 xcRB
->reply_data_length
= msg
->fmt2
.count2
;
525 static int convert_type86_rng(struct zcrypt_device
*zdev
,
526 struct ap_message
*reply
,
530 struct type86_hdr hdr
;
531 struct type86_fmt2_ext fmt2
;
533 } __attribute__((packed
)) *msg
= reply
->message
;
534 char *data
= reply
->message
;
536 if (msg
->cprbx
.ccp_rtcode
!= 0 || msg
->cprbx
.ccp_rscode
!= 0)
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;
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
571 default: /* Unknown response type, this should NEVER EVER happen */
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
598 default: /* Unknown response type, this should NEVER EVER happen */
599 xcRB
->status
= 0x0008044DL
; /* HDD_InvalidParm */
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
,
609 struct type86x_reply
*msg
= reply
->message
;
611 switch (msg
->hdr
.type
) {
612 case TYPE82_RSP_CODE
:
613 case TYPE88_RSP_CODE
:
615 case TYPE86_RSP_CODE
:
616 if (msg
->hdr
.reply_code
)
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
622 default: /* Unknown response type, this should NEVER EVER happen */
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
;
649 /* Copy the reply message to the request message buffer. */
651 memcpy(msg
->message
, &error_reply
, sizeof(error_reply
));
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
)
661 length
= min(PCIXCC_MAX_ICA_RESPONSE_SIZE
, length
);
662 memcpy(msg
->message
, reply
->message
, length
);
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
);
670 memcpy(msg
->message
, &error_reply
, sizeof error_reply
);
673 memcpy(msg
->message
, reply
->message
, sizeof error_reply
);
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
,
696 ap_init_message(&ap_msg
);
697 ap_msg
.message
= (void *) get_zeroed_page(GFP_KERNEL
);
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
);
707 init_completion(&resp_type
.work
);
708 ap_queue_message(zdev
->ap_dev
, &ap_msg
);
709 rc
= wait_for_completion_interruptible(&resp_type
.work
);
711 rc
= convert_response_ica(zdev
, &ap_msg
, mex
->outputdata
,
712 mex
->outputdatalength
);
714 /* Signal pending. */
715 ap_cancel_message(zdev
->ap_dev
, &ap_msg
);
717 free_page((unsigned long) ap_msg
.message
);
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
,
737 ap_init_message(&ap_msg
);
738 ap_msg
.message
= (void *) get_zeroed_page(GFP_KERNEL
);
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
);
748 init_completion(&resp_type
.work
);
749 ap_queue_message(zdev
->ap_dev
, &ap_msg
);
750 rc
= wait_for_completion_interruptible(&resp_type
.work
);
752 rc
= convert_response_ica(zdev
, &ap_msg
, crt
->outputdata
,
753 crt
->outputdatalength
);
755 /* Signal pending. */
756 ap_cancel_message(zdev
->ap_dev
, &ap_msg
);
758 free_page((unsigned long) ap_msg
.message
);
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
,
778 ap_init_message(&ap_msg
);
779 ap_msg
.message
= kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE
, GFP_KERNEL
);
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
);
789 init_completion(&resp_type
.work
);
790 ap_queue_message(zdev
->ap_dev
, &ap_msg
);
791 rc
= wait_for_completion_interruptible(&resp_type
.work
);
793 rc
= convert_response_xcrb(zdev
, &ap_msg
, xcRB
);
795 /* Signal pending. */
796 ap_cancel_message(zdev
->ap_dev
, &ap_msg
);
798 kzfree(ap_msg
.message
);
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
,
813 struct ap_message ap_msg
;
814 struct response_type resp_type
= {
815 .type
= PCIXCC_RESPONSE_TYPE_XCRB
,
819 ap_init_message(&ap_msg
);
820 ap_msg
.message
= kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE
, GFP_KERNEL
);
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
);
832 rc
= convert_response_rng(zdev
, &ap_msg
, buffer
);
834 /* Signal pending. */
835 ap_cancel_message(zdev
->ap_dev
, &ap_msg
);
836 kfree(ap_msg
.message
);
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,
933 unsigned long long psmid
;
938 reply
= (void *) get_zeroed_page(GFP_KERNEL
);
942 rc
= ap_send(ap_dev
->qid
, 0x0102030405060708ULL
, msg
, sizeof(msg
));
946 /* Wait for the test message to complete. */
947 for (i
= 0; i
< 6; i
++) {
949 rc
= ap_recv(ap_dev
->qid
, &psmid
, reply
, 4096);
950 if (rc
== 0 && psmid
== 0x0102030405060708ULL
)
960 cprbx
= (struct CPRBX
*) (reply
+ 48);
961 if (cprbx
->ccp_rtcode
== 8 && cprbx
->ccp_rscode
== 33)
962 rc
= ZCRYPT_PCIXCC_MCL2
;
964 rc
= ZCRYPT_PCIXCC_MCL3
;
966 free_page((unsigned long) reply
);
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
;
982 struct type86_hdr hdr
;
983 struct type86_fmt2_ext fmt2
;
985 } __attribute__((packed
)) *reply
;
988 ap_init_message(&ap_msg
);
989 ap_msg
.message
= (void *) get_zeroed_page(GFP_KERNEL
);
993 rng_type6CPRB_msgX(ap_dev
, &ap_msg
, 4);
994 rc
= ap_send(ap_dev
->qid
, 0x0102030405060708ULL
, ap_msg
.message
,
999 /* Wait for the test message to complete. */
1000 for (i
= 0; i
< 2 * HZ
; i
++) {
1002 rc
= ap_recv(ap_dev
->qid
, &psmid
, ap_msg
.message
, 4096);
1003 if (rc
== 0 && psmid
== 0x0102030405060708ULL
)
1008 /* Got no answer. */
1013 reply
= ap_msg
.message
;
1014 if (reply
->cprbx
.ccp_rtcode
== 0 && reply
->cprbx
.ccp_rscode
== 0)
1019 free_page((unsigned long) ap_msg
.message
);
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
;
1035 zdev
= zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE
);
1038 zdev
->ap_dev
= ap_dev
;
1040 switch (ap_dev
->device_type
) {
1041 case AP_DEVICE_TYPE_PCIXCC
:
1042 rc
= zcrypt_pcixcc_mcl(ap_dev
);
1044 zcrypt_device_free(zdev
);
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
;
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
;
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
;
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
;
1082 rc
= zcrypt_pcixcc_rng_supported(ap_dev
);
1084 zcrypt_device_free(zdev
);
1088 zdev
->ops
= &zcrypt_pcixcc_with_rng_ops
;
1090 zdev
->ops
= &zcrypt_pcixcc_ops
;
1091 ap_dev
->reply
= &zdev
->reply
;
1092 ap_dev
->private = zdev
;
1093 rc
= zcrypt_device_register(zdev
);
1099 ap_dev
->private = NULL
;
1100 zcrypt_device_free(zdev
);
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
);