186fbf5e2SHarald Freudenberger // SPDX-License-Identifier: GPL-2.0 286fbf5e2SHarald Freudenberger /* 386fbf5e2SHarald Freudenberger * pkey cca specific code 486fbf5e2SHarald Freudenberger * 586fbf5e2SHarald Freudenberger * Copyright IBM Corp. 2024 686fbf5e2SHarald Freudenberger */ 786fbf5e2SHarald Freudenberger 886fbf5e2SHarald Freudenberger #define KMSG_COMPONENT "pkey" 986fbf5e2SHarald Freudenberger #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 1086fbf5e2SHarald Freudenberger 1186fbf5e2SHarald Freudenberger #include "zcrypt_api.h" 1286fbf5e2SHarald Freudenberger #include "zcrypt_ccamisc.h" 1386fbf5e2SHarald Freudenberger 1486fbf5e2SHarald Freudenberger #include "pkey_base.h" 1586fbf5e2SHarald Freudenberger 1686fbf5e2SHarald Freudenberger /* 1786fbf5e2SHarald Freudenberger * Check key blob for known and supported CCA key. 1886fbf5e2SHarald Freudenberger */ 1986fbf5e2SHarald Freudenberger bool pkey_is_cca_key(const u8 *key, u32 keylen) 2086fbf5e2SHarald Freudenberger { 2186fbf5e2SHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 2286fbf5e2SHarald Freudenberger 2386fbf5e2SHarald Freudenberger if (keylen < sizeof(*hdr)) 2486fbf5e2SHarald Freudenberger return false; 2586fbf5e2SHarald Freudenberger 2686fbf5e2SHarald Freudenberger switch (hdr->type) { 2786fbf5e2SHarald Freudenberger case TOKTYPE_CCA_INTERNAL: 2886fbf5e2SHarald Freudenberger switch (hdr->version) { 2986fbf5e2SHarald Freudenberger case TOKVER_CCA_AES: 3086fbf5e2SHarald Freudenberger case TOKVER_CCA_VLSC: 3186fbf5e2SHarald Freudenberger return true; 3286fbf5e2SHarald Freudenberger default: 3386fbf5e2SHarald Freudenberger return false; 3486fbf5e2SHarald Freudenberger } 3586fbf5e2SHarald Freudenberger case TOKTYPE_CCA_INTERNAL_PKA: 3686fbf5e2SHarald Freudenberger return true; 3786fbf5e2SHarald Freudenberger default: 3886fbf5e2SHarald Freudenberger return false; 3986fbf5e2SHarald Freudenberger } 4086fbf5e2SHarald Freudenberger } 4186fbf5e2SHarald Freudenberger 4286fbf5e2SHarald Freudenberger bool pkey_is_cca_keytype(enum pkey_key_type key_type) 4386fbf5e2SHarald Freudenberger { 4486fbf5e2SHarald Freudenberger switch (key_type) { 4586fbf5e2SHarald Freudenberger case PKEY_TYPE_CCA_DATA: 4686fbf5e2SHarald Freudenberger case PKEY_TYPE_CCA_CIPHER: 4786fbf5e2SHarald Freudenberger case PKEY_TYPE_CCA_ECC: 4886fbf5e2SHarald Freudenberger return true; 4986fbf5e2SHarald Freudenberger default: 5086fbf5e2SHarald Freudenberger return false; 5186fbf5e2SHarald Freudenberger } 5286fbf5e2SHarald Freudenberger } 5386fbf5e2SHarald Freudenberger 5486fbf5e2SHarald Freudenberger int pkey_cca_key2protkey(u16 card, u16 dom, 5586fbf5e2SHarald Freudenberger const u8 *key, u32 keylen, 5686fbf5e2SHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 5786fbf5e2SHarald Freudenberger { 5886fbf5e2SHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 5986fbf5e2SHarald Freudenberger int rc; 6086fbf5e2SHarald Freudenberger 6186fbf5e2SHarald Freudenberger if (keylen < sizeof(*hdr)) 6286fbf5e2SHarald Freudenberger return -EINVAL; 6386fbf5e2SHarald Freudenberger 6486fbf5e2SHarald Freudenberger zcrypt_wait_api_operational(); 6586fbf5e2SHarald Freudenberger 6686fbf5e2SHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL && 6786fbf5e2SHarald Freudenberger hdr->version == TOKVER_CCA_AES) { 6886fbf5e2SHarald Freudenberger /* CCA AES data key */ 6986fbf5e2SHarald Freudenberger if (keylen != sizeof(struct secaeskeytoken)) 7086fbf5e2SHarald Freudenberger return -EINVAL; 7186fbf5e2SHarald Freudenberger if (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0)) 7286fbf5e2SHarald Freudenberger return -EINVAL; 7386fbf5e2SHarald Freudenberger rc = cca_sec2protkey(card, dom, key, protkey, 7486fbf5e2SHarald Freudenberger protkeylen, protkeytype); 7586fbf5e2SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 7686fbf5e2SHarald Freudenberger hdr->version == TOKVER_CCA_VLSC) { 7786fbf5e2SHarald Freudenberger /* CCA AES cipher key */ 7886fbf5e2SHarald Freudenberger if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 7986fbf5e2SHarald Freudenberger return -EINVAL; 8086fbf5e2SHarald Freudenberger if (cca_check_secaescipherkey(pkey_dbf_info, 8186fbf5e2SHarald Freudenberger 3, key, 0, 1)) 8286fbf5e2SHarald Freudenberger return -EINVAL; 8386fbf5e2SHarald Freudenberger rc = cca_cipher2protkey(card, dom, key, protkey, 8486fbf5e2SHarald Freudenberger protkeylen, protkeytype); 8586fbf5e2SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 8686fbf5e2SHarald Freudenberger /* CCA ECC (private) key */ 8786fbf5e2SHarald Freudenberger if (keylen < sizeof(struct eccprivkeytoken)) 8886fbf5e2SHarald Freudenberger return -EINVAL; 8986fbf5e2SHarald Freudenberger if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1)) 9086fbf5e2SHarald Freudenberger return -EINVAL; 9186fbf5e2SHarald Freudenberger rc = cca_ecc2protkey(card, dom, key, protkey, 9286fbf5e2SHarald Freudenberger protkeylen, protkeytype); 9386fbf5e2SHarald Freudenberger } else { 9486fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n", 9586fbf5e2SHarald Freudenberger __func__, hdr->type, hdr->version); 9686fbf5e2SHarald Freudenberger rc = -EINVAL; 9786fbf5e2SHarald Freudenberger } 9886fbf5e2SHarald Freudenberger 9986fbf5e2SHarald Freudenberger pr_debug("card=%d dom=%d rc=%d\n", card, dom, rc); 10086fbf5e2SHarald Freudenberger return rc; 10186fbf5e2SHarald Freudenberger } 10286fbf5e2SHarald Freudenberger 10386fbf5e2SHarald Freudenberger /* 10486fbf5e2SHarald Freudenberger * Generate CCA secure key. 10586fbf5e2SHarald Freudenberger * As of now only CCA AES Data or Cipher secure keys are 10686fbf5e2SHarald Freudenberger * supported. 10786fbf5e2SHarald Freudenberger * keytype is one of the PKEY_KEYTYPE_* constants, 10886fbf5e2SHarald Freudenberger * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER, 10986fbf5e2SHarald Freudenberger * keybitsize is the bit size of the key (may be 0 for 11086fbf5e2SHarald Freudenberger * keytype PKEY_KEYTYPE_AES_*). 11186fbf5e2SHarald Freudenberger */ 11286fbf5e2SHarald Freudenberger int pkey_cca_gen_key(u16 card, u16 dom, 11386fbf5e2SHarald Freudenberger u32 keytype, u32 subtype, 11486fbf5e2SHarald Freudenberger u32 keybitsize, u32 flags, 115*ea88e171SHarald Freudenberger u8 *keybuf, u32 *keybuflen, u32 *_keyinfo) 11686fbf5e2SHarald Freudenberger { 11786fbf5e2SHarald Freudenberger int len, rc; 11886fbf5e2SHarald Freudenberger 11986fbf5e2SHarald Freudenberger /* check keytype, subtype, keybitsize */ 12086fbf5e2SHarald Freudenberger switch (keytype) { 12186fbf5e2SHarald Freudenberger case PKEY_KEYTYPE_AES_128: 12286fbf5e2SHarald Freudenberger case PKEY_KEYTYPE_AES_192: 12386fbf5e2SHarald Freudenberger case PKEY_KEYTYPE_AES_256: 12486fbf5e2SHarald Freudenberger len = pkey_keytype_aes_to_size(keytype); 12586fbf5e2SHarald Freudenberger if (keybitsize && keybitsize != 8 * len) { 12686fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 12786fbf5e2SHarald Freudenberger __func__, keybitsize); 12886fbf5e2SHarald Freudenberger return -EINVAL; 12986fbf5e2SHarald Freudenberger } 13086fbf5e2SHarald Freudenberger keybitsize = 8 * len; 13186fbf5e2SHarald Freudenberger switch (subtype) { 13286fbf5e2SHarald Freudenberger case 0: 13386fbf5e2SHarald Freudenberger case PKEY_TYPE_CCA_DATA: 13486fbf5e2SHarald Freudenberger case PKEY_TYPE_CCA_CIPHER: 13586fbf5e2SHarald Freudenberger break; 13686fbf5e2SHarald Freudenberger default: 13786fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", 13886fbf5e2SHarald Freudenberger __func__, subtype); 13986fbf5e2SHarald Freudenberger return -EINVAL; 14086fbf5e2SHarald Freudenberger } 14186fbf5e2SHarald Freudenberger break; 14286fbf5e2SHarald Freudenberger default: 14386fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", 14486fbf5e2SHarald Freudenberger __func__, keytype); 14586fbf5e2SHarald Freudenberger return -EINVAL; 14686fbf5e2SHarald Freudenberger } 14786fbf5e2SHarald Freudenberger 14886fbf5e2SHarald Freudenberger zcrypt_wait_api_operational(); 14986fbf5e2SHarald Freudenberger 15086fbf5e2SHarald Freudenberger if (subtype == PKEY_TYPE_CCA_CIPHER) { 15186fbf5e2SHarald Freudenberger rc = cca_gencipherkey(card, dom, keybitsize, flags, 15286fbf5e2SHarald Freudenberger keybuf, keybuflen); 15386fbf5e2SHarald Freudenberger } else { 15486fbf5e2SHarald Freudenberger /* 0 or PKEY_TYPE_CCA_DATA */ 15586fbf5e2SHarald Freudenberger rc = cca_genseckey(card, dom, keybitsize, keybuf); 15686fbf5e2SHarald Freudenberger *keybuflen = (rc ? 0 : SECKEYBLOBSIZE); 15786fbf5e2SHarald Freudenberger } 15886fbf5e2SHarald Freudenberger 15986fbf5e2SHarald Freudenberger pr_debug("card=%d dom=%d rc=%d\n", card, dom, rc); 16086fbf5e2SHarald Freudenberger return rc; 16186fbf5e2SHarald Freudenberger } 16286fbf5e2SHarald Freudenberger 16386fbf5e2SHarald Freudenberger /* 16486fbf5e2SHarald Freudenberger * Generate CCA secure key with given clear key value. 16586fbf5e2SHarald Freudenberger * As of now only CCA AES Data or Cipher secure keys are 16686fbf5e2SHarald Freudenberger * supported. 16786fbf5e2SHarald Freudenberger * keytype is one of the PKEY_KEYTYPE_* constants, 16886fbf5e2SHarald Freudenberger * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER, 16986fbf5e2SHarald Freudenberger * keybitsize is the bit size of the key (may be 0 for 17086fbf5e2SHarald Freudenberger * keytype PKEY_KEYTYPE_AES_*). 17186fbf5e2SHarald Freudenberger */ 17286fbf5e2SHarald Freudenberger int pkey_cca_clr2key(u16 card, u16 dom, 17386fbf5e2SHarald Freudenberger u32 keytype, u32 subtype, 17486fbf5e2SHarald Freudenberger u32 keybitsize, u32 flags, 17586fbf5e2SHarald Freudenberger const u8 *clrkey, u32 clrkeylen, 176*ea88e171SHarald Freudenberger u8 *keybuf, u32 *keybuflen, u32 *_keyinfo) 17786fbf5e2SHarald Freudenberger { 17886fbf5e2SHarald Freudenberger int len, rc; 17986fbf5e2SHarald Freudenberger 18086fbf5e2SHarald Freudenberger /* check keytype, subtype, clrkeylen, keybitsize */ 18186fbf5e2SHarald Freudenberger switch (keytype) { 18286fbf5e2SHarald Freudenberger case PKEY_KEYTYPE_AES_128: 18386fbf5e2SHarald Freudenberger case PKEY_KEYTYPE_AES_192: 18486fbf5e2SHarald Freudenberger case PKEY_KEYTYPE_AES_256: 18586fbf5e2SHarald Freudenberger len = pkey_keytype_aes_to_size(keytype); 18686fbf5e2SHarald Freudenberger if (keybitsize && keybitsize != 8 * len) { 18786fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 18886fbf5e2SHarald Freudenberger __func__, keybitsize); 18986fbf5e2SHarald Freudenberger return -EINVAL; 19086fbf5e2SHarald Freudenberger } 19186fbf5e2SHarald Freudenberger keybitsize = 8 * len; 19286fbf5e2SHarald Freudenberger if (clrkeylen != len) { 19386fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s invalid clear key len %d != %d\n", 19486fbf5e2SHarald Freudenberger __func__, clrkeylen, len); 19586fbf5e2SHarald Freudenberger return -EINVAL; 19686fbf5e2SHarald Freudenberger } 19786fbf5e2SHarald Freudenberger switch (subtype) { 19886fbf5e2SHarald Freudenberger case 0: 19986fbf5e2SHarald Freudenberger case PKEY_TYPE_CCA_DATA: 20086fbf5e2SHarald Freudenberger case PKEY_TYPE_CCA_CIPHER: 20186fbf5e2SHarald Freudenberger break; 20286fbf5e2SHarald Freudenberger default: 20386fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", 20486fbf5e2SHarald Freudenberger __func__, subtype); 20586fbf5e2SHarald Freudenberger return -EINVAL; 20686fbf5e2SHarald Freudenberger } 20786fbf5e2SHarald Freudenberger break; 20886fbf5e2SHarald Freudenberger default: 20986fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", 21086fbf5e2SHarald Freudenberger __func__, keytype); 21186fbf5e2SHarald Freudenberger return -EINVAL; 21286fbf5e2SHarald Freudenberger } 21386fbf5e2SHarald Freudenberger 21486fbf5e2SHarald Freudenberger zcrypt_wait_api_operational(); 21586fbf5e2SHarald Freudenberger 21686fbf5e2SHarald Freudenberger if (subtype == PKEY_TYPE_CCA_CIPHER) { 21786fbf5e2SHarald Freudenberger rc = cca_clr2cipherkey(card, dom, keybitsize, 21886fbf5e2SHarald Freudenberger flags, clrkey, keybuf, keybuflen); 21986fbf5e2SHarald Freudenberger } else { 22086fbf5e2SHarald Freudenberger /* 0 or PKEY_TYPE_CCA_DATA */ 22186fbf5e2SHarald Freudenberger rc = cca_clr2seckey(card, dom, keybitsize, 22286fbf5e2SHarald Freudenberger clrkey, keybuf); 22386fbf5e2SHarald Freudenberger *keybuflen = (rc ? 0 : SECKEYBLOBSIZE); 22486fbf5e2SHarald Freudenberger } 22586fbf5e2SHarald Freudenberger 22686fbf5e2SHarald Freudenberger pr_debug("card=%d dom=%d rc=%d\n", card, dom, rc); 22786fbf5e2SHarald Freudenberger return rc; 22886fbf5e2SHarald Freudenberger } 22986fbf5e2SHarald Freudenberger 23086fbf5e2SHarald Freudenberger int pkey_cca_verifykey(const u8 *key, u32 keylen, 23186fbf5e2SHarald Freudenberger u16 *card, u16 *dom, 23286fbf5e2SHarald Freudenberger u32 *keytype, u32 *keybitsize, u32 *flags) 23386fbf5e2SHarald Freudenberger { 23486fbf5e2SHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 23586fbf5e2SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 23686fbf5e2SHarald Freudenberger int rc; 23786fbf5e2SHarald Freudenberger 23886fbf5e2SHarald Freudenberger if (keylen < sizeof(*hdr)) 23986fbf5e2SHarald Freudenberger return -EINVAL; 24086fbf5e2SHarald Freudenberger 24186fbf5e2SHarald Freudenberger zcrypt_wait_api_operational(); 24286fbf5e2SHarald Freudenberger 24386fbf5e2SHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL && 24486fbf5e2SHarald Freudenberger hdr->version == TOKVER_CCA_AES) { 24586fbf5e2SHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *)key; 24686fbf5e2SHarald Freudenberger 24786fbf5e2SHarald Freudenberger rc = cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0); 24886fbf5e2SHarald Freudenberger if (rc) 24986fbf5e2SHarald Freudenberger goto out; 25086fbf5e2SHarald Freudenberger *keytype = PKEY_TYPE_CCA_DATA; 25186fbf5e2SHarald Freudenberger *keybitsize = t->bitsize; 25286fbf5e2SHarald Freudenberger rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, 25386fbf5e2SHarald Freudenberger ZCRYPT_CEX3C, AES_MK_SET, 25486fbf5e2SHarald Freudenberger t->mkvp, 0, 1); 25586fbf5e2SHarald Freudenberger if (!rc) 25686fbf5e2SHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 25786fbf5e2SHarald Freudenberger if (rc == -ENODEV) { 25886fbf5e2SHarald Freudenberger rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, 25986fbf5e2SHarald Freudenberger ZCRYPT_CEX3C, AES_MK_SET, 26086fbf5e2SHarald Freudenberger 0, t->mkvp, 1); 26186fbf5e2SHarald Freudenberger if (!rc) 26286fbf5e2SHarald Freudenberger *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 26386fbf5e2SHarald Freudenberger } 26486fbf5e2SHarald Freudenberger if (rc) 26586fbf5e2SHarald Freudenberger goto out; 26686fbf5e2SHarald Freudenberger 26786fbf5e2SHarald Freudenberger *card = ((struct pkey_apqn *)apqns)->card; 26886fbf5e2SHarald Freudenberger *dom = ((struct pkey_apqn *)apqns)->domain; 26986fbf5e2SHarald Freudenberger 27086fbf5e2SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 27186fbf5e2SHarald Freudenberger hdr->version == TOKVER_CCA_VLSC) { 27286fbf5e2SHarald Freudenberger struct cipherkeytoken *t = (struct cipherkeytoken *)key; 27386fbf5e2SHarald Freudenberger 27486fbf5e2SHarald Freudenberger rc = cca_check_secaescipherkey(pkey_dbf_info, 3, key, 0, 1); 27586fbf5e2SHarald Freudenberger if (rc) 27686fbf5e2SHarald Freudenberger goto out; 27786fbf5e2SHarald Freudenberger *keytype = PKEY_TYPE_CCA_CIPHER; 27886fbf5e2SHarald Freudenberger *keybitsize = PKEY_SIZE_UNKNOWN; 27986fbf5e2SHarald Freudenberger if (!t->plfver && t->wpllen == 512) 28086fbf5e2SHarald Freudenberger *keybitsize = PKEY_SIZE_AES_128; 28186fbf5e2SHarald Freudenberger else if (!t->plfver && t->wpllen == 576) 28286fbf5e2SHarald Freudenberger *keybitsize = PKEY_SIZE_AES_192; 28386fbf5e2SHarald Freudenberger else if (!t->plfver && t->wpllen == 640) 28486fbf5e2SHarald Freudenberger *keybitsize = PKEY_SIZE_AES_256; 28586fbf5e2SHarald Freudenberger rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, 28686fbf5e2SHarald Freudenberger ZCRYPT_CEX6, AES_MK_SET, 28786fbf5e2SHarald Freudenberger t->mkvp0, 0, 1); 28886fbf5e2SHarald Freudenberger if (!rc) 28986fbf5e2SHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 29086fbf5e2SHarald Freudenberger if (rc == -ENODEV) { 29186fbf5e2SHarald Freudenberger rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom, 29286fbf5e2SHarald Freudenberger ZCRYPT_CEX6, AES_MK_SET, 29386fbf5e2SHarald Freudenberger 0, t->mkvp0, 1); 29486fbf5e2SHarald Freudenberger if (!rc) 29586fbf5e2SHarald Freudenberger *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 29686fbf5e2SHarald Freudenberger } 29786fbf5e2SHarald Freudenberger if (rc) 29886fbf5e2SHarald Freudenberger goto out; 29986fbf5e2SHarald Freudenberger 30086fbf5e2SHarald Freudenberger *card = ((struct pkey_apqn *)apqns)->card; 30186fbf5e2SHarald Freudenberger *dom = ((struct pkey_apqn *)apqns)->domain; 30286fbf5e2SHarald Freudenberger 30386fbf5e2SHarald Freudenberger } else { 30486fbf5e2SHarald Freudenberger /* unknown/unsupported key blob */ 30586fbf5e2SHarald Freudenberger rc = -EINVAL; 30686fbf5e2SHarald Freudenberger } 30786fbf5e2SHarald Freudenberger 30886fbf5e2SHarald Freudenberger out: 30986fbf5e2SHarald Freudenberger kfree(apqns); 31086fbf5e2SHarald Freudenberger pr_debug("rc=%d\n", rc); 31186fbf5e2SHarald Freudenberger return rc; 31286fbf5e2SHarald Freudenberger } 31386fbf5e2SHarald Freudenberger 31486fbf5e2SHarald Freudenberger int pkey_cca_apqns4key(const u8 *key, u32 keylen, u32 flags, 31586fbf5e2SHarald Freudenberger struct pkey_apqn *apqns, size_t *nr_apqns) 31686fbf5e2SHarald Freudenberger { 31786fbf5e2SHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 31886fbf5e2SHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 31986fbf5e2SHarald Freudenberger int rc; 32086fbf5e2SHarald Freudenberger 32186fbf5e2SHarald Freudenberger if (!flags) 32286fbf5e2SHarald Freudenberger flags = PKEY_FLAGS_MATCH_CUR_MKVP | PKEY_FLAGS_MATCH_ALT_MKVP; 32386fbf5e2SHarald Freudenberger 32486fbf5e2SHarald Freudenberger if (keylen < sizeof(struct keytoken_header)) 32586fbf5e2SHarald Freudenberger return -EINVAL; 32686fbf5e2SHarald Freudenberger 32786fbf5e2SHarald Freudenberger zcrypt_wait_api_operational(); 32886fbf5e2SHarald Freudenberger 32986fbf5e2SHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL) { 33086fbf5e2SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 33186fbf5e2SHarald Freudenberger int minhwtype = ZCRYPT_CEX3C; 33286fbf5e2SHarald Freudenberger 33386fbf5e2SHarald Freudenberger if (hdr->version == TOKVER_CCA_AES) { 33486fbf5e2SHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *)key; 33586fbf5e2SHarald Freudenberger 33686fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 33786fbf5e2SHarald Freudenberger cur_mkvp = t->mkvp; 33886fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 33986fbf5e2SHarald Freudenberger old_mkvp = t->mkvp; 34086fbf5e2SHarald Freudenberger } else if (hdr->version == TOKVER_CCA_VLSC) { 34186fbf5e2SHarald Freudenberger struct cipherkeytoken *t = (struct cipherkeytoken *)key; 34286fbf5e2SHarald Freudenberger 34386fbf5e2SHarald Freudenberger minhwtype = ZCRYPT_CEX6; 34486fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 34586fbf5e2SHarald Freudenberger cur_mkvp = t->mkvp0; 34686fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 34786fbf5e2SHarald Freudenberger old_mkvp = t->mkvp0; 34886fbf5e2SHarald Freudenberger } else { 34986fbf5e2SHarald Freudenberger /* unknown CCA internal token type */ 35086fbf5e2SHarald Freudenberger return -EINVAL; 35186fbf5e2SHarald Freudenberger } 35286fbf5e2SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 35386fbf5e2SHarald Freudenberger minhwtype, AES_MK_SET, 35486fbf5e2SHarald Freudenberger cur_mkvp, old_mkvp, 1); 35586fbf5e2SHarald Freudenberger if (rc) 35686fbf5e2SHarald Freudenberger goto out; 35786fbf5e2SHarald Freudenberger 35886fbf5e2SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 35986fbf5e2SHarald Freudenberger struct eccprivkeytoken *t = (struct eccprivkeytoken *)key; 36086fbf5e2SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 36186fbf5e2SHarald Freudenberger 36286fbf5e2SHarald Freudenberger if (t->secid == 0x20) { 36386fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 36486fbf5e2SHarald Freudenberger cur_mkvp = t->mkvp; 36586fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 36686fbf5e2SHarald Freudenberger old_mkvp = t->mkvp; 36786fbf5e2SHarald Freudenberger } else { 36886fbf5e2SHarald Freudenberger /* unknown CCA internal 2 token type */ 36986fbf5e2SHarald Freudenberger return -EINVAL; 37086fbf5e2SHarald Freudenberger } 37186fbf5e2SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 37286fbf5e2SHarald Freudenberger ZCRYPT_CEX7, APKA_MK_SET, 37386fbf5e2SHarald Freudenberger cur_mkvp, old_mkvp, 1); 37486fbf5e2SHarald Freudenberger if (rc) 37586fbf5e2SHarald Freudenberger goto out; 37686fbf5e2SHarald Freudenberger 37786fbf5e2SHarald Freudenberger } else { 37886fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n", 37986fbf5e2SHarald Freudenberger __func__, hdr->type, hdr->version); 38086fbf5e2SHarald Freudenberger return -EINVAL; 38186fbf5e2SHarald Freudenberger } 38286fbf5e2SHarald Freudenberger 38386fbf5e2SHarald Freudenberger if (apqns) { 38486fbf5e2SHarald Freudenberger if (*nr_apqns < _nr_apqns) 38586fbf5e2SHarald Freudenberger rc = -ENOSPC; 38686fbf5e2SHarald Freudenberger else 38786fbf5e2SHarald Freudenberger memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 38886fbf5e2SHarald Freudenberger } 38986fbf5e2SHarald Freudenberger *nr_apqns = _nr_apqns; 39086fbf5e2SHarald Freudenberger 39186fbf5e2SHarald Freudenberger out: 39286fbf5e2SHarald Freudenberger kfree(_apqns); 39386fbf5e2SHarald Freudenberger pr_debug("rc=%d\n", rc); 39486fbf5e2SHarald Freudenberger return rc; 39586fbf5e2SHarald Freudenberger } 39686fbf5e2SHarald Freudenberger 39786fbf5e2SHarald Freudenberger int pkey_cca_apqns4type(enum pkey_key_type ktype, 39886fbf5e2SHarald Freudenberger u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags, 39986fbf5e2SHarald Freudenberger struct pkey_apqn *apqns, size_t *nr_apqns) 40086fbf5e2SHarald Freudenberger { 40186fbf5e2SHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 40286fbf5e2SHarald Freudenberger int rc; 40386fbf5e2SHarald Freudenberger 40486fbf5e2SHarald Freudenberger zcrypt_wait_api_operational(); 40586fbf5e2SHarald Freudenberger 40686fbf5e2SHarald Freudenberger if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) { 40786fbf5e2SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 40886fbf5e2SHarald Freudenberger int minhwtype = ZCRYPT_CEX3C; 40986fbf5e2SHarald Freudenberger 41086fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 41186fbf5e2SHarald Freudenberger cur_mkvp = *((u64 *)cur_mkvp); 41286fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 41386fbf5e2SHarald Freudenberger old_mkvp = *((u64 *)alt_mkvp); 41486fbf5e2SHarald Freudenberger if (ktype == PKEY_TYPE_CCA_CIPHER) 41586fbf5e2SHarald Freudenberger minhwtype = ZCRYPT_CEX6; 41686fbf5e2SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 41786fbf5e2SHarald Freudenberger minhwtype, AES_MK_SET, 41886fbf5e2SHarald Freudenberger cur_mkvp, old_mkvp, 1); 41986fbf5e2SHarald Freudenberger if (rc) 42086fbf5e2SHarald Freudenberger goto out; 42186fbf5e2SHarald Freudenberger 42286fbf5e2SHarald Freudenberger } else if (ktype == PKEY_TYPE_CCA_ECC) { 42386fbf5e2SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 42486fbf5e2SHarald Freudenberger 42586fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 42686fbf5e2SHarald Freudenberger cur_mkvp = *((u64 *)cur_mkvp); 42786fbf5e2SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 42886fbf5e2SHarald Freudenberger old_mkvp = *((u64 *)alt_mkvp); 42986fbf5e2SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 43086fbf5e2SHarald Freudenberger ZCRYPT_CEX7, APKA_MK_SET, 43186fbf5e2SHarald Freudenberger cur_mkvp, old_mkvp, 1); 43286fbf5e2SHarald Freudenberger if (rc) 43386fbf5e2SHarald Freudenberger goto out; 43486fbf5e2SHarald Freudenberger 43586fbf5e2SHarald Freudenberger } else { 43686fbf5e2SHarald Freudenberger PKEY_DBF_ERR("%s unknown/unsupported key type %d", 43786fbf5e2SHarald Freudenberger __func__, (int)ktype); 43886fbf5e2SHarald Freudenberger return -EINVAL; 43986fbf5e2SHarald Freudenberger } 44086fbf5e2SHarald Freudenberger 44186fbf5e2SHarald Freudenberger if (apqns) { 44286fbf5e2SHarald Freudenberger if (*nr_apqns < _nr_apqns) 44386fbf5e2SHarald Freudenberger rc = -ENOSPC; 44486fbf5e2SHarald Freudenberger else 44586fbf5e2SHarald Freudenberger memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 44686fbf5e2SHarald Freudenberger } 44786fbf5e2SHarald Freudenberger *nr_apqns = _nr_apqns; 44886fbf5e2SHarald Freudenberger 44986fbf5e2SHarald Freudenberger out: 45086fbf5e2SHarald Freudenberger kfree(_apqns); 45186fbf5e2SHarald Freudenberger pr_debug("rc=%d\n", rc); 45286fbf5e2SHarald Freudenberger return rc; 45386fbf5e2SHarald Freudenberger } 454