1665 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright IBM Corp. 20194 * Author(s): Harald Freudenberger <freude@linux.ibm.com>5 *6 * Collection of EP11 misc functions used by zcrypt and pkey7 */8 9#define KMSG_COMPONENT "zcrypt"10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt11 12#include <linux/init.h>13#include <linux/module.h>14#include <linux/slab.h>15#include <linux/random.h>16#include <asm/zcrypt.h>17#include <asm/pkey.h>18#include <crypto/aes.h>19 20#include "ap_bus.h"21#include "zcrypt_api.h"22#include "zcrypt_debug.h"23#include "zcrypt_msgtype6.h"24#include "zcrypt_ep11misc.h"25#include "zcrypt_ccamisc.h"26 27#define EP11_PINBLOB_V1_BYTES 5628 29/* default iv used here */30static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,31 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };32 33/* ep11 card info cache */34struct card_list_entry {35 struct list_head list;36 u16 cardnr;37 struct ep11_card_info info;38};39static LIST_HEAD(card_list);40static DEFINE_SPINLOCK(card_list_lock);41 42static int card_cache_fetch(u16 cardnr, struct ep11_card_info *ci)43{44 int rc = -ENOENT;45 struct card_list_entry *ptr;46 47 spin_lock_bh(&card_list_lock);48 list_for_each_entry(ptr, &card_list, list) {49 if (ptr->cardnr == cardnr) {50 memcpy(ci, &ptr->info, sizeof(*ci));51 rc = 0;52 break;53 }54 }55 spin_unlock_bh(&card_list_lock);56 57 return rc;58}59 60static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci)61{62 int found = 0;63 struct card_list_entry *ptr;64 65 spin_lock_bh(&card_list_lock);66 list_for_each_entry(ptr, &card_list, list) {67 if (ptr->cardnr == cardnr) {68 memcpy(&ptr->info, ci, sizeof(*ci));69 found = 1;70 break;71 }72 }73 if (!found) {74 ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);75 if (!ptr) {76 spin_unlock_bh(&card_list_lock);77 return;78 }79 ptr->cardnr = cardnr;80 memcpy(&ptr->info, ci, sizeof(*ci));81 list_add(&ptr->list, &card_list);82 }83 spin_unlock_bh(&card_list_lock);84}85 86static void card_cache_scrub(u16 cardnr)87{88 struct card_list_entry *ptr;89 90 spin_lock_bh(&card_list_lock);91 list_for_each_entry(ptr, &card_list, list) {92 if (ptr->cardnr == cardnr) {93 list_del(&ptr->list);94 kfree(ptr);95 break;96 }97 }98 spin_unlock_bh(&card_list_lock);99}100 101static void __exit card_cache_free(void)102{103 struct card_list_entry *ptr, *pnext;104 105 spin_lock_bh(&card_list_lock);106 list_for_each_entry_safe(ptr, pnext, &card_list, list) {107 list_del(&ptr->list);108 kfree(ptr);109 }110 spin_unlock_bh(&card_list_lock);111}112 113static int ep11_kb_split(const u8 *kb, size_t kblen, u32 kbver,114 struct ep11kblob_header **kbhdr, size_t *kbhdrsize,115 u8 **kbpl, size_t *kbplsize)116{117 struct ep11kblob_header *hdr = NULL;118 size_t hdrsize, plsize = 0;119 int rc = -EINVAL;120 u8 *pl = NULL;121 122 if (kblen < sizeof(struct ep11kblob_header))123 goto out;124 hdr = (struct ep11kblob_header *)kb;125 126 switch (kbver) {127 case TOKVER_EP11_AES:128 /* header overlays the payload */129 hdrsize = 0;130 break;131 case TOKVER_EP11_ECC_WITH_HEADER:132 case TOKVER_EP11_AES_WITH_HEADER:133 /* payload starts after the header */134 hdrsize = sizeof(struct ep11kblob_header);135 break;136 default:137 goto out;138 }139 140 plsize = kblen - hdrsize;141 pl = (u8 *)kb + hdrsize;142 143 if (kbhdr)144 *kbhdr = hdr;145 if (kbhdrsize)146 *kbhdrsize = hdrsize;147 if (kbpl)148 *kbpl = pl;149 if (kbplsize)150 *kbplsize = plsize;151 152 rc = 0;153out:154 return rc;155}156 157static int ep11_kb_decode(const u8 *kb, size_t kblen,158 struct ep11kblob_header **kbhdr, size_t *kbhdrsize,159 struct ep11keyblob **kbpl, size_t *kbplsize)160{161 struct ep11kblob_header *tmph, *hdr = NULL;162 size_t hdrsize = 0, plsize = 0;163 struct ep11keyblob *pl = NULL;164 int rc = -EINVAL;165 u8 *tmpp;166 167 if (kblen < sizeof(struct ep11kblob_header))168 goto out;169 tmph = (struct ep11kblob_header *)kb;170 171 if (tmph->type != TOKTYPE_NON_CCA &&172 tmph->len > kblen)173 goto out;174 175 if (ep11_kb_split(kb, kblen, tmph->version,176 &hdr, &hdrsize, &tmpp, &plsize))177 goto out;178 179 if (plsize < sizeof(struct ep11keyblob))180 goto out;181 182 if (!is_ep11_keyblob(tmpp))183 goto out;184 185 pl = (struct ep11keyblob *)tmpp;186 plsize = hdr->len - hdrsize;187 188 if (kbhdr)189 *kbhdr = hdr;190 if (kbhdrsize)191 *kbhdrsize = hdrsize;192 if (kbpl)193 *kbpl = pl;194 if (kbplsize)195 *kbplsize = plsize;196 197 rc = 0;198out:199 return rc;200}201 202/*203 * For valid ep11 keyblobs, returns a reference to the wrappingkey verification204 * pattern. Otherwise NULL.205 */206const u8 *ep11_kb_wkvp(const u8 *keyblob, u32 keybloblen)207{208 struct ep11keyblob *kb;209 210 if (ep11_kb_decode(keyblob, keybloblen, NULL, NULL, &kb, NULL))211 return NULL;212 return kb->wkvp;213}214EXPORT_SYMBOL(ep11_kb_wkvp);215 216/*217 * Simple check if the key blob is a valid EP11 AES key blob with header.218 */219int ep11_check_aes_key_with_hdr(debug_info_t *dbg, int dbflvl,220 const u8 *key, u32 keylen, int checkcpacfexp)221{222 struct ep11kblob_header *hdr = (struct ep11kblob_header *)key;223 struct ep11keyblob *kb = (struct ep11keyblob *)(key + sizeof(*hdr));224 225#define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)226 227 if (keylen < sizeof(*hdr) + sizeof(*kb)) {228 DBF("%s key check failed, keylen %u < %zu\n",229 __func__, keylen, sizeof(*hdr) + sizeof(*kb));230 return -EINVAL;231 }232 233 if (hdr->type != TOKTYPE_NON_CCA) {234 if (dbg)235 DBF("%s key check failed, type 0x%02x != 0x%02x\n",236 __func__, (int)hdr->type, TOKTYPE_NON_CCA);237 return -EINVAL;238 }239 if (hdr->hver != 0x00) {240 if (dbg)241 DBF("%s key check failed, header version 0x%02x != 0x00\n",242 __func__, (int)hdr->hver);243 return -EINVAL;244 }245 if (hdr->version != TOKVER_EP11_AES_WITH_HEADER) {246 if (dbg)247 DBF("%s key check failed, version 0x%02x != 0x%02x\n",248 __func__, (int)hdr->version, TOKVER_EP11_AES_WITH_HEADER);249 return -EINVAL;250 }251 if (hdr->len > keylen) {252 if (dbg)253 DBF("%s key check failed, header len %d keylen %u mismatch\n",254 __func__, (int)hdr->len, keylen);255 return -EINVAL;256 }257 if (hdr->len < sizeof(*hdr) + sizeof(*kb)) {258 if (dbg)259 DBF("%s key check failed, header len %d < %zu\n",260 __func__, (int)hdr->len, sizeof(*hdr) + sizeof(*kb));261 return -EINVAL;262 }263 264 if (kb->version != EP11_STRUCT_MAGIC) {265 if (dbg)266 DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n",267 __func__, (int)kb->version, EP11_STRUCT_MAGIC);268 return -EINVAL;269 }270 if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) {271 if (dbg)272 DBF("%s key check failed, PKEY_EXTRACTABLE is off\n",273 __func__);274 return -EINVAL;275 }276 277#undef DBF278 279 return 0;280}281EXPORT_SYMBOL(ep11_check_aes_key_with_hdr);282 283/*284 * Simple check if the key blob is a valid EP11 ECC key blob with header.285 */286int ep11_check_ecc_key_with_hdr(debug_info_t *dbg, int dbflvl,287 const u8 *key, u32 keylen, int checkcpacfexp)288{289 struct ep11kblob_header *hdr = (struct ep11kblob_header *)key;290 struct ep11keyblob *kb = (struct ep11keyblob *)(key + sizeof(*hdr));291 292#define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)293 294 if (keylen < sizeof(*hdr) + sizeof(*kb)) {295 DBF("%s key check failed, keylen %u < %zu\n",296 __func__, keylen, sizeof(*hdr) + sizeof(*kb));297 return -EINVAL;298 }299 300 if (hdr->type != TOKTYPE_NON_CCA) {301 if (dbg)302 DBF("%s key check failed, type 0x%02x != 0x%02x\n",303 __func__, (int)hdr->type, TOKTYPE_NON_CCA);304 return -EINVAL;305 }306 if (hdr->hver != 0x00) {307 if (dbg)308 DBF("%s key check failed, header version 0x%02x != 0x00\n",309 __func__, (int)hdr->hver);310 return -EINVAL;311 }312 if (hdr->version != TOKVER_EP11_ECC_WITH_HEADER) {313 if (dbg)314 DBF("%s key check failed, version 0x%02x != 0x%02x\n",315 __func__, (int)hdr->version, TOKVER_EP11_ECC_WITH_HEADER);316 return -EINVAL;317 }318 if (hdr->len > keylen) {319 if (dbg)320 DBF("%s key check failed, header len %d keylen %u mismatch\n",321 __func__, (int)hdr->len, keylen);322 return -EINVAL;323 }324 if (hdr->len < sizeof(*hdr) + sizeof(*kb)) {325 if (dbg)326 DBF("%s key check failed, header len %d < %zu\n",327 __func__, (int)hdr->len, sizeof(*hdr) + sizeof(*kb));328 return -EINVAL;329 }330 331 if (kb->version != EP11_STRUCT_MAGIC) {332 if (dbg)333 DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n",334 __func__, (int)kb->version, EP11_STRUCT_MAGIC);335 return -EINVAL;336 }337 if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) {338 if (dbg)339 DBF("%s key check failed, PKEY_EXTRACTABLE is off\n",340 __func__);341 return -EINVAL;342 }343 344#undef DBF345 346 return 0;347}348EXPORT_SYMBOL(ep11_check_ecc_key_with_hdr);349 350/*351 * Simple check if the key blob is a valid EP11 AES key blob with352 * the header in the session field (old style EP11 AES key).353 */354int ep11_check_aes_key(debug_info_t *dbg, int dbflvl,355 const u8 *key, u32 keylen, int checkcpacfexp)356{357 struct ep11keyblob *kb = (struct ep11keyblob *)key;358 359#define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)360 361 if (keylen < sizeof(*kb)) {362 DBF("%s key check failed, keylen %u < %zu\n",363 __func__, keylen, sizeof(*kb));364 return -EINVAL;365 }366 367 if (kb->head.type != TOKTYPE_NON_CCA) {368 if (dbg)369 DBF("%s key check failed, type 0x%02x != 0x%02x\n",370 __func__, (int)kb->head.type, TOKTYPE_NON_CCA);371 return -EINVAL;372 }373 if (kb->head.version != TOKVER_EP11_AES) {374 if (dbg)375 DBF("%s key check failed, version 0x%02x != 0x%02x\n",376 __func__, (int)kb->head.version, TOKVER_EP11_AES);377 return -EINVAL;378 }379 if (kb->head.len > keylen) {380 if (dbg)381 DBF("%s key check failed, header len %d keylen %u mismatch\n",382 __func__, (int)kb->head.len, keylen);383 return -EINVAL;384 }385 if (kb->head.len < sizeof(*kb)) {386 if (dbg)387 DBF("%s key check failed, header len %d < %zu\n",388 __func__, (int)kb->head.len, sizeof(*kb));389 return -EINVAL;390 }391 392 if (kb->version != EP11_STRUCT_MAGIC) {393 if (dbg)394 DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n",395 __func__, (int)kb->version, EP11_STRUCT_MAGIC);396 return -EINVAL;397 }398 if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) {399 if (dbg)400 DBF("%s key check failed, PKEY_EXTRACTABLE is off\n",401 __func__);402 return -EINVAL;403 }404 405#undef DBF406 407 return 0;408}409EXPORT_SYMBOL(ep11_check_aes_key);410 411/*412 * Allocate and prepare ep11 cprb plus additional payload.413 */414static inline struct ep11_cprb *alloc_cprb(size_t payload_len)415{416 size_t len = sizeof(struct ep11_cprb) + payload_len;417 struct ep11_cprb *cprb;418 419 cprb = kzalloc(len, GFP_KERNEL);420 if (!cprb)421 return NULL;422 423 cprb->cprb_len = sizeof(struct ep11_cprb);424 cprb->cprb_ver_id = 0x04;425 memcpy(cprb->func_id, "T4", 2);426 cprb->ret_code = 0xFFFFFFFF;427 cprb->payload_len = payload_len;428 429 return cprb;430}431 432/*433 * Some helper functions related to ASN1 encoding.434 * Limited to length info <= 2 byte.435 */436 437#define ASN1TAGLEN(x) (2 + (x) + ((x) > 127 ? 1 : 0) + ((x) > 255 ? 1 : 0))438 439static int asn1tag_write(u8 *ptr, u8 tag, const u8 *pvalue, u16 valuelen)440{441 ptr[0] = tag;442 if (valuelen > 255) {443 ptr[1] = 0x82;444 *((u16 *)(ptr + 2)) = valuelen;445 memcpy(ptr + 4, pvalue, valuelen);446 return 4 + valuelen;447 }448 if (valuelen > 127) {449 ptr[1] = 0x81;450 ptr[2] = (u8)valuelen;451 memcpy(ptr + 3, pvalue, valuelen);452 return 3 + valuelen;453 }454 ptr[1] = (u8)valuelen;455 memcpy(ptr + 2, pvalue, valuelen);456 return 2 + valuelen;457}458 459/* EP11 payload > 127 bytes starts with this struct */460struct pl_head {461 u8 tag;462 u8 lenfmt;463 u16 len;464 u8 func_tag;465 u8 func_len;466 u32 func;467 u8 dom_tag;468 u8 dom_len;469 u32 dom;470} __packed;471 472/* prep ep11 payload head helper function */473static inline void prep_head(struct pl_head *h,474 size_t pl_size, int api, int func)475{476 h->tag = 0x30;477 h->lenfmt = 0x82;478 h->len = pl_size - 4;479 h->func_tag = 0x04;480 h->func_len = sizeof(u32);481 h->func = (api << 16) + func;482 h->dom_tag = 0x04;483 h->dom_len = sizeof(u32);484}485 486/* prep urb helper function */487static inline void prep_urb(struct ep11_urb *u,488 struct ep11_target_dev *t, int nt,489 struct ep11_cprb *req, size_t req_len,490 struct ep11_cprb *rep, size_t rep_len)491{492 u->targets = (u8 __user *)t;493 u->targets_num = nt;494 u->req = (u8 __user *)req;495 u->req_len = req_len;496 u->resp = (u8 __user *)rep;497 u->resp_len = rep_len;498}499 500/* Check ep11 reply payload, return 0 or suggested errno value. */501static int check_reply_pl(const u8 *pl, const char *func)502{503 int len;504 u32 ret;505 506 /* start tag */507 if (*pl++ != 0x30) {508 ZCRYPT_DBF_ERR("%s reply start tag mismatch\n", func);509 return -EIO;510 }511 512 /* payload length format */513 if (*pl < 127) {514 len = *pl;515 pl++;516 } else if (*pl == 0x81) {517 pl++;518 len = *pl;519 pl++;520 } else if (*pl == 0x82) {521 pl++;522 len = *((u16 *)pl);523 pl += 2;524 } else {525 ZCRYPT_DBF_ERR("%s reply start tag lenfmt mismatch 0x%02hhx\n",526 func, *pl);527 return -EIO;528 }529 530 /* len should cover at least 3 fields with 32 bit value each */531 if (len < 3 * 6) {532 ZCRYPT_DBF_ERR("%s reply length %d too small\n", func, len);533 return -EIO;534 }535 536 /* function tag, length and value */537 if (pl[0] != 0x04 || pl[1] != 0x04) {538 ZCRYPT_DBF_ERR("%s function tag or length mismatch\n", func);539 return -EIO;540 }541 pl += 6;542 543 /* dom tag, length and value */544 if (pl[0] != 0x04 || pl[1] != 0x04) {545 ZCRYPT_DBF_ERR("%s dom tag or length mismatch\n", func);546 return -EIO;547 }548 pl += 6;549 550 /* return value tag, length and value */551 if (pl[0] != 0x04 || pl[1] != 0x04) {552 ZCRYPT_DBF_ERR("%s return value tag or length mismatch\n",553 func);554 return -EIO;555 }556 pl += 2;557 ret = *((u32 *)pl);558 if (ret != 0) {559 ZCRYPT_DBF_ERR("%s return value 0x%08x != 0\n", func, ret);560 return -EIO;561 }562 563 return 0;564}565 566/* Check ep11 reply cprb, return 0 or suggested errno value. */567static int check_reply_cprb(const struct ep11_cprb *rep, const char *func)568{569 /* check ep11 reply return code field */570 if (rep->ret_code) {571 ZCRYPT_DBF_ERR("%s ep11 reply ret_code=0x%08x\n", __func__,572 rep->ret_code);573 if (rep->ret_code == 0x000c0003)574 return -EBUSY;575 else576 return -EIO;577 }578 579 return 0;580}581 582/*583 * Helper function which does an ep11 query with given query type.584 */585static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,586 size_t buflen, u8 *buf)587{588 struct ep11_info_req_pl {589 struct pl_head head;590 u8 query_type_tag;591 u8 query_type_len;592 u32 query_type;593 u8 query_subtype_tag;594 u8 query_subtype_len;595 u32 query_subtype;596 } __packed * req_pl;597 struct ep11_info_rep_pl {598 struct pl_head head;599 u8 rc_tag;600 u8 rc_len;601 u32 rc;602 u8 data_tag;603 u8 data_lenfmt;604 u16 data_len;605 } __packed * rep_pl;606 struct ep11_cprb *req = NULL, *rep = NULL;607 struct ep11_target_dev target;608 struct ep11_urb *urb = NULL;609 int api = EP11_API_V1, rc = -ENOMEM;610 611 /* request cprb and payload */612 req = alloc_cprb(sizeof(struct ep11_info_req_pl));613 if (!req)614 goto out;615 req_pl = (struct ep11_info_req_pl *)(((u8 *)req) + sizeof(*req));616 prep_head(&req_pl->head, sizeof(*req_pl), api, 38); /* get xcp info */617 req_pl->query_type_tag = 0x04;618 req_pl->query_type_len = sizeof(u32);619 req_pl->query_type = query_type;620 req_pl->query_subtype_tag = 0x04;621 req_pl->query_subtype_len = sizeof(u32);622 623 /* reply cprb and payload */624 rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen);625 if (!rep)626 goto out;627 rep_pl = (struct ep11_info_rep_pl *)(((u8 *)rep) + sizeof(*rep));628 629 /* urb and target */630 urb = kmalloc(sizeof(*urb), GFP_KERNEL);631 if (!urb)632 goto out;633 target.ap_id = cardnr;634 target.dom_id = domain;635 prep_urb(urb, &target, 1,636 req, sizeof(*req) + sizeof(*req_pl),637 rep, sizeof(*rep) + sizeof(*rep_pl) + buflen);638 639 rc = zcrypt_send_ep11_cprb(urb);640 if (rc) {641 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",642 __func__, (int)cardnr, (int)domain, rc);643 goto out;644 }645 646 /* check ep11 reply cprb */647 rc = check_reply_cprb(rep, __func__);648 if (rc)649 goto out;650 651 /* check payload */652 rc = check_reply_pl((u8 *)rep_pl, __func__);653 if (rc)654 goto out;655 if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {656 ZCRYPT_DBF_ERR("%s unknown reply data format\n", __func__);657 rc = -EIO;658 goto out;659 }660 if (rep_pl->data_len > buflen) {661 ZCRYPT_DBF_ERR("%s mismatch between reply data len and buffer len\n",662 __func__);663 rc = -ENOSPC;664 goto out;665 }666 667 memcpy(buf, ((u8 *)rep_pl) + sizeof(*rep_pl), rep_pl->data_len);668 669out:670 kfree(req);671 kfree(rep);672 kfree(urb);673 return rc;674}675 676/*677 * Provide information about an EP11 card.678 */679int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)680{681 int rc;682 struct ep11_module_query_info {683 u32 API_ord_nr;684 u32 firmware_id;685 u8 FW_major_vers;686 u8 FW_minor_vers;687 u8 CSP_major_vers;688 u8 CSP_minor_vers;689 u8 fwid[32];690 u8 xcp_config_hash[32];691 u8 CSP_config_hash[32];692 u8 serial[16];693 u8 module_date_time[16];694 u64 op_mode;695 u32 PKCS11_flags;696 u32 ext_flags;697 u32 domains;698 u32 sym_state_bytes;699 u32 digest_state_bytes;700 u32 pin_blob_bytes;701 u32 SPKI_bytes;702 u32 priv_key_blob_bytes;703 u32 sym_blob_bytes;704 u32 max_payload_bytes;705 u32 CP_profile_bytes;706 u32 max_CP_index;707 } __packed * pmqi = NULL;708 709 rc = card_cache_fetch(card, info);710 if (rc || verify) {711 pmqi = kmalloc(sizeof(*pmqi), GFP_KERNEL);712 if (!pmqi)713 return -ENOMEM;714 rc = ep11_query_info(card, AUTOSEL_DOM,715 0x01 /* module info query */,716 sizeof(*pmqi), (u8 *)pmqi);717 if (rc) {718 if (rc == -ENODEV)719 card_cache_scrub(card);720 goto out;721 }722 memset(info, 0, sizeof(*info));723 info->API_ord_nr = pmqi->API_ord_nr;724 info->FW_version =725 (pmqi->FW_major_vers << 8) + pmqi->FW_minor_vers;726 memcpy(info->serial, pmqi->serial, sizeof(info->serial));727 info->op_mode = pmqi->op_mode;728 card_cache_update(card, info);729 }730 731out:732 kfree(pmqi);733 return rc;734}735EXPORT_SYMBOL(ep11_get_card_info);736 737/*738 * Provide information about a domain within an EP11 card.739 */740int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info)741{742 int rc;743 struct ep11_domain_query_info {744 u32 dom_index;745 u8 cur_WK_VP[32];746 u8 new_WK_VP[32];747 u32 dom_flags;748 u64 op_mode;749 } __packed * p_dom_info;750 751 p_dom_info = kmalloc(sizeof(*p_dom_info), GFP_KERNEL);752 if (!p_dom_info)753 return -ENOMEM;754 755 rc = ep11_query_info(card, domain, 0x03 /* domain info query */,756 sizeof(*p_dom_info), (u8 *)p_dom_info);757 if (rc)758 goto out;759 760 memset(info, 0, sizeof(*info));761 info->cur_wk_state = '0';762 info->new_wk_state = '0';763 if (p_dom_info->dom_flags & 0x10 /* left imprint mode */) {764 if (p_dom_info->dom_flags & 0x02 /* cur wk valid */) {765 info->cur_wk_state = '1';766 memcpy(info->cur_wkvp, p_dom_info->cur_WK_VP, 32);767 }768 if (p_dom_info->dom_flags & 0x04 || /* new wk present */769 p_dom_info->dom_flags & 0x08 /* new wk committed */) {770 info->new_wk_state =771 p_dom_info->dom_flags & 0x08 ? '2' : '1';772 memcpy(info->new_wkvp, p_dom_info->new_WK_VP, 32);773 }774 }775 info->op_mode = p_dom_info->op_mode;776 777out:778 kfree(p_dom_info);779 return rc;780}781EXPORT_SYMBOL(ep11_get_domain_info);782 783/*784 * Default EP11 AES key generate attributes, used when no keygenflags given:785 * XCP_BLOB_ENCRYPT | XCP_BLOB_DECRYPT | XCP_BLOB_PROTKEY_EXTRACTABLE786 */787#define KEY_ATTR_DEFAULTS 0x00200c00788 789static int _ep11_genaeskey(u16 card, u16 domain,790 u32 keybitsize, u32 keygenflags,791 u8 *keybuf, size_t *keybufsize)792{793 struct keygen_req_pl {794 struct pl_head head;795 u8 var_tag;796 u8 var_len;797 u32 var;798 u8 keybytes_tag;799 u8 keybytes_len;800 u32 keybytes;801 u8 mech_tag;802 u8 mech_len;803 u32 mech;804 u8 attr_tag;805 u8 attr_len;806 u32 attr_header;807 u32 attr_bool_mask;808 u32 attr_bool_bits;809 u32 attr_val_len_type;810 u32 attr_val_len_value;811 /* followed by empty pin tag or empty pinblob tag */812 } __packed * req_pl;813 struct keygen_rep_pl {814 struct pl_head head;815 u8 rc_tag;816 u8 rc_len;817 u32 rc;818 u8 data_tag;819 u8 data_lenfmt;820 u16 data_len;821 u8 data[512];822 } __packed * rep_pl;823 struct ep11_cprb *req = NULL, *rep = NULL;824 size_t req_pl_size, pinblob_size = 0;825 struct ep11_target_dev target;826 struct ep11_urb *urb = NULL;827 int api, rc = -ENOMEM;828 u8 *p;829 830 switch (keybitsize) {831 case 128:832 case 192:833 case 256:834 break;835 default:836 ZCRYPT_DBF_ERR("%s unknown/unsupported keybitsize %d\n",837 __func__, keybitsize);838 rc = -EINVAL;839 goto out;840 }841 842 /* request cprb and payload */843 api = (!keygenflags || keygenflags & 0x00200000) ?844 EP11_API_V4 : EP11_API_V1;845 if (ap_is_se_guest()) {846 /*847 * genkey within SE environment requires API ordinal 6848 * with empty pinblob849 */850 api = EP11_API_V6;851 pinblob_size = EP11_PINBLOB_V1_BYTES;852 }853 req_pl_size = sizeof(struct keygen_req_pl) + ASN1TAGLEN(pinblob_size);854 req = alloc_cprb(req_pl_size);855 if (!req)856 goto out;857 req_pl = (struct keygen_req_pl *)(((u8 *)req) + sizeof(*req));858 prep_head(&req_pl->head, req_pl_size, api, 21); /* GenerateKey */859 req_pl->var_tag = 0x04;860 req_pl->var_len = sizeof(u32);861 req_pl->keybytes_tag = 0x04;862 req_pl->keybytes_len = sizeof(u32);863 req_pl->keybytes = keybitsize / 8;864 req_pl->mech_tag = 0x04;865 req_pl->mech_len = sizeof(u32);866 req_pl->mech = 0x00001080; /* CKM_AES_KEY_GEN */867 req_pl->attr_tag = 0x04;868 req_pl->attr_len = 5 * sizeof(u32);869 req_pl->attr_header = 0x10010000;870 req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;871 req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;872 req_pl->attr_val_len_type = 0x00000161; /* CKA_VALUE_LEN */873 req_pl->attr_val_len_value = keybitsize / 8;874 p = ((u8 *)req_pl) + sizeof(*req_pl);875 /* pin tag */876 *p++ = 0x04;877 *p++ = pinblob_size;878 879 /* reply cprb and payload */880 rep = alloc_cprb(sizeof(struct keygen_rep_pl));881 if (!rep)882 goto out;883 rep_pl = (struct keygen_rep_pl *)(((u8 *)rep) + sizeof(*rep));884 885 /* urb and target */886 urb = kmalloc(sizeof(*urb), GFP_KERNEL);887 if (!urb)888 goto out;889 target.ap_id = card;890 target.dom_id = domain;891 prep_urb(urb, &target, 1,892 req, sizeof(*req) + req_pl_size,893 rep, sizeof(*rep) + sizeof(*rep_pl));894 895 rc = zcrypt_send_ep11_cprb(urb);896 if (rc) {897 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",898 __func__, (int)card, (int)domain, rc);899 goto out;900 }901 902 /* check ep11 reply cprb */903 rc = check_reply_cprb(rep, __func__);904 if (rc)905 goto out;906 907 /* check payload */908 rc = check_reply_pl((u8 *)rep_pl, __func__);909 if (rc)910 goto out;911 if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {912 ZCRYPT_DBF_ERR("%s unknown reply data format\n", __func__);913 rc = -EIO;914 goto out;915 }916 if (rep_pl->data_len > *keybufsize) {917 ZCRYPT_DBF_ERR("%s mismatch reply data len / key buffer len\n",918 __func__);919 rc = -ENOSPC;920 goto out;921 }922 923 /* copy key blob */924 memcpy(keybuf, rep_pl->data, rep_pl->data_len);925 *keybufsize = rep_pl->data_len;926 927out:928 kfree(req);929 kfree(rep);930 kfree(urb);931 return rc;932}933 934int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,935 u8 *keybuf, u32 *keybufsize, u32 keybufver)936{937 struct ep11kblob_header *hdr;938 size_t hdr_size, pl_size;939 u8 *pl;940 int rc;941 942 switch (keybufver) {943 case TOKVER_EP11_AES:944 case TOKVER_EP11_AES_WITH_HEADER:945 break;946 default:947 return -EINVAL;948 }949 950 rc = ep11_kb_split(keybuf, *keybufsize, keybufver,951 &hdr, &hdr_size, &pl, &pl_size);952 if (rc)953 return rc;954 955 rc = _ep11_genaeskey(card, domain, keybitsize, keygenflags,956 pl, &pl_size);957 if (rc)958 return rc;959 960 *keybufsize = hdr_size + pl_size;961 962 /* update header information */963 hdr->type = TOKTYPE_NON_CCA;964 hdr->len = *keybufsize;965 hdr->version = keybufver;966 hdr->bitlen = keybitsize;967 968 return 0;969}970EXPORT_SYMBOL(ep11_genaeskey);971 972static int ep11_cryptsingle(u16 card, u16 domain,973 u16 mode, u32 mech, const u8 *iv,974 const u8 *key, size_t keysize,975 const u8 *inbuf, size_t inbufsize,976 u8 *outbuf, size_t *outbufsize)977{978 struct crypt_req_pl {979 struct pl_head head;980 u8 var_tag;981 u8 var_len;982 u32 var;983 u8 mech_tag;984 u8 mech_len;985 u32 mech;986 /*987 * maybe followed by iv data988 * followed by key tag + key blob989 * followed by plaintext tag + plaintext990 */991 } __packed * req_pl;992 struct crypt_rep_pl {993 struct pl_head head;994 u8 rc_tag;995 u8 rc_len;996 u32 rc;997 u8 data_tag;998 u8 data_lenfmt;999 /* data follows */1000 } __packed * rep_pl;1001 struct ep11_cprb *req = NULL, *rep = NULL;1002 struct ep11_target_dev target;1003 struct ep11_urb *urb = NULL;1004 size_t req_pl_size, rep_pl_size;1005 int n, api = EP11_API_V1, rc = -ENOMEM;1006 u8 *p;1007 1008 /* the simple asn1 coding used has length limits */1009 if (keysize > 0xFFFF || inbufsize > 0xFFFF)1010 return -EINVAL;1011 1012 /* request cprb and payload */1013 req_pl_size = sizeof(struct crypt_req_pl) + (iv ? 16 : 0)1014 + ASN1TAGLEN(keysize) + ASN1TAGLEN(inbufsize);1015 req = alloc_cprb(req_pl_size);1016 if (!req)1017 goto out;1018 req_pl = (struct crypt_req_pl *)(((u8 *)req) + sizeof(*req));1019 prep_head(&req_pl->head, req_pl_size, api, (mode ? 20 : 19));1020 req_pl->var_tag = 0x04;1021 req_pl->var_len = sizeof(u32);1022 /* mech is mech + mech params (iv here) */1023 req_pl->mech_tag = 0x04;1024 req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);1025 req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */1026 p = ((u8 *)req_pl) + sizeof(*req_pl);1027 if (iv) {1028 memcpy(p, iv, 16);1029 p += 16;1030 }1031 /* key and input data */1032 p += asn1tag_write(p, 0x04, key, keysize);1033 p += asn1tag_write(p, 0x04, inbuf, inbufsize);1034 1035 /* reply cprb and payload, assume out data size <= in data size + 32 */1036 rep_pl_size = sizeof(struct crypt_rep_pl) + ASN1TAGLEN(inbufsize + 32);1037 rep = alloc_cprb(rep_pl_size);1038 if (!rep)1039 goto out;1040 rep_pl = (struct crypt_rep_pl *)(((u8 *)rep) + sizeof(*rep));1041 1042 /* urb and target */1043 urb = kmalloc(sizeof(*urb), GFP_KERNEL);1044 if (!urb)1045 goto out;1046 target.ap_id = card;1047 target.dom_id = domain;1048 prep_urb(urb, &target, 1,1049 req, sizeof(*req) + req_pl_size,1050 rep, sizeof(*rep) + rep_pl_size);1051 1052 rc = zcrypt_send_ep11_cprb(urb);1053 if (rc) {1054 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",1055 __func__, (int)card, (int)domain, rc);1056 goto out;1057 }1058 1059 /* check ep11 reply cprb */1060 rc = check_reply_cprb(rep, __func__);1061 if (rc)1062 goto out;1063 1064 /* check payload */1065 rc = check_reply_pl((u8 *)rep_pl, __func__);1066 if (rc)1067 goto out;1068 if (rep_pl->data_tag != 0x04) {1069 ZCRYPT_DBF_ERR("%s unknown reply data format\n", __func__);1070 rc = -EIO;1071 goto out;1072 }1073 p = ((u8 *)rep_pl) + sizeof(*rep_pl);1074 if (rep_pl->data_lenfmt <= 127) {1075 n = rep_pl->data_lenfmt;1076 } else if (rep_pl->data_lenfmt == 0x81) {1077 n = *p++;1078 } else if (rep_pl->data_lenfmt == 0x82) {1079 n = *((u16 *)p);1080 p += 2;1081 } else {1082 ZCRYPT_DBF_ERR("%s unknown reply data length format 0x%02hhx\n",1083 __func__, rep_pl->data_lenfmt);1084 rc = -EIO;1085 goto out;1086 }1087 if (n > *outbufsize) {1088 ZCRYPT_DBF_ERR("%s mismatch reply data len %d / output buffer %zu\n",1089 __func__, n, *outbufsize);1090 rc = -ENOSPC;1091 goto out;1092 }1093 1094 memcpy(outbuf, p, n);1095 *outbufsize = n;1096 1097out:1098 kfree(req);1099 kfree(rep);1100 kfree(urb);1101 return rc;1102}1103 1104static int _ep11_unwrapkey(u16 card, u16 domain,1105 const u8 *kek, size_t keksize,1106 const u8 *enckey, size_t enckeysize,1107 u32 mech, const u8 *iv,1108 u32 keybitsize, u32 keygenflags,1109 u8 *keybuf, size_t *keybufsize)1110{1111 struct uw_req_pl {1112 struct pl_head head;1113 u8 attr_tag;1114 u8 attr_len;1115 u32 attr_header;1116 u32 attr_bool_mask;1117 u32 attr_bool_bits;1118 u32 attr_key_type;1119 u32 attr_key_type_value;1120 u32 attr_val_len;1121 u32 attr_val_len_value;1122 u8 mech_tag;1123 u8 mech_len;1124 u32 mech;1125 /*1126 * maybe followed by iv data1127 * followed by kek tag + kek blob1128 * followed by empty mac tag1129 * followed by empty pin tag or empty pinblob tag1130 * followed by encryted key tag + bytes1131 */1132 } __packed * req_pl;1133 struct uw_rep_pl {1134 struct pl_head head;1135 u8 rc_tag;1136 u8 rc_len;1137 u32 rc;1138 u8 data_tag;1139 u8 data_lenfmt;1140 u16 data_len;1141 u8 data[512];1142 } __packed * rep_pl;1143 struct ep11_cprb *req = NULL, *rep = NULL;1144 size_t req_pl_size, pinblob_size = 0;1145 struct ep11_target_dev target;1146 struct ep11_urb *urb = NULL;1147 int api, rc = -ENOMEM;1148 u8 *p;1149 1150 /* request cprb and payload */1151 api = (!keygenflags || keygenflags & 0x00200000) ?1152 EP11_API_V4 : EP11_API_V1;1153 if (ap_is_se_guest()) {1154 /*1155 * unwrap within SE environment requires API ordinal 61156 * with empty pinblob1157 */1158 api = EP11_API_V6;1159 pinblob_size = EP11_PINBLOB_V1_BYTES;1160 }1161 req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0)1162 + ASN1TAGLEN(keksize) + ASN1TAGLEN(0)1163 + ASN1TAGLEN(pinblob_size) + ASN1TAGLEN(enckeysize);1164 req = alloc_cprb(req_pl_size);1165 if (!req)1166 goto out;1167 req_pl = (struct uw_req_pl *)(((u8 *)req) + sizeof(*req));1168 prep_head(&req_pl->head, req_pl_size, api, 34); /* UnwrapKey */1169 req_pl->attr_tag = 0x04;1170 req_pl->attr_len = 7 * sizeof(u32);1171 req_pl->attr_header = 0x10020000;1172 req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;1173 req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;1174 req_pl->attr_key_type = 0x00000100; /* CKA_KEY_TYPE */1175 req_pl->attr_key_type_value = 0x0000001f; /* CKK_AES */1176 req_pl->attr_val_len = 0x00000161; /* CKA_VALUE_LEN */1177 req_pl->attr_val_len_value = keybitsize / 8;1178 /* mech is mech + mech params (iv here) */1179 req_pl->mech_tag = 0x04;1180 req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);1181 req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */1182 p = ((u8 *)req_pl) + sizeof(*req_pl);1183 if (iv) {1184 memcpy(p, iv, 16);1185 p += 16;1186 }1187 /* kek */1188 p += asn1tag_write(p, 0x04, kek, keksize);1189 /* empty mac key tag */1190 *p++ = 0x04;1191 *p++ = 0;1192 /* pin tag */1193 *p++ = 0x04;1194 *p++ = pinblob_size;1195 p += pinblob_size;1196 /* encrypted key value tag and bytes */1197 p += asn1tag_write(p, 0x04, enckey, enckeysize);1198 1199 /* reply cprb and payload */1200 rep = alloc_cprb(sizeof(struct uw_rep_pl));1201 if (!rep)1202 goto out;1203 rep_pl = (struct uw_rep_pl *)(((u8 *)rep) + sizeof(*rep));1204 1205 /* urb and target */1206 urb = kmalloc(sizeof(*urb), GFP_KERNEL);1207 if (!urb)1208 goto out;1209 target.ap_id = card;1210 target.dom_id = domain;1211 prep_urb(urb, &target, 1,1212 req, sizeof(*req) + req_pl_size,1213 rep, sizeof(*rep) + sizeof(*rep_pl));1214 1215 rc = zcrypt_send_ep11_cprb(urb);1216 if (rc) {1217 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",1218 __func__, (int)card, (int)domain, rc);1219 goto out;1220 }1221 1222 /* check ep11 reply cprb */1223 rc = check_reply_cprb(rep, __func__);1224 if (rc)1225 goto out;1226 1227 /* check payload */1228 rc = check_reply_pl((u8 *)rep_pl, __func__);1229 if (rc)1230 goto out;1231 if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {1232 ZCRYPT_DBF_ERR("%s unknown reply data format\n", __func__);1233 rc = -EIO;1234 goto out;1235 }1236 if (rep_pl->data_len > *keybufsize) {1237 ZCRYPT_DBF_ERR("%s mismatch reply data len / key buffer len\n",1238 __func__);1239 rc = -ENOSPC;1240 goto out;1241 }1242 1243 /* copy key blob */1244 memcpy(keybuf, rep_pl->data, rep_pl->data_len);1245 *keybufsize = rep_pl->data_len;1246 1247out:1248 kfree(req);1249 kfree(rep);1250 kfree(urb);1251 return rc;1252}1253 1254static int ep11_unwrapkey(u16 card, u16 domain,1255 const u8 *kek, size_t keksize,1256 const u8 *enckey, size_t enckeysize,1257 u32 mech, const u8 *iv,1258 u32 keybitsize, u32 keygenflags,1259 u8 *keybuf, u32 *keybufsize,1260 u8 keybufver)1261{1262 struct ep11kblob_header *hdr;1263 size_t hdr_size, pl_size;1264 u8 *pl;1265 int rc;1266 1267 rc = ep11_kb_split(keybuf, *keybufsize, keybufver,1268 &hdr, &hdr_size, &pl, &pl_size);1269 if (rc)1270 return rc;1271 1272 rc = _ep11_unwrapkey(card, domain, kek, keksize, enckey, enckeysize,1273 mech, iv, keybitsize, keygenflags,1274 pl, &pl_size);1275 if (rc)1276 return rc;1277 1278 *keybufsize = hdr_size + pl_size;1279 1280 /* update header information */1281 hdr = (struct ep11kblob_header *)keybuf;1282 hdr->type = TOKTYPE_NON_CCA;1283 hdr->len = *keybufsize;1284 hdr->version = keybufver;1285 hdr->bitlen = keybitsize;1286 1287 return 0;1288}1289 1290static int _ep11_wrapkey(u16 card, u16 domain,1291 const u8 *key, size_t keysize,1292 u32 mech, const u8 *iv,1293 u8 *databuf, size_t *datasize)1294{1295 struct wk_req_pl {1296 struct pl_head head;1297 u8 var_tag;1298 u8 var_len;1299 u32 var;1300 u8 mech_tag;1301 u8 mech_len;1302 u32 mech;1303 /*1304 * followed by iv data1305 * followed by key tag + key blob1306 * followed by dummy kek param1307 * followed by dummy mac param1308 */1309 } __packed * req_pl;1310 struct wk_rep_pl {1311 struct pl_head head;1312 u8 rc_tag;1313 u8 rc_len;1314 u32 rc;1315 u8 data_tag;1316 u8 data_lenfmt;1317 u16 data_len;1318 u8 data[1024];1319 } __packed * rep_pl;1320 struct ep11_cprb *req = NULL, *rep = NULL;1321 struct ep11_target_dev target;1322 struct ep11_urb *urb = NULL;1323 size_t req_pl_size;1324 int api, rc = -ENOMEM;1325 u8 *p;1326 1327 /* request cprb and payload */1328 req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0)1329 + ASN1TAGLEN(keysize) + 4;1330 req = alloc_cprb(req_pl_size);1331 if (!req)1332 goto out;1333 if (!mech || mech == 0x80060001)1334 req->flags |= 0x20; /* CPACF_WRAP needs special bit */1335 req_pl = (struct wk_req_pl *)(((u8 *)req) + sizeof(*req));1336 api = (!mech || mech == 0x80060001) ? /* CKM_IBM_CPACF_WRAP */1337 EP11_API_V4 : EP11_API_V1;1338 prep_head(&req_pl->head, req_pl_size, api, 33); /* WrapKey */1339 req_pl->var_tag = 0x04;1340 req_pl->var_len = sizeof(u32);1341 /* mech is mech + mech params (iv here) */1342 req_pl->mech_tag = 0x04;1343 req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);1344 req_pl->mech = (mech ? mech : 0x80060001); /* CKM_IBM_CPACF_WRAP */1345 p = ((u8 *)req_pl) + sizeof(*req_pl);1346 if (iv) {1347 memcpy(p, iv, 16);1348 p += 16;1349 }1350 /* key blob */1351 p += asn1tag_write(p, 0x04, key, keysize);1352 /* empty kek tag */1353 *p++ = 0x04;1354 *p++ = 0;1355 /* empty mac tag */1356 *p++ = 0x04;1357 *p++ = 0;1358 1359 /* reply cprb and payload */1360 rep = alloc_cprb(sizeof(struct wk_rep_pl));1361 if (!rep)1362 goto out;1363 rep_pl = (struct wk_rep_pl *)(((u8 *)rep) + sizeof(*rep));1364 1365 /* urb and target */1366 urb = kmalloc(sizeof(*urb), GFP_KERNEL);1367 if (!urb)1368 goto out;1369 target.ap_id = card;1370 target.dom_id = domain;1371 prep_urb(urb, &target, 1,1372 req, sizeof(*req) + req_pl_size,1373 rep, sizeof(*rep) + sizeof(*rep_pl));1374 1375 rc = zcrypt_send_ep11_cprb(urb);1376 if (rc) {1377 ZCRYPT_DBF_ERR("%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",1378 __func__, (int)card, (int)domain, rc);1379 goto out;1380 }1381 1382 /* check ep11 reply cprb */1383 rc = check_reply_cprb(rep, __func__);1384 if (rc)1385 goto out;1386 1387 /* check payload */1388 rc = check_reply_pl((u8 *)rep_pl, __func__);1389 if (rc)1390 goto out;1391 if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {1392 ZCRYPT_DBF_ERR("%s unknown reply data format\n", __func__);1393 rc = -EIO;1394 goto out;1395 }1396 if (rep_pl->data_len > *datasize) {1397 ZCRYPT_DBF_ERR("%s mismatch reply data len / data buffer len\n",1398 __func__);1399 rc = -ENOSPC;1400 goto out;1401 }1402 1403 /* copy the data from the cprb to the data buffer */1404 memcpy(databuf, rep_pl->data, rep_pl->data_len);1405 *datasize = rep_pl->data_len;1406 1407out:1408 kfree(req);1409 kfree(rep);1410 kfree(urb);1411 return rc;1412}1413 1414int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,1415 const u8 *clrkey, u8 *keybuf, u32 *keybufsize,1416 u32 keytype)1417{1418 int rc;1419 u8 encbuf[64], *kek = NULL;1420 size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);1421 1422 if (keybitsize == 128 || keybitsize == 192 || keybitsize == 256) {1423 clrkeylen = keybitsize / 8;1424 } else {1425 ZCRYPT_DBF_ERR("%s unknown/unsupported keybitsize %d\n",1426 __func__, keybitsize);1427 return -EINVAL;1428 }1429 1430 /* allocate memory for the temp kek */1431 keklen = MAXEP11AESKEYBLOBSIZE;1432 kek = kmalloc(keklen, GFP_ATOMIC);1433 if (!kek) {1434 rc = -ENOMEM;1435 goto out;1436 }1437 1438 /* Step 1: generate AES 256 bit random kek key */1439 rc = _ep11_genaeskey(card, domain, 256,1440 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */1441 kek, &keklen);1442 if (rc) {1443 ZCRYPT_DBF_ERR("%s generate kek key failed, rc=%d\n",1444 __func__, rc);1445 goto out;1446 }1447 1448 /* Step 2: encrypt clear key value with the kek key */1449 rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen,1450 clrkey, clrkeylen, encbuf, &encbuflen);1451 if (rc) {1452 ZCRYPT_DBF_ERR("%s encrypting key value with kek key failed, rc=%d\n",1453 __func__, rc);1454 goto out;1455 }1456 1457 /* Step 3: import the encrypted key value as a new key */1458 rc = ep11_unwrapkey(card, domain, kek, keklen,1459 encbuf, encbuflen, 0, def_iv,1460 keybitsize, 0, keybuf, keybufsize, keytype);1461 if (rc) {1462 ZCRYPT_DBF_ERR("%s importing key value as new key failed,, rc=%d\n",1463 __func__, rc);1464 goto out;1465 }1466 1467out:1468 kfree(kek);1469 return rc;1470}1471EXPORT_SYMBOL(ep11_clr2keyblob);1472 1473int ep11_kblob2protkey(u16 card, u16 dom,1474 const u8 *keyblob, u32 keybloblen,1475 u8 *protkey, u32 *protkeylen, u32 *protkeytype)1476{1477 struct ep11kblob_header *hdr;1478 struct ep11keyblob *key;1479 size_t wkbuflen, keylen;1480 struct wk_info {1481 u16 version;1482 u8 res1[16];1483 u32 pkeytype;1484 u32 pkeybitsize;1485 u64 pkeysize;1486 u8 res2[8];1487 u8 pkey[];1488 } __packed * wki;1489 u8 *wkbuf = NULL;1490 int rc = -EIO;1491 1492 if (ep11_kb_decode((u8 *)keyblob, keybloblen, &hdr, NULL, &key, &keylen))1493 return -EINVAL;1494 1495 if (hdr->version == TOKVER_EP11_AES) {1496 /* wipe overlayed header */1497 memset(hdr, 0, sizeof(*hdr));1498 }1499 /* !!! hdr is no longer a valid header !!! */1500 1501 /* alloc temp working buffer */1502 wkbuflen = (keylen + AES_BLOCK_SIZE) & (~(AES_BLOCK_SIZE - 1));1503 wkbuf = kmalloc(wkbuflen, GFP_ATOMIC);1504 if (!wkbuf)1505 return -ENOMEM;1506 1507 /* ep11 secure key -> protected key + info */1508 rc = _ep11_wrapkey(card, dom, (u8 *)key, keylen,1509 0, def_iv, wkbuf, &wkbuflen);1510 if (rc) {1511 ZCRYPT_DBF_ERR("%s rewrapping ep11 key to pkey failed, rc=%d\n",1512 __func__, rc);1513 goto out;1514 }1515 wki = (struct wk_info *)wkbuf;1516 1517 /* check struct version and pkey type */1518 if (wki->version != 1 || wki->pkeytype < 1 || wki->pkeytype > 5) {1519 ZCRYPT_DBF_ERR("%s wk info version %d or pkeytype %d mismatch.\n",1520 __func__, (int)wki->version, (int)wki->pkeytype);1521 rc = -EIO;1522 goto out;1523 }1524 1525 /* check protected key type field */1526 switch (wki->pkeytype) {1527 case 1: /* AES */1528 switch (wki->pkeysize) {1529 case 16 + 32:1530 /* AES 128 protected key */1531 if (protkeytype)1532 *protkeytype = PKEY_KEYTYPE_AES_128;1533 break;1534 case 24 + 32:1535 /* AES 192 protected key */1536 if (protkeytype)1537 *protkeytype = PKEY_KEYTYPE_AES_192;1538 break;1539 case 32 + 32:1540 /* AES 256 protected key */1541 if (protkeytype)1542 *protkeytype = PKEY_KEYTYPE_AES_256;1543 break;1544 default:1545 ZCRYPT_DBF_ERR("%s unknown/unsupported AES pkeysize %d\n",1546 __func__, (int)wki->pkeysize);1547 rc = -EIO;1548 goto out;1549 }1550 break;1551 case 3: /* EC-P */1552 case 4: /* EC-ED */1553 case 5: /* EC-BP */1554 if (protkeytype)1555 *protkeytype = PKEY_KEYTYPE_ECC;1556 break;1557 case 2: /* TDES */1558 default:1559 ZCRYPT_DBF_ERR("%s unknown/unsupported key type %d\n",1560 __func__, (int)wki->pkeytype);1561 rc = -EIO;1562 goto out;1563 }1564 1565 /* copy the translated protected key */1566 if (wki->pkeysize > *protkeylen) {1567 ZCRYPT_DBF_ERR("%s wk info pkeysize %llu > protkeysize %u\n",1568 __func__, wki->pkeysize, *protkeylen);1569 rc = -EINVAL;1570 goto out;1571 }1572 memcpy(protkey, wki->pkey, wki->pkeysize);1573 *protkeylen = wki->pkeysize;1574 1575out:1576 kfree(wkbuf);1577 return rc;1578}1579EXPORT_SYMBOL(ep11_kblob2protkey);1580 1581int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,1582 int minhwtype, int minapi, const u8 *wkvp)1583{1584 struct zcrypt_device_status_ext *device_status;1585 u32 *_apqns = NULL, _nr_apqns = 0;1586 int i, card, dom, rc = -ENOMEM;1587 struct ep11_domain_info edi;1588 struct ep11_card_info eci;1589 1590 /* fetch status of all crypto cards */1591 device_status = kvcalloc(MAX_ZDEV_ENTRIES_EXT,1592 sizeof(struct zcrypt_device_status_ext),1593 GFP_KERNEL);1594 if (!device_status)1595 return -ENOMEM;1596 zcrypt_device_status_mask_ext(device_status);1597 1598 /* allocate 1k space for up to 256 apqns */1599 _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);1600 if (!_apqns) {1601 kvfree(device_status);1602 return -ENOMEM;1603 }1604 1605 /* walk through all the crypto apqnss */1606 for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {1607 card = AP_QID_CARD(device_status[i].qid);1608 dom = AP_QID_QUEUE(device_status[i].qid);1609 /* check online state */1610 if (!device_status[i].online)1611 continue;1612 /* check for ep11 functions */1613 if (!(device_status[i].functions & 0x01))1614 continue;1615 /* check cardnr */1616 if (cardnr != 0xFFFF && card != cardnr)1617 continue;1618 /* check domain */1619 if (domain != 0xFFFF && dom != domain)1620 continue;1621 /* check min hardware type */1622 if (minhwtype && device_status[i].hwtype < minhwtype)1623 continue;1624 /* check min api version if given */1625 if (minapi > 0) {1626 if (ep11_get_card_info(card, &eci, 0))1627 continue;1628 if (minapi > eci.API_ord_nr)1629 continue;1630 }1631 /* check wkvp if given */1632 if (wkvp) {1633 if (ep11_get_domain_info(card, dom, &edi))1634 continue;1635 if (edi.cur_wk_state != '1')1636 continue;1637 if (memcmp(wkvp, edi.cur_wkvp, 16))1638 continue;1639 }1640 /* apqn passed all filtering criterons, add to the array */1641 if (_nr_apqns < 256)1642 _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16)dom);1643 }1644 1645 /* nothing found ? */1646 if (!_nr_apqns) {1647 kfree(_apqns);1648 rc = -ENODEV;1649 } else {1650 /* no re-allocation, simple return the _apqns array */1651 *apqns = _apqns;1652 *nr_apqns = _nr_apqns;1653 rc = 0;1654 }1655 1656 kvfree(device_status);1657 return rc;1658}1659EXPORT_SYMBOL(ep11_findcard2);1660 1661void __exit zcrypt_ep11misc_exit(void)1662{1663 card_cache_free();1664}1665