0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #define KMSG_COMPONENT "zcrypt"
0014 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0015
0016 #include <linux/module.h>
0017 #include <linux/init.h>
0018 #include <linux/err.h>
0019 #include <linux/delay.h>
0020 #include <linux/slab.h>
0021 #include <linux/atomic.h>
0022 #include <linux/uaccess.h>
0023
0024 #include "ap_bus.h"
0025 #include "zcrypt_api.h"
0026 #include "zcrypt_error.h"
0027 #include "zcrypt_msgtype6.h"
0028 #include "zcrypt_cca_key.h"
0029
0030 #define CEXXC_MAX_ICA_RESPONSE_SIZE 0x77c
0031
0032 #define CEIL4(x) ((((x) + 3) / 4) * 4)
0033
0034 struct response_type {
0035 struct completion work;
0036 int type;
0037 };
0038
0039 #define CEXXC_RESPONSE_TYPE_ICA 0
0040 #define CEXXC_RESPONSE_TYPE_XCRB 1
0041 #define CEXXC_RESPONSE_TYPE_EP11 2
0042
0043 MODULE_AUTHOR("IBM Corporation");
0044 MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \
0045 "Copyright IBM Corp. 2001, 2012");
0046 MODULE_LICENSE("GPL");
0047
0048 struct function_and_rules_block {
0049 unsigned char function_code[2];
0050 unsigned short ulen;
0051 unsigned char only_rule[8];
0052 } __packed;
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 static const struct CPRBX static_cprbx = {
0072 .cprb_len = 0x00DC,
0073 .cprb_ver_id = 0x02,
0074 .func_id = {0x54, 0x32},
0075 };
0076
0077 int speed_idx_cca(int req_type)
0078 {
0079 switch (req_type) {
0080 case 0x4142:
0081 case 0x4149:
0082 case 0x414D:
0083 case 0x4341:
0084 case 0x4344:
0085 case 0x4354:
0086 case 0x4358:
0087 case 0x444B:
0088 case 0x4558:
0089 case 0x4643:
0090 case 0x4651:
0091 case 0x4C47:
0092 case 0x4C4B:
0093 case 0x4C51:
0094 case 0x4F48:
0095 case 0x504F:
0096 case 0x5053:
0097 case 0x5058:
0098 case 0x5343:
0099 case 0x5344:
0100 case 0x5345:
0101 case 0x5350:
0102 return LOW;
0103 case 0x414B:
0104 case 0x4345:
0105 case 0x4349:
0106 case 0x434D:
0107 case 0x4847:
0108 case 0x4849:
0109 case 0x484D:
0110 case 0x4850:
0111 case 0x4851:
0112 case 0x4954:
0113 case 0x4958:
0114 case 0x4B43:
0115 case 0x4B44:
0116 case 0x4B45:
0117 case 0x4B47:
0118 case 0x4B48:
0119 case 0x4B49:
0120 case 0x4B4E:
0121 case 0x4B50:
0122 case 0x4B52:
0123 case 0x4B54:
0124 case 0x4B58:
0125 case 0x4D50:
0126 case 0x4D53:
0127 case 0x4D56:
0128 case 0x4D58:
0129 case 0x5044:
0130 case 0x5045:
0131 case 0x5046:
0132 case 0x5047:
0133 case 0x5049:
0134 case 0x504B:
0135 case 0x504D:
0136 case 0x5254:
0137 case 0x5347:
0138 case 0x5349:
0139 case 0x534B:
0140 case 0x534D:
0141 case 0x5356:
0142 case 0x5358:
0143 case 0x5443:
0144 case 0x544B:
0145 case 0x5647:
0146 return HIGH;
0147 default:
0148 return MEDIUM;
0149 }
0150 }
0151
0152 int speed_idx_ep11(int req_type)
0153 {
0154 switch (req_type) {
0155 case 1:
0156 case 2:
0157 case 36:
0158 case 37:
0159 case 38:
0160 case 39:
0161 case 40:
0162 return LOW;
0163 case 17:
0164 case 18:
0165 case 19:
0166 case 20:
0167 case 21:
0168 case 22:
0169 case 26:
0170 case 30:
0171 case 31:
0172 case 32:
0173 case 33:
0174 case 34:
0175 case 35:
0176 return HIGH;
0177 default:
0178 return MEDIUM;
0179 }
0180 }
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 static int icamex_msg_to_type6mex_msgx(struct zcrypt_queue *zq,
0192 struct ap_message *ap_msg,
0193 struct ica_rsa_modexpo *mex)
0194 {
0195 static struct type6_hdr static_type6_hdrX = {
0196 .type = 0x06,
0197 .offset1 = 0x00000058,
0198 .agent_id = {'C', 'A',},
0199 .function_code = {'P', 'K'},
0200 };
0201 static struct function_and_rules_block static_pke_fnr = {
0202 .function_code = {'P', 'K'},
0203 .ulen = 10,
0204 .only_rule = {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '}
0205 };
0206 struct {
0207 struct type6_hdr hdr;
0208 struct CPRBX cprbx;
0209 struct function_and_rules_block fr;
0210 unsigned short length;
0211 char text[0];
0212 } __packed * msg = ap_msg->msg;
0213 int size;
0214
0215
0216
0217
0218
0219
0220 if (WARN_ON_ONCE(mex->inputdatalength > PAGE_SIZE))
0221 return -EINVAL;
0222
0223
0224 msg->length = mex->inputdatalength + 2;
0225 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength))
0226 return -EFAULT;
0227
0228
0229 size = zcrypt_type6_mex_key_en(mex, msg->text + mex->inputdatalength);
0230 if (size < 0)
0231 return size;
0232 size += sizeof(*msg) + mex->inputdatalength;
0233
0234
0235 msg->hdr = static_type6_hdrX;
0236 msg->hdr.tocardlen1 = size - sizeof(msg->hdr);
0237 msg->hdr.fromcardlen1 = CEXXC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
0238
0239 msg->cprbx = static_cprbx;
0240 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
0241 msg->cprbx.rpl_msgbl = msg->hdr.fromcardlen1;
0242
0243 msg->fr = static_pke_fnr;
0244
0245 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx);
0246
0247 ap_msg->len = size;
0248 return 0;
0249 }
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 static int icacrt_msg_to_type6crt_msgx(struct zcrypt_queue *zq,
0261 struct ap_message *ap_msg,
0262 struct ica_rsa_modexpo_crt *crt)
0263 {
0264 static struct type6_hdr static_type6_hdrX = {
0265 .type = 0x06,
0266 .offset1 = 0x00000058,
0267 .agent_id = {'C', 'A',},
0268 .function_code = {'P', 'D'},
0269 };
0270 static struct function_and_rules_block static_pkd_fnr = {
0271 .function_code = {'P', 'D'},
0272 .ulen = 10,
0273 .only_rule = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'}
0274 };
0275
0276 struct {
0277 struct type6_hdr hdr;
0278 struct CPRBX cprbx;
0279 struct function_and_rules_block fr;
0280 unsigned short length;
0281 char text[0];
0282 } __packed * msg = ap_msg->msg;
0283 int size;
0284
0285
0286
0287
0288
0289
0290 if (WARN_ON_ONCE(crt->inputdatalength > PAGE_SIZE))
0291 return -EINVAL;
0292
0293
0294 msg->length = crt->inputdatalength + 2;
0295 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength))
0296 return -EFAULT;
0297
0298
0299 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength);
0300 if (size < 0)
0301 return size;
0302 size += sizeof(*msg) + crt->inputdatalength;
0303
0304
0305 msg->hdr = static_type6_hdrX;
0306 msg->hdr.tocardlen1 = size - sizeof(msg->hdr);
0307 msg->hdr.fromcardlen1 = CEXXC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr);
0308
0309 msg->cprbx = static_cprbx;
0310 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
0311 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl =
0312 size - sizeof(msg->hdr) - sizeof(msg->cprbx);
0313
0314 msg->fr = static_pkd_fnr;
0315
0316 ap_msg->len = size;
0317 return 0;
0318 }
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329 struct type86_fmt2_msg {
0330 struct type86_hdr hdr;
0331 struct type86_fmt2_ext fmt2;
0332 } __packed;
0333
0334 static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
0335 struct ica_xcRB *xcrb,
0336 unsigned int *fcode,
0337 unsigned short **dom)
0338 {
0339 static struct type6_hdr static_type6_hdrX = {
0340 .type = 0x06,
0341 .offset1 = 0x00000058,
0342 };
0343 struct {
0344 struct type6_hdr hdr;
0345 struct CPRBX cprbx;
0346 } __packed * msg = ap_msg->msg;
0347
0348 int rcblen = CEIL4(xcrb->request_control_blk_length);
0349 int req_sumlen, resp_sumlen;
0350 char *req_data = ap_msg->msg + sizeof(struct type6_hdr) + rcblen;
0351 char *function_code;
0352
0353 if (CEIL4(xcrb->request_control_blk_length) <
0354 xcrb->request_control_blk_length)
0355 return -EINVAL;
0356
0357
0358 ap_msg->len = sizeof(struct type6_hdr) +
0359 CEIL4(xcrb->request_control_blk_length) +
0360 xcrb->request_data_length;
0361 if (ap_msg->len > ap_msg->bufsize)
0362 return -EINVAL;
0363
0364
0365
0366
0367
0368 req_sumlen = CEIL4(xcrb->request_control_blk_length) +
0369 xcrb->request_data_length;
0370 if ((CEIL4(xcrb->request_control_blk_length) <=
0371 xcrb->request_data_length) ?
0372 req_sumlen < xcrb->request_data_length :
0373 req_sumlen < CEIL4(xcrb->request_control_blk_length)) {
0374 return -EINVAL;
0375 }
0376
0377 if (CEIL4(xcrb->reply_control_blk_length) <
0378 xcrb->reply_control_blk_length)
0379 return -EINVAL;
0380
0381
0382
0383
0384
0385 resp_sumlen = CEIL4(xcrb->reply_control_blk_length) +
0386 xcrb->reply_data_length;
0387 if ((CEIL4(xcrb->reply_control_blk_length) <=
0388 xcrb->reply_data_length) ?
0389 resp_sumlen < xcrb->reply_data_length :
0390 resp_sumlen < CEIL4(xcrb->reply_control_blk_length)) {
0391 return -EINVAL;
0392 }
0393
0394
0395 msg->hdr = static_type6_hdrX;
0396 memcpy(msg->hdr.agent_id, &xcrb->agent_ID, sizeof(xcrb->agent_ID));
0397 msg->hdr.tocardlen1 = xcrb->request_control_blk_length;
0398 if (xcrb->request_data_length) {
0399 msg->hdr.offset2 = msg->hdr.offset1 + rcblen;
0400 msg->hdr.tocardlen2 = xcrb->request_data_length;
0401 }
0402 msg->hdr.fromcardlen1 = xcrb->reply_control_blk_length;
0403 msg->hdr.fromcardlen2 = xcrb->reply_data_length;
0404
0405
0406 if (z_copy_from_user(userspace, &msg->cprbx, xcrb->request_control_blk_addr,
0407 xcrb->request_control_blk_length))
0408 return -EFAULT;
0409 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
0410 xcrb->request_control_blk_length)
0411 return -EINVAL;
0412 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
0413 memcpy(msg->hdr.function_code, function_code,
0414 sizeof(msg->hdr.function_code));
0415
0416 *fcode = (msg->hdr.function_code[0] << 8) | msg->hdr.function_code[1];
0417 *dom = (unsigned short *)&msg->cprbx.domain;
0418
0419
0420 if (memcmp(function_code, "US", 2) == 0 ||
0421 memcmp(function_code, "AU", 2) == 0)
0422 ap_msg->flags |= AP_MSG_FLAG_SPECIAL;
0423
0424 #ifdef CONFIG_ZCRYPT_DEBUG
0425 if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL)
0426 ap_msg->flags ^= AP_MSG_FLAG_SPECIAL;
0427 #endif
0428
0429
0430 switch (*(unsigned short *)(&msg->cprbx.func_id[0])) {
0431 case 0x5432:
0432 ap_msg->flags |= AP_MSG_FLAG_USAGE;
0433 break;
0434 case 0x5433:
0435 case 0x5435:
0436 case 0x5436:
0437 case 0x5437:
0438 ap_msg->flags |= AP_MSG_FLAG_ADMIN;
0439 break;
0440 default:
0441 ZCRYPT_DBF_DBG("%s unknown CPRB minor version '%c%c'\n",
0442 __func__, msg->cprbx.func_id[0],
0443 msg->cprbx.func_id[1]);
0444 }
0445
0446
0447 if (xcrb->request_data_length &&
0448 z_copy_from_user(userspace, req_data, xcrb->request_data_address,
0449 xcrb->request_data_length))
0450 return -EFAULT;
0451
0452 return 0;
0453 }
0454
0455 static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap_msg,
0456 struct ep11_urb *xcrb,
0457 unsigned int *fcode,
0458 unsigned int *domain)
0459 {
0460 unsigned int lfmt;
0461 static struct type6_hdr static_type6_ep11_hdr = {
0462 .type = 0x06,
0463 .rqid = {0x00, 0x01},
0464 .function_code = {0x00, 0x00},
0465 .agent_id[0] = 0x58,
0466 .agent_id[1] = 0x43,
0467 .offset1 = 0x00000058,
0468 };
0469
0470 struct {
0471 struct type6_hdr hdr;
0472 struct ep11_cprb cprbx;
0473 unsigned char pld_tag;
0474 unsigned char pld_lenfmt;
0475 } __packed * msg = ap_msg->msg;
0476
0477 struct pld_hdr {
0478 unsigned char func_tag;
0479 unsigned char func_len;
0480 unsigned int func_val;
0481 unsigned char dom_tag;
0482 unsigned char dom_len;
0483 unsigned int dom_val;
0484 } __packed * payload_hdr = NULL;
0485
0486 if (CEIL4(xcrb->req_len) < xcrb->req_len)
0487 return -EINVAL;
0488
0489
0490 ap_msg->len = sizeof(struct type6_hdr) + CEIL4(xcrb->req_len);
0491 if (ap_msg->len > ap_msg->bufsize)
0492 return -EINVAL;
0493
0494 if (CEIL4(xcrb->resp_len) < xcrb->resp_len)
0495 return -EINVAL;
0496
0497
0498 msg->hdr = static_type6_ep11_hdr;
0499 msg->hdr.tocardlen1 = xcrb->req_len;
0500 msg->hdr.fromcardlen1 = xcrb->resp_len;
0501
0502
0503 if (z_copy_from_user(userspace, &msg->cprbx.cprb_len,
0504 (char __force __user *)xcrb->req, xcrb->req_len)) {
0505 return -EFAULT;
0506 }
0507
0508 if ((msg->pld_lenfmt & 0x80) == 0x80) {
0509 switch (msg->pld_lenfmt & 0x03) {
0510 case 1:
0511 lfmt = 2;
0512 break;
0513 case 2:
0514 lfmt = 3;
0515 break;
0516 default:
0517 return -EINVAL;
0518 }
0519 } else {
0520 lfmt = 1;
0521 }
0522 payload_hdr = (struct pld_hdr *)((&msg->pld_lenfmt) + lfmt);
0523 *fcode = payload_hdr->func_val & 0xFFFF;
0524
0525
0526 if (msg->cprbx.flags & 0x20)
0527 ap_msg->flags |= AP_MSG_FLAG_SPECIAL;
0528
0529 #ifdef CONFIG_ZCRYPT_DEBUG
0530 if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL)
0531 ap_msg->flags ^= AP_MSG_FLAG_SPECIAL;
0532 #endif
0533
0534
0535 if (msg->cprbx.flags & 0x80)
0536 ap_msg->flags |= AP_MSG_FLAG_ADMIN;
0537 else
0538 ap_msg->flags |= AP_MSG_FLAG_USAGE;
0539
0540 *domain = msg->cprbx.target_id;
0541
0542 return 0;
0543 }
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555 struct type86x_reply {
0556 struct type86_hdr hdr;
0557 struct type86_fmt2_ext fmt2;
0558 struct CPRBX cprbx;
0559 unsigned char pad[4];
0560 unsigned short length;
0561 char text[];
0562 } __packed;
0563
0564 struct type86_ep11_reply {
0565 struct type86_hdr hdr;
0566 struct type86_fmt2_ext fmt2;
0567 struct ep11_cprb cprbx;
0568 } __packed;
0569
0570 static int convert_type86_ica(struct zcrypt_queue *zq,
0571 struct ap_message *reply,
0572 char __user *outputdata,
0573 unsigned int outputdatalength)
0574 {
0575 static unsigned char static_pad[] = {
0576 0x00, 0x02,
0577 0x1B, 0x7B, 0x5D, 0xB5, 0x75, 0x01, 0x3D, 0xFD,
0578 0x8D, 0xD1, 0xC7, 0x03, 0x2D, 0x09, 0x23, 0x57,
0579 0x89, 0x49, 0xB9, 0x3F, 0xBB, 0x99, 0x41, 0x5B,
0580 0x75, 0x21, 0x7B, 0x9D, 0x3B, 0x6B, 0x51, 0x39,
0581 0xBB, 0x0D, 0x35, 0xB9, 0x89, 0x0F, 0x93, 0xA5,
0582 0x0B, 0x47, 0xF1, 0xD3, 0xBB, 0xCB, 0xF1, 0x9D,
0583 0x23, 0x73, 0x71, 0xFF, 0xF3, 0xF5, 0x45, 0xFB,
0584 0x61, 0x29, 0x23, 0xFD, 0xF1, 0x29, 0x3F, 0x7F,
0585 0x17, 0xB7, 0x1B, 0xA9, 0x19, 0xBD, 0x57, 0xA9,
0586 0xD7, 0x95, 0xA3, 0xCB, 0xED, 0x1D, 0xDB, 0x45,
0587 0x7D, 0x11, 0xD1, 0x51, 0x1B, 0xED, 0x71, 0xE9,
0588 0xB1, 0xD1, 0xAB, 0xAB, 0x21, 0x2B, 0x1B, 0x9F,
0589 0x3B, 0x9F, 0xF7, 0xF7, 0xBD, 0x63, 0xEB, 0xAD,
0590 0xDF, 0xB3, 0x6F, 0x5B, 0xDB, 0x8D, 0xA9, 0x5D,
0591 0xE3, 0x7D, 0x77, 0x49, 0x47, 0xF5, 0xA7, 0xFD,
0592 0xAB, 0x2F, 0x27, 0x35, 0x77, 0xD3, 0x49, 0xC9,
0593 0x09, 0xEB, 0xB1, 0xF9, 0xBF, 0x4B, 0xCB, 0x2B,
0594 0xEB, 0xEB, 0x05, 0xFF, 0x7D, 0xC7, 0x91, 0x8B,
0595 0x09, 0x83, 0xB9, 0xB9, 0x69, 0x33, 0x39, 0x6B,
0596 0x79, 0x75, 0x19, 0xBF, 0xBB, 0x07, 0x1D, 0xBD,
0597 0x29, 0xBF, 0x39, 0x95, 0x93, 0x1D, 0x35, 0xC7,
0598 0xC9, 0x4D, 0xE5, 0x97, 0x0B, 0x43, 0x9B, 0xF1,
0599 0x16, 0x93, 0x03, 0x1F, 0xA5, 0xFB, 0xDB, 0xF3,
0600 0x27, 0x4F, 0x27, 0x61, 0x05, 0x1F, 0xB9, 0x23,
0601 0x2F, 0xC3, 0x81, 0xA9, 0x23, 0x71, 0x55, 0x55,
0602 0xEB, 0xED, 0x41, 0xE5, 0xF3, 0x11, 0xF1, 0x43,
0603 0x69, 0x03, 0xBD, 0x0B, 0x37, 0x0F, 0x51, 0x8F,
0604 0x0B, 0xB5, 0x89, 0x5B, 0x67, 0xA9, 0xD9, 0x4F,
0605 0x01, 0xF9, 0x21, 0x77, 0x37, 0x73, 0x79, 0xC5,
0606 0x7F, 0x51, 0xC1, 0xCF, 0x97, 0xA1, 0x75, 0xAD,
0607 0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41,
0608 0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09
0609 };
0610 struct type86x_reply *msg = reply->msg;
0611 unsigned short service_rc, service_rs;
0612 unsigned int reply_len, pad_len;
0613 char *data;
0614
0615 service_rc = msg->cprbx.ccp_rtcode;
0616 if (unlikely(service_rc != 0)) {
0617 service_rs = msg->cprbx.ccp_rscode;
0618 if ((service_rc == 8 && service_rs == 66) ||
0619 (service_rc == 8 && service_rs == 65) ||
0620 (service_rc == 8 && service_rs == 72) ||
0621 (service_rc == 8 && service_rs == 770) ||
0622 (service_rc == 12 && service_rs == 769)) {
0623 ZCRYPT_DBF_WARN("%s dev=%02x.%04x rc/rs=%d/%d => rc=EINVAL\n",
0624 __func__, AP_QID_CARD(zq->queue->qid),
0625 AP_QID_QUEUE(zq->queue->qid),
0626 (int)service_rc, (int)service_rs);
0627 return -EINVAL;
0628 }
0629 zq->online = 0;
0630 pr_err("Crypto dev=%02x.%04x rc/rs=%d/%d online=0 rc=EAGAIN\n",
0631 AP_QID_CARD(zq->queue->qid),
0632 AP_QID_QUEUE(zq->queue->qid),
0633 (int)service_rc, (int)service_rs);
0634 ZCRYPT_DBF_ERR("%s dev=%02x.%04x rc/rs=%d/%d => online=0 rc=EAGAIN\n",
0635 __func__, AP_QID_CARD(zq->queue->qid),
0636 AP_QID_QUEUE(zq->queue->qid),
0637 (int)service_rc, (int)service_rs);
0638 ap_send_online_uevent(&zq->queue->ap_dev, zq->online);
0639 return -EAGAIN;
0640 }
0641 data = msg->text;
0642 reply_len = msg->length - 2;
0643 if (reply_len > outputdatalength)
0644 return -EINVAL;
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655 pad_len = outputdatalength - reply_len;
0656 if (pad_len > 0) {
0657 if (pad_len < 10)
0658 return -EINVAL;
0659
0660 if (copy_to_user(outputdata, static_pad, pad_len - 1))
0661 return -EFAULT;
0662 if (put_user(0, outputdata + pad_len - 1))
0663 return -EFAULT;
0664 }
0665
0666 if (copy_to_user(outputdata + pad_len, data, reply_len))
0667 return -EFAULT;
0668 return 0;
0669 }
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680 static int convert_type86_xcrb(bool userspace, struct zcrypt_queue *zq,
0681 struct ap_message *reply,
0682 struct ica_xcRB *xcrb)
0683 {
0684 struct type86_fmt2_msg *msg = reply->msg;
0685 char *data = reply->msg;
0686
0687
0688 if (xcrb->reply_control_blk_length < msg->fmt2.count1) {
0689 ZCRYPT_DBF_DBG("%s reply_control_blk_length %u < required %u => EMSGSIZE\n",
0690 __func__, xcrb->reply_control_blk_length,
0691 msg->fmt2.count1);
0692 return -EMSGSIZE;
0693 }
0694 if (z_copy_to_user(userspace, xcrb->reply_control_blk_addr,
0695 data + msg->fmt2.offset1, msg->fmt2.count1))
0696 return -EFAULT;
0697 xcrb->reply_control_blk_length = msg->fmt2.count1;
0698
0699
0700 if (msg->fmt2.count2) {
0701 if (xcrb->reply_data_length < msg->fmt2.count2) {
0702 ZCRYPT_DBF_DBG("%s reply_data_length %u < required %u => EMSGSIZE\n",
0703 __func__, xcrb->reply_data_length,
0704 msg->fmt2.count2);
0705 return -EMSGSIZE;
0706 }
0707 if (z_copy_to_user(userspace, xcrb->reply_data_addr,
0708 data + msg->fmt2.offset2, msg->fmt2.count2))
0709 return -EFAULT;
0710 }
0711 xcrb->reply_data_length = msg->fmt2.count2;
0712
0713 return 0;
0714 }
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725 static int convert_type86_ep11_xcrb(bool userspace, struct zcrypt_queue *zq,
0726 struct ap_message *reply,
0727 struct ep11_urb *xcrb)
0728 {
0729 struct type86_fmt2_msg *msg = reply->msg;
0730 char *data = reply->msg;
0731
0732 if (xcrb->resp_len < msg->fmt2.count1) {
0733 ZCRYPT_DBF_DBG("%s resp_len %u < required %u => EMSGSIZE\n",
0734 __func__, (unsigned int)xcrb->resp_len,
0735 msg->fmt2.count1);
0736 return -EMSGSIZE;
0737 }
0738
0739
0740 if (z_copy_to_user(userspace, (char __force __user *)xcrb->resp,
0741 data + msg->fmt2.offset1, msg->fmt2.count1))
0742 return -EFAULT;
0743 xcrb->resp_len = msg->fmt2.count1;
0744 return 0;
0745 }
0746
0747 static int convert_type86_rng(struct zcrypt_queue *zq,
0748 struct ap_message *reply,
0749 char *buffer)
0750 {
0751 struct {
0752 struct type86_hdr hdr;
0753 struct type86_fmt2_ext fmt2;
0754 struct CPRBX cprbx;
0755 } __packed * msg = reply->msg;
0756 char *data = reply->msg;
0757
0758 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0)
0759 return -EINVAL;
0760 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2);
0761 return msg->fmt2.count2;
0762 }
0763
0764 static int convert_response_ica(struct zcrypt_queue *zq,
0765 struct ap_message *reply,
0766 char __user *outputdata,
0767 unsigned int outputdatalength)
0768 {
0769 struct type86x_reply *msg = reply->msg;
0770
0771 switch (msg->hdr.type) {
0772 case TYPE82_RSP_CODE:
0773 case TYPE88_RSP_CODE:
0774 return convert_error(zq, reply);
0775 case TYPE86_RSP_CODE:
0776 if (msg->cprbx.ccp_rtcode &&
0777 msg->cprbx.ccp_rscode == 0x14f &&
0778 outputdatalength > 256) {
0779 if (zq->zcard->max_exp_bit_length <= 17) {
0780 zq->zcard->max_exp_bit_length = 17;
0781 return -EAGAIN;
0782 } else {
0783 return -EINVAL;
0784 }
0785 }
0786 if (msg->hdr.reply_code)
0787 return convert_error(zq, reply);
0788 if (msg->cprbx.cprb_ver_id == 0x02)
0789 return convert_type86_ica(zq, reply,
0790 outputdata, outputdatalength);
0791 fallthrough;
0792 default:
0793
0794 zq->online = 0;
0795 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0796 AP_QID_CARD(zq->queue->qid),
0797 AP_QID_QUEUE(zq->queue->qid),
0798 (int)msg->hdr.type);
0799 ZCRYPT_DBF_ERR(
0800 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0801 __func__, AP_QID_CARD(zq->queue->qid),
0802 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type);
0803 ap_send_online_uevent(&zq->queue->ap_dev, zq->online);
0804 return -EAGAIN;
0805 }
0806 }
0807
0808 static int convert_response_xcrb(bool userspace, struct zcrypt_queue *zq,
0809 struct ap_message *reply,
0810 struct ica_xcRB *xcrb)
0811 {
0812 struct type86x_reply *msg = reply->msg;
0813
0814 switch (msg->hdr.type) {
0815 case TYPE82_RSP_CODE:
0816 case TYPE88_RSP_CODE:
0817 xcrb->status = 0x0008044DL;
0818 return convert_error(zq, reply);
0819 case TYPE86_RSP_CODE:
0820 if (msg->hdr.reply_code) {
0821 memcpy(&xcrb->status, msg->fmt2.apfs, sizeof(u32));
0822 return convert_error(zq, reply);
0823 }
0824 if (msg->cprbx.cprb_ver_id == 0x02)
0825 return convert_type86_xcrb(userspace, zq, reply, xcrb);
0826 fallthrough;
0827 default:
0828 xcrb->status = 0x0008044DL;
0829 zq->online = 0;
0830 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0831 AP_QID_CARD(zq->queue->qid),
0832 AP_QID_QUEUE(zq->queue->qid),
0833 (int)msg->hdr.type);
0834 ZCRYPT_DBF_ERR(
0835 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0836 __func__, AP_QID_CARD(zq->queue->qid),
0837 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type);
0838 ap_send_online_uevent(&zq->queue->ap_dev, zq->online);
0839 return -EAGAIN;
0840 }
0841 }
0842
0843 static int convert_response_ep11_xcrb(bool userspace, struct zcrypt_queue *zq,
0844 struct ap_message *reply, struct ep11_urb *xcrb)
0845 {
0846 struct type86_ep11_reply *msg = reply->msg;
0847
0848 switch (msg->hdr.type) {
0849 case TYPE82_RSP_CODE:
0850 case TYPE87_RSP_CODE:
0851 return convert_error(zq, reply);
0852 case TYPE86_RSP_CODE:
0853 if (msg->hdr.reply_code)
0854 return convert_error(zq, reply);
0855 if (msg->cprbx.cprb_ver_id == 0x04)
0856 return convert_type86_ep11_xcrb(userspace, zq, reply, xcrb);
0857 fallthrough;
0858 default:
0859 zq->online = 0;
0860 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0861 AP_QID_CARD(zq->queue->qid),
0862 AP_QID_QUEUE(zq->queue->qid),
0863 (int)msg->hdr.type);
0864 ZCRYPT_DBF_ERR(
0865 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0866 __func__, AP_QID_CARD(zq->queue->qid),
0867 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type);
0868 ap_send_online_uevent(&zq->queue->ap_dev, zq->online);
0869 return -EAGAIN;
0870 }
0871 }
0872
0873 static int convert_response_rng(struct zcrypt_queue *zq,
0874 struct ap_message *reply,
0875 char *data)
0876 {
0877 struct type86x_reply *msg = reply->msg;
0878
0879 switch (msg->hdr.type) {
0880 case TYPE82_RSP_CODE:
0881 case TYPE88_RSP_CODE:
0882 return -EINVAL;
0883 case TYPE86_RSP_CODE:
0884 if (msg->hdr.reply_code)
0885 return -EINVAL;
0886 if (msg->cprbx.cprb_ver_id == 0x02)
0887 return convert_type86_rng(zq, reply, data);
0888 fallthrough;
0889 default:
0890 zq->online = 0;
0891 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0892 AP_QID_CARD(zq->queue->qid),
0893 AP_QID_QUEUE(zq->queue->qid),
0894 (int)msg->hdr.type);
0895 ZCRYPT_DBF_ERR(
0896 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
0897 __func__, AP_QID_CARD(zq->queue->qid),
0898 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type);
0899 ap_send_online_uevent(&zq->queue->ap_dev, zq->online);
0900 return -EAGAIN;
0901 }
0902 }
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912 static void zcrypt_msgtype6_receive(struct ap_queue *aq,
0913 struct ap_message *msg,
0914 struct ap_message *reply)
0915 {
0916 static struct error_hdr error_reply = {
0917 .type = TYPE82_RSP_CODE,
0918 .reply_code = REP82_ERROR_MACHINE_FAILURE,
0919 };
0920 struct response_type *resp_type =
0921 (struct response_type *)msg->private;
0922 struct type86x_reply *t86r;
0923 int len;
0924
0925
0926 if (!reply)
0927 goto out;
0928 t86r = reply->msg;
0929 if (t86r->hdr.type == TYPE86_RSP_CODE &&
0930 t86r->cprbx.cprb_ver_id == 0x02) {
0931 switch (resp_type->type) {
0932 case CEXXC_RESPONSE_TYPE_ICA:
0933 len = sizeof(struct type86x_reply) + t86r->length - 2;
0934 if (len > reply->bufsize || len > msg->bufsize) {
0935 msg->rc = -EMSGSIZE;
0936 } else {
0937 memcpy(msg->msg, reply->msg, len);
0938 msg->len = len;
0939 }
0940 break;
0941 case CEXXC_RESPONSE_TYPE_XCRB:
0942 len = t86r->fmt2.offset2 + t86r->fmt2.count2;
0943 if (len > reply->bufsize || len > msg->bufsize) {
0944 msg->rc = -EMSGSIZE;
0945 } else {
0946 memcpy(msg->msg, reply->msg, len);
0947 msg->len = len;
0948 }
0949 break;
0950 default:
0951 memcpy(msg->msg, &error_reply, sizeof(error_reply));
0952 }
0953 } else {
0954 memcpy(msg->msg, reply->msg, sizeof(error_reply));
0955 }
0956 out:
0957 complete(&resp_type->work);
0958 }
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968 static void zcrypt_msgtype6_receive_ep11(struct ap_queue *aq,
0969 struct ap_message *msg,
0970 struct ap_message *reply)
0971 {
0972 static struct error_hdr error_reply = {
0973 .type = TYPE82_RSP_CODE,
0974 .reply_code = REP82_ERROR_MACHINE_FAILURE,
0975 };
0976 struct response_type *resp_type =
0977 (struct response_type *)msg->private;
0978 struct type86_ep11_reply *t86r;
0979 int len;
0980
0981
0982 if (!reply)
0983 goto out;
0984 t86r = reply->msg;
0985 if (t86r->hdr.type == TYPE86_RSP_CODE &&
0986 t86r->cprbx.cprb_ver_id == 0x04) {
0987 switch (resp_type->type) {
0988 case CEXXC_RESPONSE_TYPE_EP11:
0989 len = t86r->fmt2.offset1 + t86r->fmt2.count1;
0990 if (len > reply->bufsize || len > msg->bufsize) {
0991 msg->rc = -EMSGSIZE;
0992 } else {
0993 memcpy(msg->msg, reply->msg, len);
0994 msg->len = len;
0995 }
0996 break;
0997 default:
0998 memcpy(msg->msg, &error_reply, sizeof(error_reply));
0999 }
1000 } else {
1001 memcpy(msg->msg, reply->msg, sizeof(error_reply));
1002 }
1003 out:
1004 complete(&resp_type->work);
1005 }
1006
1007 static atomic_t zcrypt_step = ATOMIC_INIT(0);
1008
1009
1010
1011
1012
1013
1014
1015
1016 static long zcrypt_msgtype6_modexpo(struct zcrypt_queue *zq,
1017 struct ica_rsa_modexpo *mex,
1018 struct ap_message *ap_msg)
1019 {
1020 struct response_type resp_type = {
1021 .type = CEXXC_RESPONSE_TYPE_ICA,
1022 };
1023 int rc;
1024
1025 ap_msg->msg = (void *)get_zeroed_page(GFP_KERNEL);
1026 if (!ap_msg->msg)
1027 return -ENOMEM;
1028 ap_msg->bufsize = PAGE_SIZE;
1029 ap_msg->receive = zcrypt_msgtype6_receive;
1030 ap_msg->psmid = (((unsigned long long)current->pid) << 32) +
1031 atomic_inc_return(&zcrypt_step);
1032 ap_msg->private = &resp_type;
1033 rc = icamex_msg_to_type6mex_msgx(zq, ap_msg, mex);
1034 if (rc)
1035 goto out_free;
1036 init_completion(&resp_type.work);
1037 rc = ap_queue_message(zq->queue, ap_msg);
1038 if (rc)
1039 goto out_free;
1040 rc = wait_for_completion_interruptible(&resp_type.work);
1041 if (rc == 0) {
1042 rc = ap_msg->rc;
1043 if (rc == 0)
1044 rc = convert_response_ica(zq, ap_msg,
1045 mex->outputdata,
1046 mex->outputdatalength);
1047 } else {
1048
1049 ap_cancel_message(zq->queue, ap_msg);
1050 }
1051
1052 out_free:
1053 free_page((unsigned long)ap_msg->msg);
1054 ap_msg->private = NULL;
1055 ap_msg->msg = NULL;
1056 return rc;
1057 }
1058
1059
1060
1061
1062
1063
1064
1065
1066 static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq,
1067 struct ica_rsa_modexpo_crt *crt,
1068 struct ap_message *ap_msg)
1069 {
1070 struct response_type resp_type = {
1071 .type = CEXXC_RESPONSE_TYPE_ICA,
1072 };
1073 int rc;
1074
1075 ap_msg->msg = (void *)get_zeroed_page(GFP_KERNEL);
1076 if (!ap_msg->msg)
1077 return -ENOMEM;
1078 ap_msg->bufsize = PAGE_SIZE;
1079 ap_msg->receive = zcrypt_msgtype6_receive;
1080 ap_msg->psmid = (((unsigned long long)current->pid) << 32) +
1081 atomic_inc_return(&zcrypt_step);
1082 ap_msg->private = &resp_type;
1083 rc = icacrt_msg_to_type6crt_msgx(zq, ap_msg, crt);
1084 if (rc)
1085 goto out_free;
1086 init_completion(&resp_type.work);
1087 rc = ap_queue_message(zq->queue, ap_msg);
1088 if (rc)
1089 goto out_free;
1090 rc = wait_for_completion_interruptible(&resp_type.work);
1091 if (rc == 0) {
1092 rc = ap_msg->rc;
1093 if (rc == 0)
1094 rc = convert_response_ica(zq, ap_msg,
1095 crt->outputdata,
1096 crt->outputdatalength);
1097 } else {
1098
1099 ap_cancel_message(zq->queue, ap_msg);
1100 }
1101
1102 out_free:
1103 free_page((unsigned long)ap_msg->msg);
1104 ap_msg->private = NULL;
1105 ap_msg->msg = NULL;
1106 return rc;
1107 }
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118 int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb,
1119 struct ap_message *ap_msg,
1120 unsigned int *func_code, unsigned short **dom)
1121 {
1122 struct response_type resp_type = {
1123 .type = CEXXC_RESPONSE_TYPE_XCRB,
1124 };
1125
1126 ap_msg->bufsize = atomic_read(&ap_max_msg_size);
1127 ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
1128 if (!ap_msg->msg)
1129 return -ENOMEM;
1130 ap_msg->receive = zcrypt_msgtype6_receive;
1131 ap_msg->psmid = (((unsigned long long)current->pid) << 32) +
1132 atomic_inc_return(&zcrypt_step);
1133 ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL);
1134 if (!ap_msg->private)
1135 return -ENOMEM;
1136 return xcrb_msg_to_type6cprb_msgx(userspace, ap_msg, xcrb, func_code, dom);
1137 }
1138
1139
1140
1141
1142
1143
1144
1145
1146 static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq,
1147 struct ica_xcRB *xcrb,
1148 struct ap_message *ap_msg)
1149 {
1150 int rc;
1151 struct response_type *rtype = (struct response_type *)(ap_msg->private);
1152 struct {
1153 struct type6_hdr hdr;
1154 struct CPRBX cprbx;
1155
1156 } __packed * msg = ap_msg->msg;
1157
1158
1159
1160
1161
1162 msg->hdr.fromcardlen1 = min_t(unsigned int, msg->hdr.fromcardlen1,
1163 zq->reply.bufsize - 128);
1164 if (msg->hdr.fromcardlen2)
1165 msg->hdr.fromcardlen2 =
1166 zq->reply.bufsize - msg->hdr.fromcardlen1 - 128;
1167
1168 init_completion(&rtype->work);
1169 rc = ap_queue_message(zq->queue, ap_msg);
1170 if (rc)
1171 goto out;
1172 rc = wait_for_completion_interruptible(&rtype->work);
1173 if (rc == 0) {
1174 rc = ap_msg->rc;
1175 if (rc == 0)
1176 rc = convert_response_xcrb(userspace, zq, ap_msg, xcrb);
1177 } else {
1178
1179 ap_cancel_message(zq->queue, ap_msg);
1180 }
1181
1182 out:
1183 if (rc)
1184 ZCRYPT_DBF_DBG("%s send cprb at dev=%02x.%04x rc=%d\n",
1185 __func__, AP_QID_CARD(zq->queue->qid),
1186 AP_QID_QUEUE(zq->queue->qid), rc);
1187 return rc;
1188 }
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199 int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb,
1200 struct ap_message *ap_msg,
1201 unsigned int *func_code, unsigned int *domain)
1202 {
1203 struct response_type resp_type = {
1204 .type = CEXXC_RESPONSE_TYPE_EP11,
1205 };
1206
1207 ap_msg->bufsize = atomic_read(&ap_max_msg_size);
1208 ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
1209 if (!ap_msg->msg)
1210 return -ENOMEM;
1211 ap_msg->receive = zcrypt_msgtype6_receive_ep11;
1212 ap_msg->psmid = (((unsigned long long)current->pid) << 32) +
1213 atomic_inc_return(&zcrypt_step);
1214 ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL);
1215 if (!ap_msg->private)
1216 return -ENOMEM;
1217 return xcrb_msg_to_type6_ep11cprb_msgx(userspace, ap_msg, xcrb,
1218 func_code, domain);
1219 }
1220
1221
1222
1223
1224
1225
1226
1227
1228 static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *zq,
1229 struct ep11_urb *xcrb,
1230 struct ap_message *ap_msg)
1231 {
1232 int rc;
1233 unsigned int lfmt;
1234 struct response_type *rtype = (struct response_type *)(ap_msg->private);
1235 struct {
1236 struct type6_hdr hdr;
1237 struct ep11_cprb cprbx;
1238 unsigned char pld_tag;
1239 unsigned char pld_lenfmt;
1240 } __packed * msg = ap_msg->msg;
1241 struct pld_hdr {
1242 unsigned char func_tag;
1243 unsigned char func_len;
1244 unsigned int func_val;
1245 unsigned char dom_tag;
1246 unsigned char dom_len;
1247 unsigned int dom_val;
1248 } __packed * payload_hdr = NULL;
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258 if (!((msg->cprbx.flags & 0x80) == 0x80)) {
1259 msg->cprbx.target_id = (unsigned int)
1260 AP_QID_QUEUE(zq->queue->qid);
1261
1262 if ((msg->pld_lenfmt & 0x80) == 0x80) {
1263 switch (msg->pld_lenfmt & 0x03) {
1264 case 1:
1265 lfmt = 2;
1266 break;
1267 case 2:
1268 lfmt = 3;
1269 break;
1270 default:
1271 return -EINVAL;
1272 }
1273 } else {
1274 lfmt = 1;
1275 }
1276 payload_hdr = (struct pld_hdr *)((&msg->pld_lenfmt) + lfmt);
1277 payload_hdr->dom_val = (unsigned int)
1278 AP_QID_QUEUE(zq->queue->qid);
1279 }
1280
1281
1282
1283
1284
1285 msg->hdr.fromcardlen1 = zq->reply.bufsize -
1286 sizeof(struct type86_hdr) - sizeof(struct type86_fmt2_ext);
1287
1288 init_completion(&rtype->work);
1289 rc = ap_queue_message(zq->queue, ap_msg);
1290 if (rc)
1291 goto out;
1292 rc = wait_for_completion_interruptible(&rtype->work);
1293 if (rc == 0) {
1294 rc = ap_msg->rc;
1295 if (rc == 0)
1296 rc = convert_response_ep11_xcrb(userspace, zq, ap_msg, xcrb);
1297 } else {
1298
1299 ap_cancel_message(zq->queue, ap_msg);
1300 }
1301
1302 out:
1303 if (rc)
1304 ZCRYPT_DBF_DBG("%s send cprb at dev=%02x.%04x rc=%d\n",
1305 __func__, AP_QID_CARD(zq->queue->qid),
1306 AP_QID_QUEUE(zq->queue->qid), rc);
1307 return rc;
1308 }
1309
1310 int prep_rng_ap_msg(struct ap_message *ap_msg, int *func_code,
1311 unsigned int *domain)
1312 {
1313 struct response_type resp_type = {
1314 .type = CEXXC_RESPONSE_TYPE_XCRB,
1315 };
1316
1317 ap_msg->bufsize = AP_DEFAULT_MAX_MSG_SIZE;
1318 ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL);
1319 if (!ap_msg->msg)
1320 return -ENOMEM;
1321 ap_msg->receive = zcrypt_msgtype6_receive;
1322 ap_msg->psmid = (((unsigned long long)current->pid) << 32) +
1323 atomic_inc_return(&zcrypt_step);
1324 ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL);
1325 if (!ap_msg->private)
1326 return -ENOMEM;
1327
1328 rng_type6cprb_msgx(ap_msg, ZCRYPT_RNG_BUFFER_SIZE, domain);
1329
1330 *func_code = HWRNG;
1331 return 0;
1332 }
1333
1334
1335
1336
1337
1338
1339
1340
1341 static long zcrypt_msgtype6_rng(struct zcrypt_queue *zq,
1342 char *buffer, struct ap_message *ap_msg)
1343 {
1344 struct {
1345 struct type6_hdr hdr;
1346 struct CPRBX cprbx;
1347 char function_code[2];
1348 short int rule_length;
1349 char rule[8];
1350 short int verb_length;
1351 short int key_length;
1352 } __packed * msg = ap_msg->msg;
1353 struct response_type *rtype = (struct response_type *)(ap_msg->private);
1354 int rc;
1355
1356 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid);
1357
1358 init_completion(&rtype->work);
1359 rc = ap_queue_message(zq->queue, ap_msg);
1360 if (rc)
1361 goto out;
1362 rc = wait_for_completion_interruptible(&rtype->work);
1363 if (rc == 0) {
1364 rc = ap_msg->rc;
1365 if (rc == 0)
1366 rc = convert_response_rng(zq, ap_msg, buffer);
1367 } else {
1368
1369 ap_cancel_message(zq->queue, ap_msg);
1370 }
1371 out:
1372 return rc;
1373 }
1374
1375
1376
1377
1378 static struct zcrypt_ops zcrypt_msgtype6_norng_ops = {
1379 .owner = THIS_MODULE,
1380 .name = MSGTYPE06_NAME,
1381 .variant = MSGTYPE06_VARIANT_NORNG,
1382 .rsa_modexpo = zcrypt_msgtype6_modexpo,
1383 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1384 .send_cprb = zcrypt_msgtype6_send_cprb,
1385 };
1386
1387 static struct zcrypt_ops zcrypt_msgtype6_ops = {
1388 .owner = THIS_MODULE,
1389 .name = MSGTYPE06_NAME,
1390 .variant = MSGTYPE06_VARIANT_DEFAULT,
1391 .rsa_modexpo = zcrypt_msgtype6_modexpo,
1392 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt,
1393 .send_cprb = zcrypt_msgtype6_send_cprb,
1394 .rng = zcrypt_msgtype6_rng,
1395 };
1396
1397 static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = {
1398 .owner = THIS_MODULE,
1399 .name = MSGTYPE06_NAME,
1400 .variant = MSGTYPE06_VARIANT_EP11,
1401 .rsa_modexpo = NULL,
1402 .rsa_modexpo_crt = NULL,
1403 .send_ep11_cprb = zcrypt_msgtype6_send_ep11_cprb,
1404 };
1405
1406 void __init zcrypt_msgtype6_init(void)
1407 {
1408 zcrypt_msgtype_register(&zcrypt_msgtype6_norng_ops);
1409 zcrypt_msgtype_register(&zcrypt_msgtype6_ops);
1410 zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops);
1411 }
1412
1413 void __exit zcrypt_msgtype6_exit(void)
1414 {
1415 zcrypt_msgtype_unregister(&zcrypt_msgtype6_norng_ops);
1416 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops);
1417 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops);
1418 }