27 #include <linux/module.h>
32 #include <asm/uaccess.h>
40 #define PCICC_MIN_MOD_SIZE 64
41 #define PCICC_MAX_MOD_SIZE_OLD 128
42 #define PCICC_MAX_MOD_SIZE 256
54 #define PCICC_SPEED_RATING 0
56 #define PCICC_MAX_MESSAGE_SIZE 0x710
57 #define PCICC_MAX_RESPONSE_SIZE 0x710
59 #define PCICC_CLEANUP_TIME (15*HZ)
69 "Copyright IBM Corp. 2001, 2006");
72 static int zcrypt_pcicc_probe(
struct ap_device *ap_dev);
73 static void zcrypt_pcicc_remove(
struct ap_device *ap_dev);
77 static struct ap_driver zcrypt_pcicc_driver = {
78 .probe = zcrypt_pcicc_probe,
79 .remove = zcrypt_pcicc_remove,
80 .ids = zcrypt_pcicc_ids,
97 static struct CPRB static_cprb = {
100 .func_id = {0x54,0x32},
101 .checkpoint_flag= 0x01,
103 .svr_name = {
'I',
'C',
'S',
'F',
' ',
' ',
' ',
' '}
109 static inline int is_PKCS11_padded(
unsigned char *
buffer,
int length)
112 if ((buffer[0] != 0x00) || (buffer[1] != 0x01))
114 for (i = 2; i <
length; i++)
115 if (buffer[i] != 0xFF)
117 if (i < 10 || i == length)
119 if (buffer[i] != 0x00)
127 static inline int is_PKCS12_padded(
unsigned char *buffer,
int length)
130 if ((buffer[0] != 0x00) || (buffer[1] != 0x02))
132 for (i = 2; i <
length; i++)
133 if (buffer[i] == 0x00)
135 if ((i < 10) || (i == length))
137 if (buffer[i] != 0x00)
151 static int ICAMEX_msg_to_type6MEX_msg(
struct zcrypt_device *zdev,
155 static struct type6_hdr static_type6_hdr = {
157 .offset1 = 0x00000058,
158 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
159 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
160 .function_code = {
'P',
'K'},
165 .only_rule = {
'P',
'K',
'C',
'S',
'-',
'1',
'.',
'2'}
184 msg->hdr = static_type6_hdr;
185 msg->fr = static_pke_function_and_rules;
197 size = zcrypt_type6_mex_key_en(mex,
msg->text + vud_len, 0);
200 size +=
sizeof(*msg) + vud_len;
205 msg->hdr.function_code[1] =
'D';
206 msg->fr.function_code[1] =
'D';
209 size = zcrypt_type6_mex_key_de(mex,
msg->text + vud_len, 0);
212 size +=
sizeof(*msg) + vud_len;
216 msg->hdr.ToCardLen1 = (size -
sizeof(
msg->hdr) + 3) & -4;
219 msg->cprb = static_cprb;
225 ap_msg->
length = (size + 3) & -4;
238 static int ICACRT_msg_to_type6CRT_msg(
struct zcrypt_device *zdev,
242 static struct type6_hdr static_type6_hdr = {
244 .offset1 = 0x00000058,
245 .agent_id = {0x01,0x00,0x43,0x43,0x41,0x2D,0x41,0x50,
246 0x50,0x4C,0x20,0x20,0x20,0x01,0x01,0x01},
247 .function_code = {
'P',
'D'},
252 .only_rule = {
'P',
'K',
'C',
'S',
'-',
'1',
'.',
'2'}
278 msg->hdr = static_type6_hdr;
279 msg->hdr.ToCardLen1 = (size -
sizeof(
msg->hdr) + 3) & -4;
282 msg->cprb = static_cprb;
284 msg->cprb.req_parml =
msg->cprb.rpl_parml =
287 msg->fr = static_pkd_function_and_rules;
289 ap_msg->
length = (size + 3) & -4;
314 char __user *outputdata,
315 unsigned int outputdatalength)
317 static unsigned char static_pad[] = {
319 0x1B,0x7B,0x5D,0xB5,0x75,0x01,0x3D,0xFD,
320 0x8D,0xD1,0xC7,0x03,0x2D,0x09,0x23,0x57,
321 0x89,0x49,0xB9,0x3F,0xBB,0x99,0x41,0x5B,
322 0x75,0x21,0x7B,0x9D,0x3B,0x6B,0x51,0x39,
323 0xBB,0x0D,0x35,0xB9,0x89,0x0F,0x93,0xA5,
324 0x0B,0x47,0xF1,0xD3,0xBB,0xCB,0xF1,0x9D,
325 0x23,0x73,0x71,0xFF,0xF3,0xF5,0x45,0xFB,
326 0x61,0x29,0x23,0xFD,0xF1,0x29,0x3F,0x7F,
327 0x17,0xB7,0x1B,0xA9,0x19,0xBD,0x57,0xA9,
328 0xD7,0x95,0xA3,0xCB,0xED,0x1D,0xDB,0x45,
329 0x7D,0x11,0xD1,0x51,0x1B,0xED,0x71,0xE9,
330 0xB1,0xD1,0xAB,0xAB,0x21,0x2B,0x1B,0x9F,
331 0x3B,0x9F,0xF7,0xF7,0xBD,0x63,0xEB,0xAD,
332 0xDF,0xB3,0x6F,0x5B,0xDB,0x8D,0xA9,0x5D,
333 0xE3,0x7D,0x77,0x49,0x47,0xF5,0xA7,0xFD,
334 0xAB,0x2F,0x27,0x35,0x77,0xD3,0x49,0xC9,
335 0x09,0xEB,0xB1,0xF9,0xBF,0x4B,0xCB,0x2B,
336 0xEB,0xEB,0x05,0xFF,0x7D,0xC7,0x91,0x8B,
337 0x09,0x83,0xB9,0xB9,0x69,0x33,0x39,0x6B,
338 0x79,0x75,0x19,0xBF,0xBB,0x07,0x1D,0xBD,
339 0x29,0xBF,0x39,0x95,0x93,0x1D,0x35,0xC7,
340 0xC9,0x4D,0xE5,0x97,0x0B,0x43,0x9B,0xF1,
341 0x16,0x93,0x03,0x1F,0xA5,0xFB,0xDB,0xF3,
342 0x27,0x4F,0x27,0x61,0x05,0x1F,0xB9,0x23,
343 0x2F,0xC3,0x81,0xA9,0x23,0x71,0x55,0x55,
344 0xEB,0xED,0x41,0xE5,0xF3,0x11,0xF1,0x43,
345 0x69,0x03,0xBD,0x0B,0x37,0x0F,0x51,0x8F,
346 0x0B,0xB5,0x89,0x5B,0x67,0xA9,0xD9,0x4F,
347 0x01,0xF9,0x21,0x77,0x37,0x73,0x79,0xC5,
348 0x7F,0x51,0xC1,0xCF,0x97,0xA1,0x75,0xAD,
349 0x35,0x9D,0xD3,0xD3,0xA7,0x9D,0x5D,0x41,
350 0x6F,0x65,0x1B,0xCF,0xA9,0x87,0x91,0x09
353 unsigned short service_rc, service_rs;
354 unsigned int reply_len,
pad_len;
360 if (service_rc == 8 && service_rs == 66)
362 if (service_rc == 8 && service_rs == 65)
364 if (service_rc == 8 && service_rs == 770) {
368 if (service_rc == 8 && service_rs == 783) {
372 if (service_rc == 8 && service_rs == 72)
379 if (reply_len > outputdatalength)
391 pad_len = outputdatalength - reply_len;
398 if (
put_user(0, outputdata + pad_len - 1))
402 if (
copy_to_user(outputdata + pad_len, data, reply_len))
409 char __user *outputdata,
410 unsigned int outputdatalength)
415 switch (msg->
hdr.type) {
418 return convert_error(zdev, reply);
420 if (msg->
hdr.reply_code)
421 return convert_error(zdev, reply);
422 if (msg->
cprb.cprb_ver_id == 0x01)
423 return convert_type86(zdev, reply,
424 outputdata, outputdatalength);
440 static void zcrypt_pcicc_receive(
struct ap_device *ap_dev,
458 t86r->
cprb.cprb_ver_id == 0x01) {
459 length =
sizeof(
struct type86_reply) + t86r->length - 2;
484 ap_init_message(&ap_msg);
488 ap_msg.
receive = zcrypt_pcicc_receive;
493 rc = ICAMEX_msg_to_type6MEX_msg(zdev, &ap_msg, mex);
496 init_completion(&
work);
500 rc = convert_response(zdev, &ap_msg, mex->
outputdata,
517 static long zcrypt_pcicc_modexpo_crt(
struct zcrypt_device *zdev,
524 ap_init_message(&ap_msg);
528 ap_msg.
receive = zcrypt_pcicc_receive;
533 rc = ICACRT_msg_to_type6CRT_msg(zdev, &ap_msg, crt);
536 init_completion(&
work);
540 rc = convert_response(zdev, &ap_msg, crt->
outputdata,
554 .rsa_modexpo = zcrypt_pcicc_modexpo,
555 .rsa_modexpo_crt = zcrypt_pcicc_modexpo_crt,
563 static int zcrypt_pcicc_probe(
struct ap_device *ap_dev)
572 zdev->
ops = &zcrypt_pcicc_ops;
597 static void zcrypt_pcicc_remove(
struct ap_device *ap_dev)