28 #include <linux/module.h>
32 #include <linux/slab.h>
42 #define PCIXCC_MIN_MOD_SIZE_OLD 64
43 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c
45 #define CEIL4(x) ((((x)+3)/4)*4)
51 #define PCIXCC_RESPONSE_TYPE_ICA 0
52 #define PCIXCC_RESPONSE_TYPE_XCRB 1
56 "Copyright IBM Corp. 2001, 2012");
142 static struct CPRBX static_cprbx = {
145 .func_id = {0x54, 0x32},
157 static int ICAMEX_msg_to_type6MEX_msgX(
struct zcrypt_device *zdev,
161 static struct type6_hdr static_type6_hdrX = {
163 .offset1 = 0x00000058,
164 .agent_id = {
'C',
'A',},
165 .function_code = {
'P',
'K'},
170 .only_rule = {
'M',
'R',
'P',
' ',
' ',
' ',
' ',
' '}
175 .only_rule = {
'Z',
'E',
'R',
'O',
'-',
'P',
'A',
'D'}
192 size = zcrypt_type6_mex_key_en(mex, msg->text+mex->
inputdatalength, 1);
198 msg->hdr = static_type6_hdrX;
199 msg->hdr.ToCardLen1 = size -
sizeof(msg->hdr);
202 msg->cprbx = static_cprbx;
204 msg->cprbx.rpl_msgbl = msg->hdr.FromCardLen1;
207 static_pke_fnr_MCL2 : static_pke_fnr;
209 msg->cprbx.req_parml = size -
sizeof(msg->hdr) -
sizeof(msg->cprbx);
224 static int ICACRT_msg_to_type6CRT_msgX(
struct zcrypt_device *zdev,
228 static struct type6_hdr static_type6_hdrX = {
230 .offset1 = 0x00000058,
231 .agent_id = {
'C',
'A',},
232 .function_code = {
'P',
'D'},
237 .only_rule = {
'Z',
'E',
'R',
'O',
'-',
'P',
'A',
'D'}
243 .only_rule = {
'P',
'K',
'C',
'S',
'-',
'1',
'.',
'2'}
266 msg->hdr = static_type6_hdrX;
267 msg->hdr.ToCardLen1 = size -
sizeof(msg->hdr);
270 msg->cprbx = static_cprbx;
272 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
273 size -
sizeof(msg->hdr) -
sizeof(msg->cprbx);
276 static_pkd_fnr_MCL2 : static_pkd_fnr;
296 static int XCRB_msg_to_type6CPRB_msgX(
struct zcrypt_device *zdev,
300 static struct type6_hdr static_type6_hdrX = {
302 .offset1 = 0x00000058,
327 msg->hdr = static_type6_hdrX;
331 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
341 if (msg->cprbx.cprb_len +
sizeof(msg->hdr.function_code) >
344 function_code = ((
unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
345 memcpy(msg->hdr.function_code, function_code,
346 sizeof(msg->hdr.function_code));
348 if (
memcmp(function_code,
"US", 2) == 0)
382 char __user *outputdata,
383 unsigned int outputdatalength)
385 static unsigned char static_pad[] = {
387 0x1B, 0x7B, 0x5D, 0xB5, 0x75, 0x01, 0x3D, 0xFD,
388 0x8D, 0xD1, 0xC7, 0x03, 0x2D, 0x09, 0x23, 0x57,
389 0x89, 0x49, 0xB9, 0x3F, 0xBB, 0x99, 0x41, 0x5B,
390 0x75, 0x21, 0x7B, 0x9D, 0x3B, 0x6B, 0x51, 0x39,
391 0xBB, 0x0D, 0x35, 0xB9, 0x89, 0x0F, 0x93, 0xA5,
392 0x0B, 0x47, 0xF1, 0xD3, 0xBB, 0xCB, 0xF1, 0x9D,
393 0x23, 0x73, 0x71, 0xFF, 0xF3, 0xF5, 0x45, 0xFB,
394 0x61, 0x29, 0x23, 0xFD, 0xF1, 0x29, 0x3F, 0x7F,
395 0x17, 0xB7, 0x1B, 0xA9, 0x19, 0xBD, 0x57, 0xA9,
396 0xD7, 0x95, 0xA3, 0xCB, 0xED, 0x1D, 0xDB, 0x45,
397 0x7D, 0x11, 0xD1, 0x51, 0x1B, 0xED, 0x71, 0xE9,
398 0xB1, 0xD1, 0xAB, 0xAB, 0x21, 0x2B, 0x1B, 0x9F,
399 0x3B, 0x9F, 0xF7, 0xF7, 0xBD, 0x63, 0xEB, 0xAD,
400 0xDF, 0xB3, 0x6F, 0x5B, 0xDB, 0x8D, 0xA9, 0x5D,
401 0xE3, 0x7D, 0x77, 0x49, 0x47, 0xF5, 0xA7, 0xFD,
402 0xAB, 0x2F, 0x27, 0x35, 0x77, 0xD3, 0x49, 0xC9,
403 0x09, 0xEB, 0xB1, 0xF9, 0xBF, 0x4B, 0xCB, 0x2B,
404 0xEB, 0xEB, 0x05, 0xFF, 0x7D, 0xC7, 0x91, 0x8B,
405 0x09, 0x83, 0xB9, 0xB9, 0x69, 0x33, 0x39, 0x6B,
406 0x79, 0x75, 0x19, 0xBF, 0xBB, 0x07, 0x1D, 0xBD,
407 0x29, 0xBF, 0x39, 0x95, 0x93, 0x1D, 0x35, 0xC7,
408 0xC9, 0x4D, 0xE5, 0x97, 0x0B, 0x43, 0x9B, 0xF1,
409 0x16, 0x93, 0x03, 0x1F, 0xA5, 0xFB, 0xDB, 0xF3,
410 0x27, 0x4F, 0x27, 0x61, 0x05, 0x1F, 0xB9, 0x23,
411 0x2F, 0xC3, 0x81, 0xA9, 0x23, 0x71, 0x55, 0x55,
412 0xEB, 0xED, 0x41, 0xE5, 0xF3, 0x11, 0xF1, 0x43,
413 0x69, 0x03, 0xBD, 0x0B, 0x37, 0x0F, 0x51, 0x8F,
414 0x0B, 0xB5, 0x89, 0x5B, 0x67, 0xA9, 0xD9, 0x4F,
415 0x01, 0xF9, 0x21, 0x77, 0x37, 0x73, 0x79, 0xC5,
416 0x7F, 0x51, 0xC1, 0xCF, 0x97, 0xA1, 0x75, 0xAD,
417 0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41,
418 0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09
421 unsigned short service_rc, service_rs;
422 unsigned int reply_len,
pad_len;
425 service_rc = msg->
cprbx.ccp_rtcode;
427 service_rs = msg->
cprbx.ccp_rscode;
428 if (service_rc == 8 && service_rs == 66)
430 if (service_rc == 8 && service_rs == 65)
432 if (service_rc == 8 && service_rs == 770)
434 if (service_rc == 8 && service_rs == 783) {
438 if (service_rc == 12 && service_rs == 769)
440 if (service_rc == 8 && service_rs == 72)
446 reply_len = msg->
length - 2;
447 if (reply_len > outputdatalength)
459 pad_len = outputdatalength - reply_len;
466 if (
put_user(0, outputdata + pad_len - 1))
470 if (
copy_to_user(outputdata + pad_len, data, reply_len))
493 data + msg->
fmt2.offset1, msg->
fmt2.count1))
498 if (msg->
fmt2.count2)
500 data + msg->
fmt2.offset2, msg->
fmt2.count2))
517 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
519 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
520 return msg->fmt2.count2;
525 char __user *outputdata,
526 unsigned int outputdatalength)
531 switch (((
unsigned char *) reply->
message)[1]) {
534 return convert_error(zdev, reply);
536 if (msg->
cprbx.ccp_rtcode &&
537 (msg->
cprbx.ccp_rscode == 0x14f) &&
538 (outputdatalength > 256)) {
545 if (msg->
hdr.reply_code)
546 return convert_error(zdev, reply);
547 if (msg->
cprbx.cprb_ver_id == 0x02)
548 return convert_type86_ica(zdev, reply,
549 outputdata, outputdatalength);
565 switch (((
unsigned char *) reply->
message)[1]) {
569 return convert_error(zdev, reply);
571 if (msg->
hdr.reply_code) {
573 return convert_error(zdev, reply);
575 if (msg->
cprbx.cprb_ver_id == 0x02)
576 return convert_type86_xcrb(zdev, reply, xcRB);
592 switch (msg->
hdr.type) {
597 if (msg->
hdr.reply_code)
599 if (msg->
cprbx.cprb_ver_id == 0x02)
600 return convert_type86_rng(zdev, reply, data);
617 static void zcrypt_msgtype6_receive(
struct ap_device *ap_dev,
637 t86r->cprbx.cprb_ver_id == 0x02) {
638 switch (resp_type->
type) {
646 length = t86r->fmt2.offset2 + t86r->fmt2.count2;
652 sizeof(error_reply));
669 static long zcrypt_msgtype6_modexpo(
struct zcrypt_device *zdev,
678 ap_init_message(&ap_msg);
682 ap_msg.
receive = zcrypt_msgtype6_receive;
686 rc = ICAMEX_msg_to_type6MEX_msgX(zdev, &ap_msg, mex);
689 init_completion(&resp_type.
work);
693 rc = convert_response_ica(zdev, &ap_msg, mex->
outputdata,
710 static long zcrypt_msgtype6_modexpo_crt(
struct zcrypt_device *zdev,
719 ap_init_message(&ap_msg);
723 ap_msg.
receive = zcrypt_msgtype6_receive;
727 rc = ICACRT_msg_to_type6CRT_msgX(zdev, &ap_msg, crt);
730 init_completion(&resp_type.
work);
734 rc = convert_response_ica(zdev, &ap_msg, crt->
outputdata,
751 static long zcrypt_msgtype6_send_cprb(
struct zcrypt_device *zdev,
760 ap_init_message(&ap_msg);
764 ap_msg.
receive = zcrypt_msgtype6_receive;
768 rc = XCRB_msg_to_type6CPRB_msgX(zdev, &ap_msg, xcRB);
771 init_completion(&resp_type.
work);
775 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
801 ap_init_message(&ap_msg);
805 ap_msg.
receive = zcrypt_msgtype6_receive;
810 init_completion(&resp_type.
work);
814 rc = convert_response_rng(zdev, &ap_msg, buffer);
825 static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
828 .rsa_modexpo = zcrypt_msgtype6_modexpo,
829 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
830 .send_cprb = zcrypt_msgtype6_send_cprb,
833 static struct zcrypt_ops zcrypt_msgtype6_ops = {
836 .rsa_modexpo = zcrypt_msgtype6_modexpo,
837 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
838 .send_cprb = zcrypt_msgtype6_send_cprb,
839 .rng = zcrypt_msgtype6_rng,