FILE
zcrypt_msgtype6.c
File preview with syntax highlighting.
linux-6.19.14/drivers/s390/crypto/zcrypt_msgtype6.c
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright IBM Corp. 2001, 2023 4 * Author(s): Robert Burroughs 5 * Eric Rossman (edrossma@us.ibm.com) 6 * 7 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 8 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 9 * Ralph Wuerthner <rwuerthn@de.ibm.com> 10 * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 11 */ 12 13#define pr_fmt(fmt) "zcrypt: " fmt 14 15#include <linux/module.h> 16#include <linux/init.h> 17#include <linux/err.h> 18#include <linux/delay.h> 19#include <linux/slab.h> 20#include <linux/atomic.h> 21#include <linux/uaccess.h> 22 23#include "ap_bus.h" 24#include "zcrypt_api.h" 25#include "zcrypt_error.h" 26#include "zcrypt_msgtype6.h" 27#include "zcrypt_cca_key.h" 28 29#define CEXXC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ 30 31#define CEIL4(x) ((((x) + 3) / 4) * 4) 32 33#define CEXXC_RESPONSE_TYPE_ICA 0 34#define CEXXC_RESPONSE_TYPE_XCRB 1 35#define CEXXC_RESPONSE_TYPE_EP11 2 36 37MODULE_AUTHOR("IBM Corporation"); 38MODULE_DESCRIPTION("Cryptographic Coprocessor (message type 6), " \ 39 "Copyright IBM Corp. 2001, 2023"); 40MODULE_LICENSE("GPL"); 41 42struct function_and_rules_block { 43 unsigned char function_code[2]; 44 unsigned short ulen; 45 unsigned char only_rule[8]; 46} __packed; 47 48/* 49 * The following is used to initialize the CPRBX passed to the CEXxC/CEXxP 50 * card in a type6 message. The 3 fields that must be filled in at execution 51 * time are req_parml, rpl_parml and usage_domain. 52 * Everything about this interface is ascii/big-endian, since the 53 * device does *not* have 'Intel inside'. 54 * 55 * The CPRBX is followed immediately by the parm block. 56 * The parm block contains: 57 * - function code ('PD' 0x5044 or 'PK' 0x504B) 58 * - rule block (one of:) 59 * + 0x000A 'PKCS-1.2' (MCL2 'PD') 60 * + 0x000A 'ZERO-PAD' (MCL2 'PK') 61 * + 0x000A 'ZERO-PAD' (MCL3 'PD' or CEX2C 'PD') 62 * + 0x000A 'MRP ' (MCL3 'PK' or CEX2C 'PK') 63 * - VUD block 64 */ 65static const struct CPRBX static_cprbx = { 66 .cprb_len = 0x00DC, 67 .cprb_ver_id = 0x02, 68 .func_id = {0x54, 0x32}, 69}; 70 71int speed_idx_cca(int req_type) 72{ 73 switch (req_type) { 74 case 0x4142: 75 case 0x4149: 76 case 0x414D: 77 case 0x4341: 78 case 0x4344: 79 case 0x4354: 80 case 0x4358: 81 case 0x444B: 82 case 0x4558: 83 case 0x4643: 84 case 0x4651: 85 case 0x4C47: 86 case 0x4C4B: 87 case 0x4C51: 88 case 0x4F48: 89 case 0x504F: 90 case 0x5053: 91 case 0x5058: 92 case 0x5343: 93 case 0x5344: 94 case 0x5345: 95 case 0x5350: 96 return LOW; 97 case 0x414B: 98 case 0x4345: 99 case 0x4349: 100 case 0x434D: 101 case 0x4847: 102 case 0x4849: 103 case 0x484D: 104 case 0x4850: 105 case 0x4851: 106 case 0x4954: 107 case 0x4958: 108 case 0x4B43: 109 case 0x4B44: 110 case 0x4B45: 111 case 0x4B47: 112 case 0x4B48: 113 case 0x4B49: 114 case 0x4B4E: 115 case 0x4B50: 116 case 0x4B52: 117 case 0x4B54: 118 case 0x4B58: 119 case 0x4D50: 120 case 0x4D53: 121 case 0x4D56: 122 case 0x4D58: 123 case 0x5044: 124 case 0x5045: 125 case 0x5046: 126 case 0x5047: 127 case 0x5049: 128 case 0x504B: 129 case 0x504D: 130 case 0x5254: 131 case 0x5347: 132 case 0x5349: 133 case 0x534B: 134 case 0x534D: 135 case 0x5356: 136 case 0x5358: 137 case 0x5443: 138 case 0x544B: 139 case 0x5647: 140 return HIGH; 141 default: 142 return MEDIUM; 143 } 144} 145 146int speed_idx_ep11(int req_type) 147{ 148 switch (req_type) { 149 case 1: 150 case 2: 151 case 36: 152 case 37: 153 case 38: 154 case 39: 155 case 40: 156 return LOW; 157 case 17: 158 case 18: 159 case 19: 160 case 20: 161 case 21: 162 case 22: 163 case 26: 164 case 30: 165 case 31: 166 case 32: 167 case 33: 168 case 34: 169 case 35: 170 return HIGH; 171 default: 172 return MEDIUM; 173 } 174} 175 176/* 177 * Convert a ICAMEX message to a type6 MEX message. 178 * 179 * @zq: crypto device pointer 180 * @ap_msg: pointer to AP message 181 * @mex: pointer to user input data 182 * 183 * Returns 0 on success or negative errno value. 184 */ 185static int icamex_msg_to_type6mex_msgx(struct zcrypt_queue *zq, 186 struct ap_message *ap_msg, 187 struct ica_rsa_modexpo *mex) 188{ 189 static struct type6_hdr static_type6_hdrX = { 190 .type = 0x06, 191 .offset1 = 0x00000058, 192 .agent_id = {'C', 'A',}, 193 .function_code = {'P', 'K'}, 194 }; 195 static struct function_and_rules_block static_pke_fnr = { 196 .function_code = {'P', 'K'}, 197 .ulen = 10, 198 .only_rule = {'M', 'R', 'P', ' ', ' ', ' ', ' ', ' '} 199 }; 200 struct { 201 struct type6_hdr hdr; 202 struct CPRBX cprbx; 203 struct function_and_rules_block fr; 204 unsigned short length; 205 char text[]; 206 } __packed * msg = ap_msg->msg; 207 int size; 208 209 /* 210 * The inputdatalength was a selection criteria in the dispatching 211 * function zcrypt_rsa_modexpo(). However, make sure the following 212 * copy_from_user() never exceeds the allocated buffer space. 213 */ 214 if (WARN_ON_ONCE(mex->inputdatalength > PAGE_SIZE)) 215 return -EINVAL; 216 217 /* VUD.ciphertext */ 218 msg->length = mex->inputdatalength + 2; 219 if (copy_from_user(msg->text, mex->inputdata, mex->inputdatalength)) 220 return -EFAULT; 221 222 /* Set up key which is located after the variable length text. */ 223 size = zcrypt_type6_mex_key_en(mex, msg->text + mex->inputdatalength); 224 if (size < 0) 225 return size; 226 size += sizeof(*msg) + mex->inputdatalength; 227 228 /* message header, cprbx and f&r */ 229 msg->hdr = static_type6_hdrX; 230 msg->hdr.tocardlen1 = size - sizeof(msg->hdr); 231 msg->hdr.fromcardlen1 = CEXXC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr); 232 233 msg->cprbx = static_cprbx; 234 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid); 235 msg->cprbx.rpl_msgbl = msg->hdr.fromcardlen1; 236 237 msg->fr = static_pke_fnr; 238 239 msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx); 240 241 ap_msg->len = size; 242 return 0; 243} 244 245/* 246 * Convert a ICACRT message to a type6 CRT message. 247 * 248 * @zq: crypto device pointer 249 * @ap_msg: pointer to AP message 250 * @crt: pointer to user input data 251 * 252 * Returns 0 on success or negative errno value. 253 */ 254static int icacrt_msg_to_type6crt_msgx(struct zcrypt_queue *zq, 255 struct ap_message *ap_msg, 256 struct ica_rsa_modexpo_crt *crt) 257{ 258 static struct type6_hdr static_type6_hdrX = { 259 .type = 0x06, 260 .offset1 = 0x00000058, 261 .agent_id = {'C', 'A',}, 262 .function_code = {'P', 'D'}, 263 }; 264 static struct function_and_rules_block static_pkd_fnr = { 265 .function_code = {'P', 'D'}, 266 .ulen = 10, 267 .only_rule = {'Z', 'E', 'R', 'O', '-', 'P', 'A', 'D'} 268 }; 269 270 struct { 271 struct type6_hdr hdr; 272 struct CPRBX cprbx; 273 struct function_and_rules_block fr; 274 unsigned short length; 275 char text[]; 276 } __packed * msg = ap_msg->msg; 277 int size; 278 279 /* 280 * The inputdatalength was a selection criteria in the dispatching 281 * function zcrypt_rsa_crt(). However, make sure the following 282 * copy_from_user() never exceeds the allocated buffer space. 283 */ 284 if (WARN_ON_ONCE(crt->inputdatalength > PAGE_SIZE)) 285 return -EINVAL; 286 287 /* VUD.ciphertext */ 288 msg->length = crt->inputdatalength + 2; 289 if (copy_from_user(msg->text, crt->inputdata, crt->inputdatalength)) 290 return -EFAULT; 291 292 /* Set up key which is located after the variable length text. */ 293 size = zcrypt_type6_crt_key(crt, msg->text + crt->inputdatalength); 294 if (size < 0) 295 return size; 296 size += sizeof(*msg) + crt->inputdatalength; /* total size of msg */ 297 298 /* message header, cprbx and f&r */ 299 msg->hdr = static_type6_hdrX; 300 msg->hdr.tocardlen1 = size - sizeof(msg->hdr); 301 msg->hdr.fromcardlen1 = CEXXC_MAX_ICA_RESPONSE_SIZE - sizeof(msg->hdr); 302 303 msg->cprbx = static_cprbx; 304 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid); 305 msg->cprbx.req_parml = msg->cprbx.rpl_msgbl = 306 size - sizeof(msg->hdr) - sizeof(msg->cprbx); 307 308 msg->fr = static_pkd_fnr; 309 310 ap_msg->len = size; 311 return 0; 312} 313 314/* 315 * Convert a XCRB message to a type6 CPRB message. 316 * 317 * @zq: crypto device pointer 318 * @ap_msg: pointer to AP message 319 * @xcRB: pointer to user input data 320 * 321 * Returns 0 on success or -EFAULT, -EINVAL. 322 */ 323struct type86_fmt2_msg { 324 struct type86_hdr hdr; 325 struct type86_fmt2_ext fmt2; 326} __packed; 327 328static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg, 329 struct ica_xcRB *xcrb, 330 unsigned int *fcode, 331 unsigned short **dom) 332{ 333 static struct type6_hdr static_type6_hdrX = { 334 .type = 0x06, 335 .offset1 = 0x00000058, 336 }; 337 struct { 338 struct type6_hdr hdr; 339 union { 340 struct CPRBX cprbx; 341 DECLARE_FLEX_ARRAY(u8, userdata); 342 }; 343 } __packed * msg = ap_msg->msg; 344 345 int rcblen = CEIL4(xcrb->request_control_blk_length); 346 int req_sumlen, resp_sumlen; 347 char *req_data = ap_msg->msg + sizeof(struct type6_hdr) + rcblen; 348 char *function_code; 349 350 if (CEIL4(xcrb->request_control_blk_length) < 351 xcrb->request_control_blk_length) 352 return -EINVAL; /* overflow after alignment*/ 353 354 /* length checks */ 355 ap_msg->len = sizeof(struct type6_hdr) + 356 CEIL4(xcrb->request_control_blk_length) + 357 xcrb->request_data_length; 358 if (ap_msg->len > ap_msg->bufsize) 359 return -EINVAL; 360 361 /* 362 * Overflow check 363 * sum must be greater (or equal) than the largest operand 364 */ 365 req_sumlen = CEIL4(xcrb->request_control_blk_length) + 366 xcrb->request_data_length; 367 if ((CEIL4(xcrb->request_control_blk_length) <= 368 xcrb->request_data_length) ? 369 req_sumlen < xcrb->request_data_length : 370 req_sumlen < CEIL4(xcrb->request_control_blk_length)) { 371 return -EINVAL; 372 } 373 374 if (CEIL4(xcrb->reply_control_blk_length) < 375 xcrb->reply_control_blk_length) 376 return -EINVAL; /* overflow after alignment*/ 377 378 /* 379 * Overflow check 380 * sum must be greater (or equal) than the largest operand 381 */ 382 resp_sumlen = CEIL4(xcrb->reply_control_blk_length) + 383 xcrb->reply_data_length; 384 if ((CEIL4(xcrb->reply_control_blk_length) <= 385 xcrb->reply_data_length) ? 386 resp_sumlen < xcrb->reply_data_length : 387 resp_sumlen < CEIL4(xcrb->reply_control_blk_length)) { 388 return -EINVAL; 389 } 390 391 /* prepare type6 header */ 392 msg->hdr = static_type6_hdrX; 393 memcpy(msg->hdr.agent_id, &xcrb->agent_ID, sizeof(xcrb->agent_ID)); 394 msg->hdr.tocardlen1 = xcrb->request_control_blk_length; 395 if (xcrb->request_data_length) { 396 msg->hdr.offset2 = msg->hdr.offset1 + rcblen; 397 msg->hdr.tocardlen2 = xcrb->request_data_length; 398 } 399 msg->hdr.fromcardlen1 = xcrb->reply_control_blk_length; 400 msg->hdr.fromcardlen2 = xcrb->reply_data_length; 401 402 /* prepare CPRB */ 403 if (z_copy_from_user(userspace, msg->userdata, 404 xcrb->request_control_blk_addr, 405 xcrb->request_control_blk_length)) 406 return -EFAULT; 407 if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > 408 xcrb->request_control_blk_length) 409 return -EINVAL; 410 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; 411 memcpy(msg->hdr.function_code, function_code, 412 sizeof(msg->hdr.function_code)); 413 414 *fcode = (msg->hdr.function_code[0] << 8) | msg->hdr.function_code[1]; 415 *dom = (unsigned short *)&msg->cprbx.domain; 416 417 /* check subfunction, US and AU need special flag with NQAP */ 418 if (memcmp(function_code, "US", 2) == 0 || 419 memcmp(function_code, "AU", 2) == 0) 420 ap_msg->flags |= AP_MSG_FLAG_SPECIAL; 421 422 /* check CPRB minor version, set info bits in ap_message flag field */ 423 switch (*(unsigned short *)(&msg->cprbx.func_id[0])) { 424 case 0x5432: /* "T2" */ 425 ap_msg->flags |= AP_MSG_FLAG_USAGE; 426 break; 427 case 0x5433: /* "T3" */ 428 case 0x5435: /* "T5" */ 429 case 0x5436: /* "T6" */ 430 case 0x5437: /* "T7" */ 431 ap_msg->flags |= AP_MSG_FLAG_ADMIN; 432 break; 433 default: 434 pr_debug("unknown CPRB minor version '%c%c'\n", 435 msg->cprbx.func_id[0], msg->cprbx.func_id[1]); 436 } 437 438 /* copy data block */ 439 if (xcrb->request_data_length && 440 z_copy_from_user(userspace, req_data, xcrb->request_data_address, 441 xcrb->request_data_length)) 442 return -EFAULT; 443 444 return 0; 445} 446 447static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap_msg, 448 struct ep11_urb *xcrb, 449 unsigned int *fcode, 450 unsigned int *domain) 451{ 452 unsigned int lfmt; 453 static struct type6_hdr static_type6_ep11_hdr = { 454 .type = 0x06, 455 .rqid = {0x00, 0x01}, 456 .function_code = {0x00, 0x00}, 457 .agent_id[0] = 0x58, /* {'X'} */ 458 .agent_id[1] = 0x43, /* {'C'} */ 459 .offset1 = 0x00000058, 460 }; 461 462 struct { 463 struct type6_hdr hdr; 464 union { 465 struct { 466 struct ep11_cprb cprbx; 467 unsigned char pld_tag; /* fixed value 0x30 */ 468 unsigned char pld_lenfmt; /* length format */ 469 } __packed; 470 DECLARE_FLEX_ARRAY(u8, userdata); 471 }; 472 } __packed * msg = ap_msg->msg; 473 474 struct pld_hdr { 475 unsigned char func_tag; /* fixed value 0x4 */ 476 unsigned char func_len; /* fixed value 0x4 */ 477 unsigned int func_val; /* function ID */ 478 unsigned char dom_tag; /* fixed value 0x4 */ 479 unsigned char dom_len; /* fixed value 0x4 */ 480 unsigned int dom_val; /* domain id */ 481 } __packed * payload_hdr = NULL; 482 483 if (CEIL4(xcrb->req_len) < xcrb->req_len) 484 return -EINVAL; /* overflow after alignment*/ 485 486 /* length checks */ 487 ap_msg->len = sizeof(struct type6_hdr) + CEIL4(xcrb->req_len); 488 if (ap_msg->len > ap_msg->bufsize) 489 return -EINVAL; 490 491 if (CEIL4(xcrb->resp_len) < xcrb->resp_len) 492 return -EINVAL; /* overflow after alignment*/ 493 494 /* prepare type6 header */ 495 msg->hdr = static_type6_ep11_hdr; 496 msg->hdr.tocardlen1 = xcrb->req_len; 497 msg->hdr.fromcardlen1 = xcrb->resp_len; 498 499 /* Import CPRB data from the ioctl input parameter */ 500 if (z_copy_from_user(userspace, msg->userdata, 501 (char __force __user *)xcrb->req, xcrb->req_len)) { 502 return -EFAULT; 503 } 504 505 if ((msg->pld_lenfmt & 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/ 506 switch (msg->pld_lenfmt & 0x03) { 507 case 1: 508 lfmt = 2; 509 break; 510 case 2: 511 lfmt = 3; 512 break; 513 default: 514 return -EINVAL; 515 } 516 } else { 517 lfmt = 1; /* length format #1 */ 518 } 519 payload_hdr = (struct pld_hdr *)((&msg->pld_lenfmt) + lfmt); 520 *fcode = payload_hdr->func_val & 0xFFFF; 521 522 /* enable special processing based on the cprbs flags special bit */ 523 if (msg->cprbx.flags & 0x20) 524 ap_msg->flags |= AP_MSG_FLAG_SPECIAL; 525 526 /* set info bits in ap_message flag field */ 527 if (msg->cprbx.flags & 0x80) 528 ap_msg->flags |= AP_MSG_FLAG_ADMIN; 529 else 530 ap_msg->flags |= AP_MSG_FLAG_USAGE; 531 532 *domain = msg->cprbx.target_id; 533 534 return 0; 535} 536 537/* 538 * Copy results from a type 86 ICA reply message back to user space. 539 * 540 * @zq: crypto device pointer 541 * @reply: reply AP message. 542 * @data: pointer to user output data 543 * @length: size of user output data 544 * 545 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. 546 */ 547struct type86x_reply { 548 struct type86_hdr hdr; 549 struct type86_fmt2_ext fmt2; 550 struct CPRBX cprbx; 551 unsigned char pad[4]; /* 4 byte function code/rules block ? */ 552 unsigned short length; /* length of data including length field size */ 553 char data[]; 554} __packed; 555 556struct type86_ep11_reply { 557 struct type86_hdr hdr; 558 struct type86_fmt2_ext fmt2; 559 struct ep11_cprb cprbx; 560} __packed; 561 562static int convert_type86_ica(struct zcrypt_queue *zq, 563 struct ap_message *reply, 564 char __user *outputdata, 565 unsigned int outputdatalength) 566{ 567 struct type86x_reply *msg = reply->msg; 568 unsigned short service_rc, service_rs; 569 unsigned int data_len; 570 571 service_rc = msg->cprbx.ccp_rtcode; 572 if (unlikely(service_rc != 0)) { 573 service_rs = msg->cprbx.ccp_rscode; 574 if ((service_rc == 8 && service_rs == 66) || 575 (service_rc == 8 && service_rs == 65) || 576 (service_rc == 8 && service_rs == 72) || 577 (service_rc == 8 && service_rs == 770) || 578 (service_rc == 12 && service_rs == 769)) { 579 ZCRYPT_DBF_WARN("%s dev=%02x.%04x rc/rs=%d/%d => rc=EINVAL\n", 580 __func__, AP_QID_CARD(zq->queue->qid), 581 AP_QID_QUEUE(zq->queue->qid), 582 (int)service_rc, (int)service_rs); 583 return -EINVAL; 584 } 585 zq->online = 0; 586 pr_err("Crypto dev=%02x.%04x rc/rs=%d/%d online=0 rc=EAGAIN\n", 587 AP_QID_CARD(zq->queue->qid), 588 AP_QID_QUEUE(zq->queue->qid), 589 (int)service_rc, (int)service_rs); 590 ZCRYPT_DBF_ERR("%s dev=%02x.%04x rc/rs=%d/%d => online=0 rc=EAGAIN\n", 591 __func__, AP_QID_CARD(zq->queue->qid), 592 AP_QID_QUEUE(zq->queue->qid), 593 (int)service_rc, (int)service_rs); 594 ap_send_online_uevent(&zq->queue->ap_dev, zq->online); 595 return -EAGAIN; 596 } 597 data_len = msg->length - sizeof(msg->length); 598 if (data_len > outputdatalength) 599 return -EMSGSIZE; 600 601 /* Copy the crypto response to user space. */ 602 if (copy_to_user(outputdata, msg->data, data_len)) 603 return -EFAULT; 604 return 0; 605} 606 607/* 608 * Copy results from a type 86 XCRB reply message back to user space. 609 * 610 * @zq: crypto device pointer 611 * @reply: reply AP message. 612 * @xcrb: pointer to XCRB 613 * 614 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. 615 */ 616static int convert_type86_xcrb(bool userspace, struct zcrypt_queue *zq, 617 struct ap_message *reply, 618 struct ica_xcRB *xcrb) 619{ 620 struct type86_fmt2_msg *msg = reply->msg; 621 char *data = reply->msg; 622 623 /* Copy CPRB to user */ 624 if (xcrb->reply_control_blk_length < msg->fmt2.count1) { 625 pr_debug("reply_control_blk_length %u < required %u => EMSGSIZE\n", 626 xcrb->reply_control_blk_length, msg->fmt2.count1); 627 return -EMSGSIZE; 628 } 629 if (z_copy_to_user(userspace, xcrb->reply_control_blk_addr, 630 data + msg->fmt2.offset1, msg->fmt2.count1)) 631 return -EFAULT; 632 xcrb->reply_control_blk_length = msg->fmt2.count1; 633 634 /* Copy data buffer to user */ 635 if (msg->fmt2.count2) { 636 if (xcrb->reply_data_length < msg->fmt2.count2) { 637 pr_debug("reply_data_length %u < required %u => EMSGSIZE\n", 638 xcrb->reply_data_length, msg->fmt2.count2); 639 return -EMSGSIZE; 640 } 641 if (z_copy_to_user(userspace, xcrb->reply_data_addr, 642 data + msg->fmt2.offset2, msg->fmt2.count2)) 643 return -EFAULT; 644 } 645 xcrb->reply_data_length = msg->fmt2.count2; 646 647 return 0; 648} 649 650/* 651 * Copy results from a type 86 EP11 XCRB reply message back to user space. 652 * 653 * @zq: crypto device pointer 654 * @reply: reply AP message. 655 * @xcrb: pointer to EP11 user request block 656 * 657 * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. 658 */ 659static int convert_type86_ep11_xcrb(bool userspace, struct zcrypt_queue *zq, 660 struct ap_message *reply, 661 struct ep11_urb *xcrb) 662{ 663 struct type86_fmt2_msg *msg = reply->msg; 664 char *data = reply->msg; 665 666 if (xcrb->resp_len < msg->fmt2.count1) { 667 pr_debug("resp_len %u < required %u => EMSGSIZE\n", 668 (unsigned int)xcrb->resp_len, msg->fmt2.count1); 669 return -EMSGSIZE; 670 } 671 672 /* Copy response CPRB to user */ 673 if (z_copy_to_user(userspace, (char __force __user *)xcrb->resp, 674 data + msg->fmt2.offset1, msg->fmt2.count1)) 675 return -EFAULT; 676 xcrb->resp_len = msg->fmt2.count1; 677 return 0; 678} 679 680static int convert_type86_rng(struct zcrypt_queue *zq, 681 struct ap_message *reply, 682 char *buffer) 683{ 684 struct { 685 struct type86_hdr hdr; 686 struct type86_fmt2_ext fmt2; 687 struct CPRBX cprbx; 688 } __packed * msg = reply->msg; 689 char *data = reply->msg; 690 691 if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) 692 return -EINVAL; 693 memcpy(buffer, data + msg->fmt2.offset2, msg->fmt2.count2); 694 return msg->fmt2.count2; 695} 696 697static int convert_response_ica(struct zcrypt_queue *zq, 698 struct ap_message *reply, 699 char __user *outputdata, 700 unsigned int outputdatalength) 701{ 702 struct type86x_reply *msg = reply->msg; 703 704 switch (msg->hdr.type) { 705 case TYPE82_RSP_CODE: 706 case TYPE88_RSP_CODE: 707 return convert_error(zq, reply); 708 case TYPE86_RSP_CODE: 709 if (msg->cprbx.ccp_rtcode && 710 msg->cprbx.ccp_rscode == 0x14f && 711 outputdatalength > 256) { 712 if (zq->zcard->max_exp_bit_length <= 17) { 713 zq->zcard->max_exp_bit_length = 17; 714 return -EAGAIN; 715 } else { 716 return -EINVAL; 717 } 718 } 719 if (msg->hdr.reply_code) 720 return convert_error(zq, reply); 721 if (msg->cprbx.cprb_ver_id == 0x02) 722 return convert_type86_ica(zq, reply, 723 outputdata, outputdatalength); 724 fallthrough; /* wrong cprb version is an unknown response */ 725 default: 726 /* Unknown response type, this should NEVER EVER happen */ 727 zq->online = 0; 728 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 729 AP_QID_CARD(zq->queue->qid), 730 AP_QID_QUEUE(zq->queue->qid), 731 (int)msg->hdr.type); 732 ZCRYPT_DBF_ERR( 733 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 734 __func__, AP_QID_CARD(zq->queue->qid), 735 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type); 736 ap_send_online_uevent(&zq->queue->ap_dev, zq->online); 737 return -EAGAIN; 738 } 739} 740 741static int convert_response_xcrb(bool userspace, struct zcrypt_queue *zq, 742 struct ap_message *reply, 743 struct ica_xcRB *xcrb) 744{ 745 struct type86x_reply *msg = reply->msg; 746 747 switch (msg->hdr.type) { 748 case TYPE82_RSP_CODE: 749 case TYPE88_RSP_CODE: 750 xcrb->status = 0x0008044DL; /* HDD_InvalidParm */ 751 return convert_error(zq, reply); 752 case TYPE86_RSP_CODE: 753 if (msg->hdr.reply_code) { 754 memcpy(&xcrb->status, msg->fmt2.apfs, sizeof(u32)); 755 return convert_error(zq, reply); 756 } 757 if (msg->cprbx.cprb_ver_id == 0x02) 758 return convert_type86_xcrb(userspace, zq, reply, xcrb); 759 fallthrough; /* wrong cprb version is an unknown response */ 760 default: /* Unknown response type, this should NEVER EVER happen */ 761 xcrb->status = 0x0008044DL; /* HDD_InvalidParm */ 762 zq->online = 0; 763 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 764 AP_QID_CARD(zq->queue->qid), 765 AP_QID_QUEUE(zq->queue->qid), 766 (int)msg->hdr.type); 767 ZCRYPT_DBF_ERR( 768 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 769 __func__, AP_QID_CARD(zq->queue->qid), 770 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type); 771 ap_send_online_uevent(&zq->queue->ap_dev, zq->online); 772 return -EAGAIN; 773 } 774} 775 776static int convert_response_ep11_xcrb(bool userspace, struct zcrypt_queue *zq, 777 struct ap_message *reply, struct ep11_urb *xcrb) 778{ 779 struct type86_ep11_reply *msg = reply->msg; 780 781 switch (msg->hdr.type) { 782 case TYPE82_RSP_CODE: 783 case TYPE87_RSP_CODE: 784 return convert_error(zq, reply); 785 case TYPE86_RSP_CODE: 786 if (msg->hdr.reply_code) 787 return convert_error(zq, reply); 788 if (msg->cprbx.cprb_ver_id == 0x04) 789 return convert_type86_ep11_xcrb(userspace, zq, reply, xcrb); 790 fallthrough; /* wrong cprb version is an unknown resp */ 791 default: /* Unknown response type, this should NEVER EVER happen */ 792 zq->online = 0; 793 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 794 AP_QID_CARD(zq->queue->qid), 795 AP_QID_QUEUE(zq->queue->qid), 796 (int)msg->hdr.type); 797 ZCRYPT_DBF_ERR( 798 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 799 __func__, AP_QID_CARD(zq->queue->qid), 800 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type); 801 ap_send_online_uevent(&zq->queue->ap_dev, zq->online); 802 return -EAGAIN; 803 } 804} 805 806static int convert_response_rng(struct zcrypt_queue *zq, 807 struct ap_message *reply, 808 char *data) 809{ 810 struct type86x_reply *msg = reply->msg; 811 812 switch (msg->hdr.type) { 813 case TYPE82_RSP_CODE: 814 case TYPE88_RSP_CODE: 815 return -EINVAL; 816 case TYPE86_RSP_CODE: 817 if (msg->hdr.reply_code) 818 return -EINVAL; 819 if (msg->cprbx.cprb_ver_id == 0x02) 820 return convert_type86_rng(zq, reply, data); 821 fallthrough; /* wrong cprb version is an unknown response */ 822 default: /* Unknown response type, this should NEVER EVER happen */ 823 zq->online = 0; 824 pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 825 AP_QID_CARD(zq->queue->qid), 826 AP_QID_QUEUE(zq->queue->qid), 827 (int)msg->hdr.type); 828 ZCRYPT_DBF_ERR( 829 "%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", 830 __func__, AP_QID_CARD(zq->queue->qid), 831 AP_QID_QUEUE(zq->queue->qid), (int)msg->hdr.type); 832 ap_send_online_uevent(&zq->queue->ap_dev, zq->online); 833 return -EAGAIN; 834 } 835} 836 837/* 838 * This function is called from the AP bus code after a crypto request 839 * "msg" has finished with the reply message "reply". 840 * It is called from tasklet context. 841 * @aq: pointer to the AP queue 842 * @msg: pointer to the AP message 843 * @reply: pointer to the AP reply message 844 */ 845static void zcrypt_msgtype6_receive(struct ap_queue *aq, 846 struct ap_message *msg, 847 struct ap_message *reply) 848{ 849 static struct error_hdr error_reply = { 850 .type = TYPE82_RSP_CODE, 851 .reply_code = REP82_ERROR_MACHINE_FAILURE, 852 }; 853 struct ap_response_type *resp_type = &msg->response; 854 struct type86x_reply *t86r; 855 int len; 856 857 /* Copy the reply message to the request message buffer. */ 858 if (!reply) 859 goto out; /* ap_msg->rc indicates the error */ 860 t86r = reply->msg; 861 if (t86r->hdr.type == TYPE86_RSP_CODE && 862 t86r->cprbx.cprb_ver_id == 0x02) { 863 switch (resp_type->type) { 864 case CEXXC_RESPONSE_TYPE_ICA: 865 len = sizeof(struct type86x_reply) + t86r->length; 866 if (len > reply->bufsize || len > msg->bufsize || 867 len != reply->len) { 868 pr_debug("len mismatch => EMSGSIZE\n"); 869 msg->rc = -EMSGSIZE; 870 goto out; 871 } 872 memcpy(msg->msg, reply->msg, len); 873 msg->len = len; 874 break; 875 case CEXXC_RESPONSE_TYPE_XCRB: 876 if (t86r->fmt2.count2) 877 len = t86r->fmt2.offset2 + t86r->fmt2.count2; 878 else 879 len = t86r->fmt2.offset1 + t86r->fmt2.count1; 880 if (len > reply->bufsize || len > msg->bufsize || 881 len != reply->len) { 882 pr_debug("len mismatch => EMSGSIZE\n"); 883 msg->rc = -EMSGSIZE; 884 goto out; 885 } 886 memcpy(msg->msg, reply->msg, len); 887 msg->len = len; 888 break; 889 default: 890 memcpy(msg->msg, &error_reply, sizeof(error_reply)); 891 msg->len = sizeof(error_reply); 892 } 893 } else { 894 memcpy(msg->msg, reply->msg, sizeof(error_reply)); 895 msg->len = sizeof(error_reply); 896 } 897out: 898 complete(&resp_type->work); 899} 900 901/* 902 * This function is called from the AP bus code after a crypto request 903 * "msg" has finished with the reply message "reply". 904 * It is called from tasklet context. 905 * @aq: pointer to the AP queue 906 * @msg: pointer to the AP message 907 * @reply: pointer to the AP reply message 908 */ 909static void zcrypt_msgtype6_receive_ep11(struct ap_queue *aq, 910 struct ap_message *msg, 911 struct ap_message *reply) 912{ 913 static struct error_hdr error_reply = { 914 .type = TYPE82_RSP_CODE, 915 .reply_code = REP82_ERROR_MACHINE_FAILURE, 916 }; 917 struct ap_response_type *resp_type = &msg->response; 918 struct type86_ep11_reply *t86r; 919 int len; 920 921 /* Copy the reply message to the request message buffer. */ 922 if (!reply) 923 goto out; /* ap_msg->rc indicates the error */ 924 t86r = reply->msg; 925 if (t86r->hdr.type == TYPE86_RSP_CODE && 926 t86r->cprbx.cprb_ver_id == 0x04) { 927 switch (resp_type->type) { 928 case CEXXC_RESPONSE_TYPE_EP11: 929 len = t86r->fmt2.offset1 + t86r->fmt2.count1; 930 if (len > reply->bufsize || len > msg->bufsize || 931 len != reply->len) { 932 pr_debug("len mismatch => EMSGSIZE\n"); 933 msg->rc = -EMSGSIZE; 934 goto out; 935 } 936 memcpy(msg->msg, reply->msg, len); 937 msg->len = len; 938 break; 939 default: 940 memcpy(msg->msg, &error_reply, sizeof(error_reply)); 941 msg->len = sizeof(error_reply); 942 } 943 } else { 944 memcpy(msg->msg, reply->msg, sizeof(error_reply)); 945 msg->len = sizeof(error_reply); 946 } 947out: 948 complete(&resp_type->work); 949} 950 951static atomic_t zcrypt_step = ATOMIC_INIT(0); 952 953/* 954 * The request distributor calls this function if it picked the CEXxC 955 * device to handle a modexpo request. 956 * This function assumes that ap_msg has been initialized with 957 * ap_init_apmsg() and thus a valid buffer with the size of 958 * ap_msg->bufsize is available within ap_msg. Also the caller has 959 * to make sure ap_release_apmsg() is always called even on failure. 960 * @zq: pointer to zcrypt_queue structure that identifies the 961 * CEXxC device to the request distributor 962 * @mex: pointer to the modexpo request buffer 963 */ 964static long zcrypt_msgtype6_modexpo(struct zcrypt_queue *zq, 965 struct ica_rsa_modexpo *mex, 966 struct ap_message *ap_msg) 967{ 968 struct ap_response_type *resp_type = &ap_msg->response; 969 int rc; 970 971 ap_msg->receive = zcrypt_msgtype6_receive; 972 ap_msg->psmid = (((unsigned long)current->pid) << 32) + 973 atomic_inc_return(&zcrypt_step); 974 rc = icamex_msg_to_type6mex_msgx(zq, ap_msg, mex); 975 if (rc) 976 goto out; 977 resp_type->type = CEXXC_RESPONSE_TYPE_ICA; 978 init_completion(&resp_type->work); 979 rc = ap_queue_message(zq->queue, ap_msg); 980 if (rc) 981 goto out; 982 rc = wait_for_completion_interruptible(&resp_type->work); 983 if (rc == 0) { 984 rc = ap_msg->rc; 985 if (rc == 0) 986 rc = convert_response_ica(zq, ap_msg, 987 mex->outputdata, 988 mex->outputdatalength); 989 } else { 990 /* Signal pending. */ 991 ap_cancel_message(zq->queue, ap_msg); 992 } 993 994out: 995 return rc; 996} 997 998/* 999 * The request distributor calls this function if it picked the CEXxC 1000 * device to handle a modexpo_crt request. 1001 * This function assumes that ap_msg has been initialized with 1002 * ap_init_apmsg() and thus a valid buffer with the size of 1003 * ap_msg->bufsize is available within ap_msg. Also the caller has 1004 * to make sure ap_release_apmsg() is always called even on failure. 1005 * @zq: pointer to zcrypt_queue structure that identifies the 1006 * CEXxC device to the request distributor 1007 * @crt: pointer to the modexpoc_crt request buffer 1008 */ 1009static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq, 1010 struct ica_rsa_modexpo_crt *crt, 1011 struct ap_message *ap_msg) 1012{ 1013 struct ap_response_type *resp_type = &ap_msg->response; 1014 int rc; 1015 1016 ap_msg->receive = zcrypt_msgtype6_receive; 1017 ap_msg->psmid = (((unsigned long)current->pid) << 32) + 1018 atomic_inc_return(&zcrypt_step); 1019 rc = icacrt_msg_to_type6crt_msgx(zq, ap_msg, crt); 1020 if (rc) 1021 goto out; 1022 resp_type->type = CEXXC_RESPONSE_TYPE_ICA; 1023 init_completion(&resp_type->work); 1024 rc = ap_queue_message(zq->queue, ap_msg); 1025 if (rc) 1026 goto out; 1027 rc = wait_for_completion_interruptible(&resp_type->work); 1028 if (rc == 0) { 1029 rc = ap_msg->rc; 1030 if (rc == 0) 1031 rc = convert_response_ica(zq, ap_msg, 1032 crt->outputdata, 1033 crt->outputdatalength); 1034 } else { 1035 /* Signal pending. */ 1036 ap_cancel_message(zq->queue, ap_msg); 1037 } 1038 1039out: 1040 return rc; 1041} 1042 1043/* 1044 * Prepare a CCA AP msg request. 1045 * Prepare a CCA AP msg: fetch the required data from userspace, 1046 * prepare the AP msg, fill some info into the ap_message struct, 1047 * extract some data from the CPRB and give back to the caller. 1048 * This function assumes that ap_msg has been initialized with 1049 * ap_init_apmsg() and thus a valid buffer with the size of 1050 * ap_msg->bufsize is available within ap_msg. Also the caller has 1051 * to make sure ap_release_apmsg() is always called even on failure. 1052 */ 1053int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb, 1054 struct ap_message *ap_msg, 1055 unsigned int *func_code, unsigned short **dom) 1056{ 1057 struct ap_response_type *resp_type = &ap_msg->response; 1058 1059 ap_msg->receive = zcrypt_msgtype6_receive; 1060 ap_msg->psmid = (((unsigned long)current->pid) << 32) + 1061 atomic_inc_return(&zcrypt_step); 1062 resp_type->type = CEXXC_RESPONSE_TYPE_XCRB; 1063 return xcrb_msg_to_type6cprb_msgx(userspace, ap_msg, xcrb, func_code, dom); 1064} 1065 1066/* 1067 * The request distributor calls this function if it picked the CEXxC 1068 * device to handle a send_cprb request. 1069 * @zq: pointer to zcrypt_queue structure that identifies the 1070 * CEXxC device to the request distributor 1071 * @xcrb: pointer to the send_cprb request buffer 1072 */ 1073static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq, 1074 struct ica_xcRB *xcrb, 1075 struct ap_message *ap_msg) 1076{ 1077 struct ap_response_type *resp_type = &ap_msg->response; 1078 struct { 1079 struct type6_hdr hdr; 1080 struct CPRBX cprbx; 1081 /* ... more data blocks ... */ 1082 } __packed * msg = ap_msg->msg; 1083 unsigned int max_payload_size; 1084 int rc, delta; 1085 1086 /* calculate maximum payload for this card and msg type */ 1087 max_payload_size = zq->reply.bufsize - sizeof(struct type86_fmt2_msg); 1088 1089 /* limit each of the two from fields to the maximum payload size */ 1090 msg->hdr.fromcardlen1 = min(msg->hdr.fromcardlen1, max_payload_size); 1091 msg->hdr.fromcardlen2 = min(msg->hdr.fromcardlen2, max_payload_size); 1092 1093 /* calculate delta if the sum of both exceeds max payload size */ 1094 delta = msg->hdr.fromcardlen1 + msg->hdr.fromcardlen2 1095 - max_payload_size; 1096 if (delta > 0) { 1097 /* 1098 * Sum exceeds maximum payload size, prune fromcardlen1 1099 * (always trust fromcardlen2) 1100 */ 1101 if (delta > msg->hdr.fromcardlen1) { 1102 rc = -EINVAL; 1103 goto out; 1104 } 1105 msg->hdr.fromcardlen1 -= delta; 1106 } 1107 1108 init_completion(&resp_type->work); 1109 rc = ap_queue_message(zq->queue, ap_msg); 1110 if (rc) 1111 goto out; 1112 rc = wait_for_completion_interruptible(&resp_type->work); 1113 if (rc == 0) { 1114 rc = ap_msg->rc; 1115 if (rc == 0) 1116 rc = convert_response_xcrb(userspace, zq, ap_msg, xcrb); 1117 } else { 1118 /* Signal pending. */ 1119 ap_cancel_message(zq->queue, ap_msg); 1120 } 1121 1122 if (rc == -EAGAIN && ap_msg->flags & AP_MSG_FLAG_ADMIN) 1123 rc = -EIO; /* do not retry administrative requests */ 1124 1125out: 1126 if (rc) 1127 pr_debug("send cprb at dev=%02x.%04x rc=%d\n", 1128 AP_QID_CARD(zq->queue->qid), 1129 AP_QID_QUEUE(zq->queue->qid), rc); 1130 return rc; 1131} 1132 1133/* 1134 * Prepare an EP11 AP msg request. 1135 * Prepare an EP11 AP msg: fetch the required data from userspace, 1136 * prepare the AP msg, fill some info into the ap_message struct, 1137 * extract some data from the CPRB and give back to the caller. 1138 * This function assumes that ap_msg has been initialized with 1139 * ap_init_apmsg() and thus a valid buffer with the size of 1140 * ap_msg->bufsize is available within ap_msg. Also the caller has 1141 * to make sure ap_release_apmsg() is always called even on failure. 1142 */ 1143int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb, 1144 struct ap_message *ap_msg, 1145 unsigned int *func_code, unsigned int *domain) 1146{ 1147 struct ap_response_type *resp_type = &ap_msg->response; 1148 1149 ap_msg->receive = zcrypt_msgtype6_receive_ep11; 1150 ap_msg->psmid = (((unsigned long)current->pid) << 32) + 1151 atomic_inc_return(&zcrypt_step); 1152 resp_type->type = CEXXC_RESPONSE_TYPE_EP11; 1153 return xcrb_msg_to_type6_ep11cprb_msgx(userspace, ap_msg, xcrb, 1154 func_code, domain); 1155} 1156 1157/* 1158 * The request distributor calls this function if it picked the CEX4P 1159 * device to handle a send_ep11_cprb request. 1160 * @zq: pointer to zcrypt_queue structure that identifies the 1161 * CEX4P device to the request distributor 1162 * @xcrb: pointer to the ep11 user request block 1163 */ 1164static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *zq, 1165 struct ep11_urb *xcrb, 1166 struct ap_message *ap_msg) 1167{ 1168 int rc; 1169 unsigned int lfmt; 1170 struct ap_response_type *resp_type = &ap_msg->response; 1171 struct { 1172 struct type6_hdr hdr; 1173 struct ep11_cprb cprbx; 1174 unsigned char pld_tag; /* fixed value 0x30 */ 1175 unsigned char pld_lenfmt; /* payload length format */ 1176 } __packed * msg = ap_msg->msg; 1177 struct pld_hdr { 1178 unsigned char func_tag; /* fixed value 0x4 */ 1179 unsigned char func_len; /* fixed value 0x4 */ 1180 unsigned int func_val; /* function ID */ 1181 unsigned char dom_tag; /* fixed value 0x4 */ 1182 unsigned char dom_len; /* fixed value 0x4 */ 1183 unsigned int dom_val; /* domain id */ 1184 } __packed * payload_hdr = NULL; 1185 1186 /* 1187 * The target domain field within the cprb body/payload block will be 1188 * replaced by the usage domain for non-management commands only. 1189 * Therefore we check the first bit of the 'flags' parameter for 1190 * management command indication. 1191 * 0 - non management command 1192 * 1 - management command 1193 */ 1194 if (!((msg->cprbx.flags & 0x80) == 0x80)) { 1195 msg->cprbx.target_id = (unsigned int) 1196 AP_QID_QUEUE(zq->queue->qid); 1197 1198 if ((msg->pld_lenfmt & 0x80) == 0x80) { /*ext.len.fmt 2 or 3*/ 1199 switch (msg->pld_lenfmt & 0x03) { 1200 case 1: 1201 lfmt = 2; 1202 break; 1203 case 2: 1204 lfmt = 3; 1205 break; 1206 default: 1207 return -EINVAL; 1208 } 1209 } else { 1210 lfmt = 1; /* length format #1 */ 1211 } 1212 payload_hdr = (struct pld_hdr *)((&msg->pld_lenfmt) + lfmt); 1213 payload_hdr->dom_val = (unsigned int) 1214 AP_QID_QUEUE(zq->queue->qid); 1215 } 1216 1217 /* 1218 * Set the queue's reply buffer length minus the two prepend headers 1219 * as reply limit for the card firmware. 1220 */ 1221 msg->hdr.fromcardlen1 = zq->reply.bufsize - 1222 sizeof(struct type86_hdr) - sizeof(struct type86_fmt2_ext); 1223 1224 init_completion(&resp_type->work); 1225 rc = ap_queue_message(zq->queue, ap_msg); 1226 if (rc) 1227 goto out; 1228 rc = wait_for_completion_interruptible(&resp_type->work); 1229 if (rc == 0) { 1230 rc = ap_msg->rc; 1231 if (rc == 0) 1232 rc = convert_response_ep11_xcrb(userspace, zq, ap_msg, xcrb); 1233 } else { 1234 /* Signal pending. */ 1235 ap_cancel_message(zq->queue, ap_msg); 1236 } 1237 1238 if (rc == -EAGAIN && ap_msg->flags & AP_MSG_FLAG_ADMIN) 1239 rc = -EIO; /* do not retry administrative requests */ 1240 1241out: 1242 if (rc) 1243 pr_debug("send cprb at dev=%02x.%04x rc=%d\n", 1244 AP_QID_CARD(zq->queue->qid), 1245 AP_QID_QUEUE(zq->queue->qid), rc); 1246 return rc; 1247} 1248 1249/* 1250 * Prepare a CEXXC get random request ap message. 1251 * This function assumes that ap_msg has been initialized with 1252 * ap_init_apmsg() and thus a valid buffer with the size of 1253 * ap_max_msg_size is available within ap_msg. Also the caller has 1254 * to make sure ap_release_apmsg() is always called even on failure. 1255 */ 1256int prep_rng_ap_msg(struct ap_message *ap_msg, int *func_code, 1257 unsigned int *domain) 1258{ 1259 struct ap_response_type *resp_type = &ap_msg->response; 1260 1261 if (ap_msg->bufsize < AP_DEFAULT_MAX_MSG_SIZE) 1262 return -EMSGSIZE; 1263 ap_msg->receive = zcrypt_msgtype6_receive; 1264 ap_msg->psmid = (((unsigned long)current->pid) << 32) + 1265 atomic_inc_return(&zcrypt_step); 1266 1267 resp_type->type = CEXXC_RESPONSE_TYPE_XCRB; 1268 1269 rng_type6cprb_msgx(ap_msg, ZCRYPT_RNG_BUFFER_SIZE, domain); 1270 1271 *func_code = HWRNG; 1272 return 0; 1273} 1274 1275/* 1276 * The request distributor calls this function if it picked the CEXxC 1277 * device to generate random data. 1278 * @zq: pointer to zcrypt_queue structure that identifies the 1279 * CEXxC device to the request distributor 1280 * @buffer: pointer to a memory page to return random data 1281 */ 1282static long zcrypt_msgtype6_rng(struct zcrypt_queue *zq, 1283 char *buffer, struct ap_message *ap_msg) 1284{ 1285 struct { 1286 struct type6_hdr hdr; 1287 struct CPRBX cprbx; 1288 char function_code[2]; 1289 short int rule_length; 1290 char rule[8]; 1291 short int verb_length; 1292 short int key_length; 1293 } __packed * msg = ap_msg->msg; 1294 struct ap_response_type *resp_type = &ap_msg->response; 1295 int rc; 1296 1297 msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid); 1298 1299 init_completion(&resp_type->work); 1300 rc = ap_queue_message(zq->queue, ap_msg); 1301 if (rc) 1302 goto out; 1303 rc = wait_for_completion_interruptible(&resp_type->work); 1304 if (rc == 0) { 1305 rc = ap_msg->rc; 1306 if (rc == 0) 1307 rc = convert_response_rng(zq, ap_msg, buffer); 1308 } else { 1309 /* Signal pending. */ 1310 ap_cancel_message(zq->queue, ap_msg); 1311 } 1312out: 1313 return rc; 1314} 1315 1316/* 1317 * The crypto operations for a CEXxC card. 1318 */ 1319 1320static struct zcrypt_ops zcrypt_msgtype6_ops = { 1321 .owner = THIS_MODULE, 1322 .name = MSGTYPE06_NAME, 1323 .variant = MSGTYPE06_VARIANT_DEFAULT, 1324 .rsa_modexpo = zcrypt_msgtype6_modexpo, 1325 .rsa_modexpo_crt = zcrypt_msgtype6_modexpo_crt, 1326 .send_cprb = zcrypt_msgtype6_send_cprb, 1327 .rng = zcrypt_msgtype6_rng, 1328}; 1329 1330static struct zcrypt_ops zcrypt_msgtype6_ep11_ops = { 1331 .owner = THIS_MODULE, 1332 .name = MSGTYPE06_NAME, 1333 .variant = MSGTYPE06_VARIANT_EP11, 1334 .rsa_modexpo = NULL, 1335 .rsa_modexpo_crt = NULL, 1336 .send_ep11_cprb = zcrypt_msgtype6_send_ep11_cprb, 1337}; 1338 1339void __init zcrypt_msgtype6_init(void) 1340{ 1341 zcrypt_msgtype_register(&zcrypt_msgtype6_ops); 1342 zcrypt_msgtype_register(&zcrypt_msgtype6_ep11_ops); 1343} 1344 1345void __exit zcrypt_msgtype6_exit(void) 1346{ 1347 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ops); 1348 zcrypt_msgtype_unregister(&zcrypt_msgtype6_ep11_ops); 1349}
~/
Read-only file preview.