1812141a9SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2e80d4af0SHarald Freudenberger /* 3e80d4af0SHarald Freudenberger * pkey device driver 4e80d4af0SHarald Freudenberger * 59e436c19SHarald Freudenberger * Copyright IBM Corp. 2017, 2023 69e436c19SHarald Freudenberger * 7e80d4af0SHarald Freudenberger * Author(s): Harald Freudenberger 8e80d4af0SHarald Freudenberger */ 9e80d4af0SHarald Freudenberger 10e80d4af0SHarald Freudenberger #define KMSG_COMPONENT "pkey" 11e80d4af0SHarald Freudenberger #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12e80d4af0SHarald Freudenberger 13e80d4af0SHarald Freudenberger #include <linux/fs.h> 14e80d4af0SHarald Freudenberger #include <linux/init.h> 15e80d4af0SHarald Freudenberger #include <linux/miscdevice.h> 16e80d4af0SHarald Freudenberger #include <linux/module.h> 17e80d4af0SHarald Freudenberger #include <linux/slab.h> 18e80d4af0SHarald Freudenberger #include <linux/kallsyms.h> 19e80d4af0SHarald Freudenberger #include <linux/debugfs.h> 20a45a5c7dSIngo Franzki #include <linux/random.h> 2163c19be0SIngo Franzki #include <linux/cpufeature.h> 22e80d4af0SHarald Freudenberger #include <asm/zcrypt.h> 23e80d4af0SHarald Freudenberger #include <asm/cpacf.h> 24e80d4af0SHarald Freudenberger #include <asm/pkey.h> 25cb26b9ffSIngo Franzki #include <crypto/aes.h> 26e80d4af0SHarald Freudenberger 27e80d4af0SHarald Freudenberger #include "zcrypt_api.h" 28efc598e6SHarald Freudenberger #include "zcrypt_ccamisc.h" 2955d0a513SHarald Freudenberger #include "zcrypt_ep11misc.h" 30e80d4af0SHarald Freudenberger 31e80d4af0SHarald Freudenberger MODULE_LICENSE("GPL"); 32e80d4af0SHarald Freudenberger MODULE_AUTHOR("IBM Corporation"); 33e80d4af0SHarald Freudenberger MODULE_DESCRIPTION("s390 protected key interface"); 34e80d4af0SHarald Freudenberger 35f2bbc96eSHarald Freudenberger #define KEYBLOBBUFSIZE 8192 /* key buffer size used for internal processing */ 369e436c19SHarald Freudenberger #define MINKEYBLOBBUFSIZE (sizeof(struct keytoken_header)) 37fa6999e3SHarald Freudenberger #define PROTKEYBLOBBUFSIZE 256 /* protected key buffer size used internal */ 38f2bbc96eSHarald Freudenberger #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ 39f370f45cSHarald Freudenberger #define AES_WK_VP_SIZE 32 /* Size of WK VP block appended to a prot key */ 40f2bbc96eSHarald Freudenberger 41e80d4af0SHarald Freudenberger /* 42e80d4af0SHarald Freudenberger * debug feature data and functions 43e80d4af0SHarald Freudenberger */ 44e80d4af0SHarald Freudenberger 45e80d4af0SHarald Freudenberger static debug_info_t *debug_info; 46e80d4af0SHarald Freudenberger 47e80d4af0SHarald Freudenberger #define DEBUG_DBG(...) debug_sprintf_event(debug_info, 6, ##__VA_ARGS__) 48e80d4af0SHarald Freudenberger #define DEBUG_INFO(...) debug_sprintf_event(debug_info, 5, ##__VA_ARGS__) 49e80d4af0SHarald Freudenberger #define DEBUG_WARN(...) debug_sprintf_event(debug_info, 4, ##__VA_ARGS__) 50e80d4af0SHarald Freudenberger #define DEBUG_ERR(...) debug_sprintf_event(debug_info, 3, ##__VA_ARGS__) 51e80d4af0SHarald Freudenberger 52e80d4af0SHarald Freudenberger static void __init pkey_debug_init(void) 53e80d4af0SHarald Freudenberger { 546b1f16baSHarald Freudenberger /* 5 arguments per dbf entry (including the format string ptr) */ 556b1f16baSHarald Freudenberger debug_info = debug_register("pkey", 1, 1, 5 * sizeof(long)); 56e80d4af0SHarald Freudenberger debug_register_view(debug_info, &debug_sprintf_view); 57e80d4af0SHarald Freudenberger debug_set_level(debug_info, 3); 58e80d4af0SHarald Freudenberger } 59e80d4af0SHarald Freudenberger 60e80d4af0SHarald Freudenberger static void __exit pkey_debug_exit(void) 61e80d4af0SHarald Freudenberger { 62e80d4af0SHarald Freudenberger debug_unregister(debug_info); 63e80d4af0SHarald Freudenberger } 64e80d4af0SHarald Freudenberger 650534bde7SIngo Franzki /* inside view of a protected key token (only type 0x00 version 0x01) */ 660534bde7SIngo Franzki struct protaeskeytoken { 670534bde7SIngo Franzki u8 type; /* 0x00 for PAES specific key tokens */ 680534bde7SIngo Franzki u8 res0[3]; 690534bde7SIngo Franzki u8 version; /* should be 0x01 for protected AES key token */ 700534bde7SIngo Franzki u8 res1[3]; 710534bde7SIngo Franzki u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ 720534bde7SIngo Franzki u32 len; /* bytes actually stored in protkey[] */ 730534bde7SIngo Franzki u8 protkey[MAXPROTKEYSIZE]; /* the protected key blob */ 740534bde7SIngo Franzki } __packed; 750534bde7SIngo Franzki 76888edbc4SHarald Freudenberger /* inside view of a clear key token (type 0x00 version 0x02) */ 779e436c19SHarald Freudenberger struct clearkeytoken { 78888edbc4SHarald Freudenberger u8 type; /* 0x00 for PAES specific key tokens */ 79888edbc4SHarald Freudenberger u8 res0[3]; 809e436c19SHarald Freudenberger u8 version; /* 0x02 for clear key token */ 81888edbc4SHarald Freudenberger u8 res1[3]; 829e436c19SHarald Freudenberger u32 keytype; /* key type, one of the PKEY_KEYTYPE_* values */ 83888edbc4SHarald Freudenberger u32 len; /* bytes actually stored in clearkey[] */ 84fa226f1dSGustavo A. R. Silva u8 clearkey[]; /* clear key value */ 85888edbc4SHarald Freudenberger } __packed; 86888edbc4SHarald Freudenberger 879e436c19SHarald Freudenberger /* helper function which translates the PKEY_KEYTYPE_AES_* to their keysize */ 889e436c19SHarald Freudenberger static inline u32 pkey_keytype_aes_to_size(u32 keytype) 899e436c19SHarald Freudenberger { 909e436c19SHarald Freudenberger switch (keytype) { 919e436c19SHarald Freudenberger case PKEY_KEYTYPE_AES_128: 929e436c19SHarald Freudenberger return 16; 939e436c19SHarald Freudenberger case PKEY_KEYTYPE_AES_192: 949e436c19SHarald Freudenberger return 24; 959e436c19SHarald Freudenberger case PKEY_KEYTYPE_AES_256: 969e436c19SHarald Freudenberger return 32; 979e436c19SHarald Freudenberger default: 989e436c19SHarald Freudenberger return 0; 999e436c19SHarald Freudenberger } 1009e436c19SHarald Freudenberger } 1019e436c19SHarald Freudenberger 102e80d4af0SHarald Freudenberger /* 103f370f45cSHarald Freudenberger * Create a protected key from a clear key value via PCKMO instruction. 104e80d4af0SHarald Freudenberger */ 105f370f45cSHarald Freudenberger static int pkey_clr2protkey(u32 keytype, const u8 *clrkey, 106f370f45cSHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 107e80d4af0SHarald Freudenberger { 1085b35047eSHarald Freudenberger /* mask of available pckmo subfunctions */ 1095b35047eSHarald Freudenberger static cpacf_mask_t pckmo_functions; 1105b35047eSHarald Freudenberger 1119e436c19SHarald Freudenberger u8 paramblock[112]; 1129e436c19SHarald Freudenberger u32 pkeytype; 11346a29b03SHarald Freudenberger int keysize; 11446a29b03SHarald Freudenberger long fc; 115e80d4af0SHarald Freudenberger 116e80d4af0SHarald Freudenberger switch (keytype) { 117e80d4af0SHarald Freudenberger case PKEY_KEYTYPE_AES_128: 1189e436c19SHarald Freudenberger /* 16 byte key, 32 byte aes wkvp, total 48 bytes */ 119e80d4af0SHarald Freudenberger keysize = 16; 1209e436c19SHarald Freudenberger pkeytype = keytype; 121e80d4af0SHarald Freudenberger fc = CPACF_PCKMO_ENC_AES_128_KEY; 122e80d4af0SHarald Freudenberger break; 123e80d4af0SHarald Freudenberger case PKEY_KEYTYPE_AES_192: 1249e436c19SHarald Freudenberger /* 24 byte key, 32 byte aes wkvp, total 56 bytes */ 125e80d4af0SHarald Freudenberger keysize = 24; 1269e436c19SHarald Freudenberger pkeytype = keytype; 127e80d4af0SHarald Freudenberger fc = CPACF_PCKMO_ENC_AES_192_KEY; 128e80d4af0SHarald Freudenberger break; 129e80d4af0SHarald Freudenberger case PKEY_KEYTYPE_AES_256: 1309e436c19SHarald Freudenberger /* 32 byte key, 32 byte aes wkvp, total 64 bytes */ 131e80d4af0SHarald Freudenberger keysize = 32; 1329e436c19SHarald Freudenberger pkeytype = keytype; 133e80d4af0SHarald Freudenberger fc = CPACF_PCKMO_ENC_AES_256_KEY; 134e80d4af0SHarald Freudenberger break; 1359e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P256: 1369e436c19SHarald Freudenberger /* 32 byte key, 32 byte aes wkvp, total 64 bytes */ 1379e436c19SHarald Freudenberger keysize = 32; 1389e436c19SHarald Freudenberger pkeytype = PKEY_KEYTYPE_ECC; 1399e436c19SHarald Freudenberger fc = CPACF_PCKMO_ENC_ECC_P256_KEY; 1409e436c19SHarald Freudenberger break; 1419e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P384: 1429e436c19SHarald Freudenberger /* 48 byte key, 32 byte aes wkvp, total 80 bytes */ 1439e436c19SHarald Freudenberger keysize = 48; 1449e436c19SHarald Freudenberger pkeytype = PKEY_KEYTYPE_ECC; 1459e436c19SHarald Freudenberger fc = CPACF_PCKMO_ENC_ECC_P384_KEY; 1469e436c19SHarald Freudenberger break; 1479e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P521: 1489e436c19SHarald Freudenberger /* 80 byte key, 32 byte aes wkvp, total 112 bytes */ 1499e436c19SHarald Freudenberger keysize = 80; 1509e436c19SHarald Freudenberger pkeytype = PKEY_KEYTYPE_ECC; 1519e436c19SHarald Freudenberger fc = CPACF_PCKMO_ENC_ECC_P521_KEY; 1529e436c19SHarald Freudenberger break; 1539e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_ED25519: 1549e436c19SHarald Freudenberger /* 32 byte key, 32 byte aes wkvp, total 64 bytes */ 1559e436c19SHarald Freudenberger keysize = 32; 1569e436c19SHarald Freudenberger pkeytype = PKEY_KEYTYPE_ECC; 1579e436c19SHarald Freudenberger fc = CPACF_PCKMO_ENC_ECC_ED25519_KEY; 1589e436c19SHarald Freudenberger break; 1599e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_ED448: 1609e436c19SHarald Freudenberger /* 64 byte key, 32 byte aes wkvp, total 96 bytes */ 1619e436c19SHarald Freudenberger keysize = 64; 1629e436c19SHarald Freudenberger pkeytype = PKEY_KEYTYPE_ECC; 1639e436c19SHarald Freudenberger fc = CPACF_PCKMO_ENC_ECC_ED448_KEY; 1649e436c19SHarald Freudenberger break; 165e80d4af0SHarald Freudenberger default: 166f370f45cSHarald Freudenberger DEBUG_ERR("%s unknown/unsupported keytype %u\n", 167ac2b96f3SHarald Freudenberger __func__, keytype); 168e80d4af0SHarald Freudenberger return -EINVAL; 169e80d4af0SHarald Freudenberger } 170e80d4af0SHarald Freudenberger 171f370f45cSHarald Freudenberger if (*protkeylen < keysize + AES_WK_VP_SIZE) { 172f370f45cSHarald Freudenberger DEBUG_ERR("%s prot key buffer size too small: %u < %d\n", 173f370f45cSHarald Freudenberger __func__, *protkeylen, keysize + AES_WK_VP_SIZE); 174f370f45cSHarald Freudenberger return -EINVAL; 175f370f45cSHarald Freudenberger } 176f370f45cSHarald Freudenberger 1775b35047eSHarald Freudenberger /* Did we already check for PCKMO ? */ 1785b35047eSHarald Freudenberger if (!pckmo_functions.bytes[0]) { 1795b35047eSHarald Freudenberger /* no, so check now */ 1805b35047eSHarald Freudenberger if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) 1815b35047eSHarald Freudenberger return -ENODEV; 1825b35047eSHarald Freudenberger } 1835b35047eSHarald Freudenberger /* check for the pckmo subfunction we need now */ 184f822ad2cSHarald Freudenberger if (!cpacf_test_func(&pckmo_functions, fc)) { 185f822ad2cSHarald Freudenberger DEBUG_ERR("%s pckmo functions not available\n", __func__); 18658443b67SDavid Hildenbrand return -ENODEV; 187f822ad2cSHarald Freudenberger } 188f822ad2cSHarald Freudenberger 189e80d4af0SHarald Freudenberger /* prepare param block */ 190e80d4af0SHarald Freudenberger memset(paramblock, 0, sizeof(paramblock)); 191f370f45cSHarald Freudenberger memcpy(paramblock, clrkey, keysize); 192e80d4af0SHarald Freudenberger 193e80d4af0SHarald Freudenberger /* call the pckmo instruction */ 194e80d4af0SHarald Freudenberger cpacf_pckmo(fc, paramblock); 195e80d4af0SHarald Freudenberger 196f370f45cSHarald Freudenberger /* copy created protected key to key buffer including the wkvp block */ 197f370f45cSHarald Freudenberger *protkeylen = keysize + AES_WK_VP_SIZE; 198f370f45cSHarald Freudenberger memcpy(protkey, paramblock, *protkeylen); 1999e436c19SHarald Freudenberger *protkeytype = pkeytype; 200e80d4af0SHarald Freudenberger 201e80d4af0SHarald Freudenberger return 0; 202e80d4af0SHarald Freudenberger } 203e80d4af0SHarald Freudenberger 204e80d4af0SHarald Freudenberger /* 205e80d4af0SHarald Freudenberger * Find card and transform secure key into protected key. 206e80d4af0SHarald Freudenberger */ 207f370f45cSHarald Freudenberger static int pkey_skey2pkey(const u8 *key, u8 *protkey, 208f370f45cSHarald Freudenberger u32 *protkeylen, u32 *protkeytype) 209e80d4af0SHarald Freudenberger { 210f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 21146a29b03SHarald Freudenberger u16 cardnr, domain; 21246a29b03SHarald Freudenberger int rc, verify; 213e80d4af0SHarald Freudenberger 21443cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 21543cb5a7cSHarald Freudenberger 216e80d4af0SHarald Freudenberger /* 217f2bbc96eSHarald Freudenberger * The cca_xxx2protkey call may fail when a card has been 218e80d4af0SHarald Freudenberger * addressed where the master key was changed after last fetch 219f4272c03SJulia Lawall * of the mkvp into the cache. Try 3 times: First without verify 220efc598e6SHarald Freudenberger * then with verify and last round with verify and old master 221efc598e6SHarald Freudenberger * key verification pattern match not ignored. 222e80d4af0SHarald Freudenberger */ 223efc598e6SHarald Freudenberger for (verify = 0; verify < 3; verify++) { 224f2bbc96eSHarald Freudenberger rc = cca_findcard(key, &cardnr, &domain, verify); 225efc598e6SHarald Freudenberger if (rc < 0) 226e80d4af0SHarald Freudenberger continue; 227efc598e6SHarald Freudenberger if (rc > 0 && verify < 2) 228efc598e6SHarald Freudenberger continue; 229f2bbc96eSHarald Freudenberger switch (hdr->version) { 230f2bbc96eSHarald Freudenberger case TOKVER_CCA_AES: 231f370f45cSHarald Freudenberger rc = cca_sec2protkey(cardnr, domain, key, 232f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 233f2bbc96eSHarald Freudenberger break; 234f2bbc96eSHarald Freudenberger case TOKVER_CCA_VLSC: 235f370f45cSHarald Freudenberger rc = cca_cipher2protkey(cardnr, domain, key, 236f370f45cSHarald Freudenberger protkey, protkeylen, 237f370f45cSHarald Freudenberger protkeytype); 238f2bbc96eSHarald Freudenberger break; 239f2bbc96eSHarald Freudenberger default: 240f2bbc96eSHarald Freudenberger return -EINVAL; 241f2bbc96eSHarald Freudenberger } 242e80d4af0SHarald Freudenberger if (rc == 0) 243e80d4af0SHarald Freudenberger break; 244e80d4af0SHarald Freudenberger } 245e80d4af0SHarald Freudenberger 246e80d4af0SHarald Freudenberger if (rc) 247ac2b96f3SHarald Freudenberger DEBUG_DBG("%s failed rc=%d\n", __func__, rc); 248e80d4af0SHarald Freudenberger 249e80d4af0SHarald Freudenberger return rc; 250e80d4af0SHarald Freudenberger } 251e80d4af0SHarald Freudenberger 252e80d4af0SHarald Freudenberger /* 25355d0a513SHarald Freudenberger * Construct EP11 key with given clear key value. 25455d0a513SHarald Freudenberger */ 25555d0a513SHarald Freudenberger static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen, 25655d0a513SHarald Freudenberger u8 *keybuf, size_t *keybuflen) 25755d0a513SHarald Freudenberger { 25855d0a513SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 25946a29b03SHarald Freudenberger u16 card, dom; 26046a29b03SHarald Freudenberger int i, rc; 26155d0a513SHarald Freudenberger 26243cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 26343cb5a7cSHarald Freudenberger 26455d0a513SHarald Freudenberger /* build a list of apqns suitable for ep11 keys with cpacf support */ 26555d0a513SHarald Freudenberger rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 26655d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, NULL); 26755d0a513SHarald Freudenberger if (rc) 26855d0a513SHarald Freudenberger goto out; 26955d0a513SHarald Freudenberger 27055d0a513SHarald Freudenberger /* go through the list of apqns and try to bild an ep11 key */ 27155d0a513SHarald Freudenberger for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { 27255d0a513SHarald Freudenberger card = apqns[i] >> 16; 27355d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 27455d0a513SHarald Freudenberger rc = ep11_clr2keyblob(card, dom, clrkeylen * 8, 275da2863f1SHolger Dengler 0, clrkey, keybuf, keybuflen, 276da2863f1SHolger Dengler PKEY_TYPE_EP11); 27755d0a513SHarald Freudenberger if (rc == 0) 27855d0a513SHarald Freudenberger break; 27955d0a513SHarald Freudenberger } 28055d0a513SHarald Freudenberger 28155d0a513SHarald Freudenberger out: 28255d0a513SHarald Freudenberger kfree(apqns); 28355d0a513SHarald Freudenberger if (rc) 28455d0a513SHarald Freudenberger DEBUG_DBG("%s failed rc=%d\n", __func__, rc); 28555d0a513SHarald Freudenberger return rc; 28655d0a513SHarald Freudenberger } 28755d0a513SHarald Freudenberger 28855d0a513SHarald Freudenberger /* 28955d0a513SHarald Freudenberger * Find card and transform EP11 secure key into protected key. 29055d0a513SHarald Freudenberger */ 291*d1fdfb0bSHolger Dengler static int pkey_ep11key2pkey(const u8 *key, size_t keylen, 292*d1fdfb0bSHolger Dengler u8 *protkey, u32 *protkeylen, u32 *protkeytype) 29355d0a513SHarald Freudenberger { 29446a29b03SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 29546a29b03SHarald Freudenberger u16 card, dom; 29646a29b03SHarald Freudenberger int i, rc; 29755d0a513SHarald Freudenberger 29843cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 29943cb5a7cSHarald Freudenberger 30055d0a513SHarald Freudenberger /* build a list of apqns suitable for this key */ 30155d0a513SHarald Freudenberger rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 302*d1fdfb0bSHolger Dengler ZCRYPT_CEX7, EP11_API_V, 303*d1fdfb0bSHolger Dengler ep11_kb_wkvp(key, keylen)); 30455d0a513SHarald Freudenberger if (rc) 30555d0a513SHarald Freudenberger goto out; 30655d0a513SHarald Freudenberger 30755d0a513SHarald Freudenberger /* go through the list of apqns and try to derive an pkey */ 30855d0a513SHarald Freudenberger for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { 30955d0a513SHarald Freudenberger card = apqns[i] >> 16; 31055d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 311*d1fdfb0bSHolger Dengler rc = ep11_kblob2protkey(card, dom, key, keylen, 312f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 31355d0a513SHarald Freudenberger if (rc == 0) 31455d0a513SHarald Freudenberger break; 31555d0a513SHarald Freudenberger } 31655d0a513SHarald Freudenberger 31755d0a513SHarald Freudenberger out: 31855d0a513SHarald Freudenberger kfree(apqns); 31955d0a513SHarald Freudenberger if (rc) 32055d0a513SHarald Freudenberger DEBUG_DBG("%s failed rc=%d\n", __func__, rc); 32155d0a513SHarald Freudenberger return rc; 32255d0a513SHarald Freudenberger } 32355d0a513SHarald Freudenberger 32455d0a513SHarald Freudenberger /* 325e61a6134SHarald Freudenberger * Verify key and give back some info about the key. 326e61a6134SHarald Freudenberger */ 327183cb469SHarald Freudenberger static int pkey_verifykey(const struct pkey_seckey *seckey, 328e61a6134SHarald Freudenberger u16 *pcardnr, u16 *pdomain, 329e61a6134SHarald Freudenberger u16 *pkeysize, u32 *pattributes) 330e61a6134SHarald Freudenberger { 331e61a6134SHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *)seckey; 332e61a6134SHarald Freudenberger u16 cardnr, domain; 333e61a6134SHarald Freudenberger int rc; 334e61a6134SHarald Freudenberger 335e61a6134SHarald Freudenberger /* check the secure key for valid AES secure key */ 336efc598e6SHarald Freudenberger rc = cca_check_secaeskeytoken(debug_info, 3, (u8 *)seckey, 0); 337e61a6134SHarald Freudenberger if (rc) 338e61a6134SHarald Freudenberger goto out; 339e61a6134SHarald Freudenberger if (pattributes) 340e61a6134SHarald Freudenberger *pattributes = PKEY_VERIFY_ATTR_AES; 341e61a6134SHarald Freudenberger if (pkeysize) 342e61a6134SHarald Freudenberger *pkeysize = t->bitsize; 343e61a6134SHarald Freudenberger 344e61a6134SHarald Freudenberger /* try to find a card which can handle this key */ 345efc598e6SHarald Freudenberger rc = cca_findcard(seckey->seckey, &cardnr, &domain, 1); 346efc598e6SHarald Freudenberger if (rc < 0) 347e61a6134SHarald Freudenberger goto out; 348e61a6134SHarald Freudenberger 349efc598e6SHarald Freudenberger if (rc > 0) { 350efc598e6SHarald Freudenberger /* key mkvp matches to old master key mkvp */ 351ac2b96f3SHarald Freudenberger DEBUG_DBG("%s secure key has old mkvp\n", __func__); 352e61a6134SHarald Freudenberger if (pattributes) 353e61a6134SHarald Freudenberger *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP; 354efc598e6SHarald Freudenberger rc = 0; 355e61a6134SHarald Freudenberger } 356e61a6134SHarald Freudenberger 357e61a6134SHarald Freudenberger if (pcardnr) 358e61a6134SHarald Freudenberger *pcardnr = cardnr; 359e61a6134SHarald Freudenberger if (pdomain) 360e61a6134SHarald Freudenberger *pdomain = domain; 361e61a6134SHarald Freudenberger 362e61a6134SHarald Freudenberger out: 363ac2b96f3SHarald Freudenberger DEBUG_DBG("%s rc=%d\n", __func__, rc); 364e61a6134SHarald Freudenberger return rc; 365e61a6134SHarald Freudenberger } 366e61a6134SHarald Freudenberger 367e61a6134SHarald Freudenberger /* 368a45a5c7dSIngo Franzki * Generate a random protected key 369a45a5c7dSIngo Franzki */ 370f370f45cSHarald Freudenberger static int pkey_genprotkey(u32 keytype, u8 *protkey, 371f370f45cSHarald Freudenberger u32 *protkeylen, u32 *protkeytype) 372a45a5c7dSIngo Franzki { 373f370f45cSHarald Freudenberger u8 clrkey[32]; 374a45a5c7dSIngo Franzki int keysize; 375a45a5c7dSIngo Franzki int rc; 376a45a5c7dSIngo Franzki 3779e436c19SHarald Freudenberger keysize = pkey_keytype_aes_to_size(keytype); 3789e436c19SHarald Freudenberger if (!keysize) { 379a45a5c7dSIngo Franzki DEBUG_ERR("%s unknown/unsupported keytype %d\n", __func__, 380a45a5c7dSIngo Franzki keytype); 381a45a5c7dSIngo Franzki return -EINVAL; 382a45a5c7dSIngo Franzki } 383a45a5c7dSIngo Franzki 384a45a5c7dSIngo Franzki /* generate a dummy random clear key */ 385f370f45cSHarald Freudenberger get_random_bytes(clrkey, keysize); 386a45a5c7dSIngo Franzki 387a45a5c7dSIngo Franzki /* convert it to a dummy protected key */ 388f370f45cSHarald Freudenberger rc = pkey_clr2protkey(keytype, clrkey, 389f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 390a45a5c7dSIngo Franzki if (rc) 391a45a5c7dSIngo Franzki return rc; 392a45a5c7dSIngo Franzki 393a45a5c7dSIngo Franzki /* replace the key part of the protected key with random bytes */ 394f370f45cSHarald Freudenberger get_random_bytes(protkey, keysize); 395a45a5c7dSIngo Franzki 396a45a5c7dSIngo Franzki return 0; 397a45a5c7dSIngo Franzki } 398a45a5c7dSIngo Franzki 399a45a5c7dSIngo Franzki /* 400cb26b9ffSIngo Franzki * Verify if a protected key is still valid 401cb26b9ffSIngo Franzki */ 402f370f45cSHarald Freudenberger static int pkey_verifyprotkey(const u8 *protkey, u32 protkeylen, 403f370f45cSHarald Freudenberger u32 protkeytype) 404cb26b9ffSIngo Franzki { 405cb26b9ffSIngo Franzki struct { 406cb26b9ffSIngo Franzki u8 iv[AES_BLOCK_SIZE]; 407cb26b9ffSIngo Franzki u8 key[MAXPROTKEYSIZE]; 408cb26b9ffSIngo Franzki } param; 409cb26b9ffSIngo Franzki u8 null_msg[AES_BLOCK_SIZE]; 410cb26b9ffSIngo Franzki u8 dest_buf[AES_BLOCK_SIZE]; 411f370f45cSHarald Freudenberger unsigned int k, pkeylen; 41246a29b03SHarald Freudenberger unsigned long fc; 413cb26b9ffSIngo Franzki 414f370f45cSHarald Freudenberger switch (protkeytype) { 415cb26b9ffSIngo Franzki case PKEY_KEYTYPE_AES_128: 416f370f45cSHarald Freudenberger pkeylen = 16 + AES_WK_VP_SIZE; 417cb26b9ffSIngo Franzki fc = CPACF_KMC_PAES_128; 418cb26b9ffSIngo Franzki break; 419cb26b9ffSIngo Franzki case PKEY_KEYTYPE_AES_192: 420f370f45cSHarald Freudenberger pkeylen = 24 + AES_WK_VP_SIZE; 421cb26b9ffSIngo Franzki fc = CPACF_KMC_PAES_192; 422cb26b9ffSIngo Franzki break; 423cb26b9ffSIngo Franzki case PKEY_KEYTYPE_AES_256: 424f370f45cSHarald Freudenberger pkeylen = 32 + AES_WK_VP_SIZE; 425cb26b9ffSIngo Franzki fc = CPACF_KMC_PAES_256; 426cb26b9ffSIngo Franzki break; 427cb26b9ffSIngo Franzki default: 428f370f45cSHarald Freudenberger DEBUG_ERR("%s unknown/unsupported keytype %u\n", __func__, 429f370f45cSHarald Freudenberger protkeytype); 430f370f45cSHarald Freudenberger return -EINVAL; 431f370f45cSHarald Freudenberger } 432f370f45cSHarald Freudenberger if (protkeylen != pkeylen) { 433f370f45cSHarald Freudenberger DEBUG_ERR("%s invalid protected key size %u for keytype %u\n", 434f370f45cSHarald Freudenberger __func__, protkeylen, protkeytype); 435cb26b9ffSIngo Franzki return -EINVAL; 436cb26b9ffSIngo Franzki } 437cb26b9ffSIngo Franzki 438cb26b9ffSIngo Franzki memset(null_msg, 0, sizeof(null_msg)); 439cb26b9ffSIngo Franzki 440cb26b9ffSIngo Franzki memset(param.iv, 0, sizeof(param.iv)); 441f370f45cSHarald Freudenberger memcpy(param.key, protkey, protkeylen); 442cb26b9ffSIngo Franzki 443cb26b9ffSIngo Franzki k = cpacf_kmc(fc | CPACF_ENCRYPT, ¶m, null_msg, dest_buf, 444cb26b9ffSIngo Franzki sizeof(null_msg)); 445cb26b9ffSIngo Franzki if (k != sizeof(null_msg)) { 446cb26b9ffSIngo Franzki DEBUG_ERR("%s protected key is not valid\n", __func__); 447cb26b9ffSIngo Franzki return -EKEYREJECTED; 448cb26b9ffSIngo Franzki } 449cb26b9ffSIngo Franzki 450cb26b9ffSIngo Franzki return 0; 451cb26b9ffSIngo Franzki } 452cb26b9ffSIngo Franzki 4539e436c19SHarald Freudenberger /* Helper for pkey_nonccatok2pkey, handles aes clear key token */ 4549e436c19SHarald Freudenberger static int nonccatokaes2pkey(const struct clearkeytoken *t, 4559e436c19SHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 4569e436c19SHarald Freudenberger { 4579e436c19SHarald Freudenberger size_t tmpbuflen = max_t(size_t, SECKEYBLOBSIZE, MAXEP11AESKEYBLOBSIZE); 4589e436c19SHarald Freudenberger u8 *tmpbuf = NULL; 4599e436c19SHarald Freudenberger u32 keysize; 4609e436c19SHarald Freudenberger int rc; 4619e436c19SHarald Freudenberger 4629e436c19SHarald Freudenberger keysize = pkey_keytype_aes_to_size(t->keytype); 4639e436c19SHarald Freudenberger if (!keysize) { 4649e436c19SHarald Freudenberger DEBUG_ERR("%s unknown/unsupported keytype %u\n", 4659e436c19SHarald Freudenberger __func__, t->keytype); 4669e436c19SHarald Freudenberger return -EINVAL; 4679e436c19SHarald Freudenberger } 4689e436c19SHarald Freudenberger if (t->len != keysize) { 4699e436c19SHarald Freudenberger DEBUG_ERR("%s non clear key aes token: invalid key len %u\n", 4709e436c19SHarald Freudenberger __func__, t->len); 4719e436c19SHarald Freudenberger return -EINVAL; 4729e436c19SHarald Freudenberger } 4739e436c19SHarald Freudenberger 4749e436c19SHarald Freudenberger /* try direct way with the PCKMO instruction */ 4759e436c19SHarald Freudenberger rc = pkey_clr2protkey(t->keytype, t->clearkey, 4769e436c19SHarald Freudenberger protkey, protkeylen, protkeytype); 4779e436c19SHarald Freudenberger if (!rc) 4789e436c19SHarald Freudenberger goto out; 4799e436c19SHarald Freudenberger 4809e436c19SHarald Freudenberger /* PCKMO failed, so try the CCA secure key way */ 4819e436c19SHarald Freudenberger tmpbuf = kmalloc(tmpbuflen, GFP_ATOMIC); 4829e436c19SHarald Freudenberger if (!tmpbuf) 4839e436c19SHarald Freudenberger return -ENOMEM; 4849e436c19SHarald Freudenberger zcrypt_wait_api_operational(); 4859e436c19SHarald Freudenberger rc = cca_clr2seckey(0xFFFF, 0xFFFF, t->keytype, t->clearkey, tmpbuf); 4869e436c19SHarald Freudenberger if (rc) 4879e436c19SHarald Freudenberger goto try_via_ep11; 4889e436c19SHarald Freudenberger rc = pkey_skey2pkey(tmpbuf, 4899e436c19SHarald Freudenberger protkey, protkeylen, protkeytype); 4909e436c19SHarald Freudenberger if (!rc) 4919e436c19SHarald Freudenberger goto out; 4929e436c19SHarald Freudenberger 4939e436c19SHarald Freudenberger try_via_ep11: 4949e436c19SHarald Freudenberger /* if the CCA way also failed, let's try via EP11 */ 4959e436c19SHarald Freudenberger rc = pkey_clr2ep11key(t->clearkey, t->len, 4969e436c19SHarald Freudenberger tmpbuf, &tmpbuflen); 4979e436c19SHarald Freudenberger if (rc) 4989e436c19SHarald Freudenberger goto failure; 499*d1fdfb0bSHolger Dengler rc = pkey_ep11key2pkey(tmpbuf, tmpbuflen, 5009e436c19SHarald Freudenberger protkey, protkeylen, protkeytype); 5019e436c19SHarald Freudenberger if (!rc) 5029e436c19SHarald Freudenberger goto out; 5039e436c19SHarald Freudenberger 5049e436c19SHarald Freudenberger failure: 5059e436c19SHarald Freudenberger DEBUG_ERR("%s unable to build protected key from clear", __func__); 5069e436c19SHarald Freudenberger 5079e436c19SHarald Freudenberger out: 5089e436c19SHarald Freudenberger kfree(tmpbuf); 5099e436c19SHarald Freudenberger return rc; 5109e436c19SHarald Freudenberger } 5119e436c19SHarald Freudenberger 5129e436c19SHarald Freudenberger /* Helper for pkey_nonccatok2pkey, handles ecc clear key token */ 5139e436c19SHarald Freudenberger static int nonccatokecc2pkey(const struct clearkeytoken *t, 5149e436c19SHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 5159e436c19SHarald Freudenberger { 5169e436c19SHarald Freudenberger u32 keylen; 5179e436c19SHarald Freudenberger int rc; 5189e436c19SHarald Freudenberger 5199e436c19SHarald Freudenberger switch (t->keytype) { 5209e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P256: 5219e436c19SHarald Freudenberger keylen = 32; 5229e436c19SHarald Freudenberger break; 5239e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P384: 5249e436c19SHarald Freudenberger keylen = 48; 5259e436c19SHarald Freudenberger break; 5269e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P521: 5279e436c19SHarald Freudenberger keylen = 80; 5289e436c19SHarald Freudenberger break; 5299e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_ED25519: 5309e436c19SHarald Freudenberger keylen = 32; 5319e436c19SHarald Freudenberger break; 5329e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_ED448: 5339e436c19SHarald Freudenberger keylen = 64; 5349e436c19SHarald Freudenberger break; 5359e436c19SHarald Freudenberger default: 5369e436c19SHarald Freudenberger DEBUG_ERR("%s unknown/unsupported keytype %u\n", 5379e436c19SHarald Freudenberger __func__, t->keytype); 5389e436c19SHarald Freudenberger return -EINVAL; 5399e436c19SHarald Freudenberger } 5409e436c19SHarald Freudenberger 5419e436c19SHarald Freudenberger if (t->len != keylen) { 5429e436c19SHarald Freudenberger DEBUG_ERR("%s non clear key ecc token: invalid key len %u\n", 5439e436c19SHarald Freudenberger __func__, t->len); 5449e436c19SHarald Freudenberger return -EINVAL; 5459e436c19SHarald Freudenberger } 5469e436c19SHarald Freudenberger 5479e436c19SHarald Freudenberger /* only one path possible: via PCKMO instruction */ 5489e436c19SHarald Freudenberger rc = pkey_clr2protkey(t->keytype, t->clearkey, 5499e436c19SHarald Freudenberger protkey, protkeylen, protkeytype); 5509e436c19SHarald Freudenberger if (rc) { 5519e436c19SHarald Freudenberger DEBUG_ERR("%s unable to build protected key from clear", 5529e436c19SHarald Freudenberger __func__); 5539e436c19SHarald Freudenberger } 5549e436c19SHarald Freudenberger 5559e436c19SHarald Freudenberger return rc; 5569e436c19SHarald Freudenberger } 5579e436c19SHarald Freudenberger 558cb26b9ffSIngo Franzki /* 559fb1136d6SIngo Franzki * Transform a non-CCA key token into a protected key 560fb1136d6SIngo Franzki */ 561183cb469SHarald Freudenberger static int pkey_nonccatok2pkey(const u8 *key, u32 keylen, 562f370f45cSHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 563fb1136d6SIngo Franzki { 564fb1136d6SIngo Franzki struct keytoken_header *hdr = (struct keytoken_header *)key; 56546a29b03SHarald Freudenberger int rc = -EINVAL; 566fb1136d6SIngo Franzki 567fb1136d6SIngo Franzki switch (hdr->version) { 568888edbc4SHarald Freudenberger case TOKVER_PROTECTED_KEY: { 569888edbc4SHarald Freudenberger struct protaeskeytoken *t; 570fb1136d6SIngo Franzki 571888edbc4SHarald Freudenberger if (keylen != sizeof(struct protaeskeytoken)) 572888edbc4SHarald Freudenberger goto out; 573fb1136d6SIngo Franzki t = (struct protaeskeytoken *)key; 574f370f45cSHarald Freudenberger rc = pkey_verifyprotkey(t->protkey, t->len, t->keytype); 575f370f45cSHarald Freudenberger if (rc) 576f370f45cSHarald Freudenberger goto out; 577f370f45cSHarald Freudenberger memcpy(protkey, t->protkey, t->len); 578f370f45cSHarald Freudenberger *protkeylen = t->len; 579f370f45cSHarald Freudenberger *protkeytype = t->keytype; 580888edbc4SHarald Freudenberger break; 581888edbc4SHarald Freudenberger } 582888edbc4SHarald Freudenberger case TOKVER_CLEAR_KEY: { 5839e436c19SHarald Freudenberger struct clearkeytoken *t = (struct clearkeytoken *)key; 584fb1136d6SIngo Franzki 5859e436c19SHarald Freudenberger if (keylen < sizeof(struct clearkeytoken) || 5869e436c19SHarald Freudenberger keylen != sizeof(*t) + t->len) 587888edbc4SHarald Freudenberger goto out; 5889e436c19SHarald Freudenberger switch (t->keytype) { 5899e436c19SHarald Freudenberger case PKEY_KEYTYPE_AES_128: 5909e436c19SHarald Freudenberger case PKEY_KEYTYPE_AES_192: 5919e436c19SHarald Freudenberger case PKEY_KEYTYPE_AES_256: 5929e436c19SHarald Freudenberger rc = nonccatokaes2pkey(t, protkey, 5939e436c19SHarald Freudenberger protkeylen, protkeytype); 5949e436c19SHarald Freudenberger break; 5959e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P256: 5969e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P384: 5979e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_P521: 5989e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_ED25519: 5999e436c19SHarald Freudenberger case PKEY_KEYTYPE_ECC_ED448: 6009e436c19SHarald Freudenberger rc = nonccatokecc2pkey(t, protkey, 6019e436c19SHarald Freudenberger protkeylen, protkeytype); 6029e436c19SHarald Freudenberger break; 6039e436c19SHarald Freudenberger default: 6049e436c19SHarald Freudenberger DEBUG_ERR("%s unknown/unsupported non cca clear key type %u\n", 6059e436c19SHarald Freudenberger __func__, t->keytype); 6069e436c19SHarald Freudenberger return -EINVAL; 60755d0a513SHarald Freudenberger } 608888edbc4SHarald Freudenberger break; 609888edbc4SHarald Freudenberger } 61055d0a513SHarald Freudenberger case TOKVER_EP11_AES: { 61155d0a513SHarald Freudenberger /* check ep11 key for exportable as protected key */ 612fa6999e3SHarald Freudenberger rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); 61355d0a513SHarald Freudenberger if (rc) 61455d0a513SHarald Freudenberger goto out; 615*d1fdfb0bSHolger Dengler rc = pkey_ep11key2pkey(key, keylen, 616f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 61755d0a513SHarald Freudenberger break; 61855d0a513SHarald Freudenberger } 619fa6999e3SHarald Freudenberger case TOKVER_EP11_AES_WITH_HEADER: 620fa6999e3SHarald Freudenberger /* check ep11 key with header for exportable as protected key */ 621fa6999e3SHarald Freudenberger rc = ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1); 622fa6999e3SHarald Freudenberger if (rc) 623fa6999e3SHarald Freudenberger goto out; 624*d1fdfb0bSHolger Dengler rc = pkey_ep11key2pkey(key, keylen, 625f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 626fa6999e3SHarald Freudenberger break; 627fb1136d6SIngo Franzki default: 628fb1136d6SIngo Franzki DEBUG_ERR("%s unknown/unsupported non-CCA token version %d\n", 629fb1136d6SIngo Franzki __func__, hdr->version); 630fb1136d6SIngo Franzki } 631888edbc4SHarald Freudenberger 632888edbc4SHarald Freudenberger out: 633888edbc4SHarald Freudenberger return rc; 634fb1136d6SIngo Franzki } 635fb1136d6SIngo Franzki 636fb1136d6SIngo Franzki /* 637fb1136d6SIngo Franzki * Transform a CCA internal key token into a protected key 638fb1136d6SIngo Franzki */ 639183cb469SHarald Freudenberger static int pkey_ccainttok2pkey(const u8 *key, u32 keylen, 640f370f45cSHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 641fb1136d6SIngo Franzki { 642fb1136d6SIngo Franzki struct keytoken_header *hdr = (struct keytoken_header *)key; 643fb1136d6SIngo Franzki 644fb1136d6SIngo Franzki switch (hdr->version) { 645fb1136d6SIngo Franzki case TOKVER_CCA_AES: 646fb1136d6SIngo Franzki if (keylen != sizeof(struct secaeskeytoken)) 647fb1136d6SIngo Franzki return -EINVAL; 648f2bbc96eSHarald Freudenberger break; 649f2bbc96eSHarald Freudenberger case TOKVER_CCA_VLSC: 650f2bbc96eSHarald Freudenberger if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 651f2bbc96eSHarald Freudenberger return -EINVAL; 652f2bbc96eSHarald Freudenberger break; 653fb1136d6SIngo Franzki default: 654fb1136d6SIngo Franzki DEBUG_ERR("%s unknown/unsupported CCA internal token version %d\n", 655fb1136d6SIngo Franzki __func__, hdr->version); 656fb1136d6SIngo Franzki return -EINVAL; 657fb1136d6SIngo Franzki } 658f2bbc96eSHarald Freudenberger 659f370f45cSHarald Freudenberger return pkey_skey2pkey(key, protkey, protkeylen, protkeytype); 660fb1136d6SIngo Franzki } 661fb1136d6SIngo Franzki 662fb1136d6SIngo Franzki /* 663fb1136d6SIngo Franzki * Transform a key blob (of any type) into a protected key 664fb1136d6SIngo Franzki */ 665183cb469SHarald Freudenberger int pkey_keyblob2pkey(const u8 *key, u32 keylen, 666f370f45cSHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 667fb1136d6SIngo Franzki { 668fb1136d6SIngo Franzki struct keytoken_header *hdr = (struct keytoken_header *)key; 66946a29b03SHarald Freudenberger int rc; 670fb1136d6SIngo Franzki 671f2bbc96eSHarald Freudenberger if (keylen < sizeof(struct keytoken_header)) { 672f2bbc96eSHarald Freudenberger DEBUG_ERR("%s invalid keylen %d\n", __func__, keylen); 673f2bbc96eSHarald Freudenberger return -EINVAL; 674f2bbc96eSHarald Freudenberger } 675f2bbc96eSHarald Freudenberger 676f2bbc96eSHarald Freudenberger switch (hdr->type) { 677f2bbc96eSHarald Freudenberger case TOKTYPE_NON_CCA: 678f370f45cSHarald Freudenberger rc = pkey_nonccatok2pkey(key, keylen, 679f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 680f2bbc96eSHarald Freudenberger break; 681f2bbc96eSHarald Freudenberger case TOKTYPE_CCA_INTERNAL: 682f370f45cSHarald Freudenberger rc = pkey_ccainttok2pkey(key, keylen, 683f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 684f2bbc96eSHarald Freudenberger break; 685f2bbc96eSHarald Freudenberger default: 686f2bbc96eSHarald Freudenberger DEBUG_ERR("%s unknown/unsupported blob type %d\n", 687f2bbc96eSHarald Freudenberger __func__, hdr->type); 688f2bbc96eSHarald Freudenberger return -EINVAL; 689f2bbc96eSHarald Freudenberger } 690f2bbc96eSHarald Freudenberger 691f2bbc96eSHarald Freudenberger DEBUG_DBG("%s rc=%d\n", __func__, rc); 692f2bbc96eSHarald Freudenberger return rc; 693f2bbc96eSHarald Freudenberger } 694f2bbc96eSHarald Freudenberger EXPORT_SYMBOL(pkey_keyblob2pkey); 695f2bbc96eSHarald Freudenberger 696f2bbc96eSHarald Freudenberger static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns, 697f2bbc96eSHarald Freudenberger enum pkey_key_type ktype, enum pkey_key_size ksize, 698f2bbc96eSHarald Freudenberger u32 kflags, u8 *keybuf, size_t *keybufsize) 699f2bbc96eSHarald Freudenberger { 700f2bbc96eSHarald Freudenberger int i, card, dom, rc; 701f2bbc96eSHarald Freudenberger 702f2bbc96eSHarald Freudenberger /* check for at least one apqn given */ 703f2bbc96eSHarald Freudenberger if (!apqns || !nr_apqns) 704f2bbc96eSHarald Freudenberger return -EINVAL; 705f2bbc96eSHarald Freudenberger 706f2bbc96eSHarald Freudenberger /* check key type and size */ 707f2bbc96eSHarald Freudenberger switch (ktype) { 708f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_DATA: 709f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_CIPHER: 710f2bbc96eSHarald Freudenberger if (*keybufsize < SECKEYBLOBSIZE) 711f2bbc96eSHarald Freudenberger return -EINVAL; 712f2bbc96eSHarald Freudenberger break; 71355d0a513SHarald Freudenberger case PKEY_TYPE_EP11: 71455d0a513SHarald Freudenberger if (*keybufsize < MINEP11AESKEYBLOBSIZE) 71555d0a513SHarald Freudenberger return -EINVAL; 71655d0a513SHarald Freudenberger break; 717fb249ce7SHolger Dengler case PKEY_TYPE_EP11_AES: 718fb249ce7SHolger Dengler if (*keybufsize < (sizeof(struct ep11kblob_header) + 719fb249ce7SHolger Dengler MINEP11AESKEYBLOBSIZE)) 720fb249ce7SHolger Dengler return -EINVAL; 721fb249ce7SHolger Dengler break; 722f2bbc96eSHarald Freudenberger default: 723f2bbc96eSHarald Freudenberger return -EINVAL; 724f2bbc96eSHarald Freudenberger } 725f2bbc96eSHarald Freudenberger switch (ksize) { 726f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_128: 727f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_192: 728f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_256: 729f2bbc96eSHarald Freudenberger break; 730f2bbc96eSHarald Freudenberger default: 731f2bbc96eSHarald Freudenberger return -EINVAL; 732f2bbc96eSHarald Freudenberger } 733f2bbc96eSHarald Freudenberger 734f2bbc96eSHarald Freudenberger /* simple try all apqns from the list */ 735f2bbc96eSHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 736f2bbc96eSHarald Freudenberger card = apqns[i].card; 737f2bbc96eSHarald Freudenberger dom = apqns[i].domain; 738fb249ce7SHolger Dengler if (ktype == PKEY_TYPE_EP11 || 739fb249ce7SHolger Dengler ktype == PKEY_TYPE_EP11_AES) { 74055d0a513SHarald Freudenberger rc = ep11_genaeskey(card, dom, ksize, kflags, 741fb249ce7SHolger Dengler keybuf, keybufsize, ktype); 74255d0a513SHarald Freudenberger } else if (ktype == PKEY_TYPE_CCA_DATA) { 743f2bbc96eSHarald Freudenberger rc = cca_genseckey(card, dom, ksize, keybuf); 744f2bbc96eSHarald Freudenberger *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); 7452004b57cSHarald Freudenberger } else { 7462004b57cSHarald Freudenberger /* TOKVER_CCA_VLSC */ 747f2bbc96eSHarald Freudenberger rc = cca_gencipherkey(card, dom, ksize, kflags, 748f2bbc96eSHarald Freudenberger keybuf, keybufsize); 7492004b57cSHarald Freudenberger } 750f2bbc96eSHarald Freudenberger if (rc == 0) 751f2bbc96eSHarald Freudenberger break; 752f2bbc96eSHarald Freudenberger } 753f2bbc96eSHarald Freudenberger 754f2bbc96eSHarald Freudenberger return rc; 755f2bbc96eSHarald Freudenberger } 756f2bbc96eSHarald Freudenberger 757f2bbc96eSHarald Freudenberger static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns, 758f2bbc96eSHarald Freudenberger enum pkey_key_type ktype, enum pkey_key_size ksize, 759f2bbc96eSHarald Freudenberger u32 kflags, const u8 *clrkey, 760f2bbc96eSHarald Freudenberger u8 *keybuf, size_t *keybufsize) 761f2bbc96eSHarald Freudenberger { 762f2bbc96eSHarald Freudenberger int i, card, dom, rc; 763f2bbc96eSHarald Freudenberger 764f2bbc96eSHarald Freudenberger /* check for at least one apqn given */ 765f2bbc96eSHarald Freudenberger if (!apqns || !nr_apqns) 766f2bbc96eSHarald Freudenberger return -EINVAL; 767f2bbc96eSHarald Freudenberger 768f2bbc96eSHarald Freudenberger /* check key type and size */ 769f2bbc96eSHarald Freudenberger switch (ktype) { 770f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_DATA: 771f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_CIPHER: 772f2bbc96eSHarald Freudenberger if (*keybufsize < SECKEYBLOBSIZE) 773f2bbc96eSHarald Freudenberger return -EINVAL; 774f2bbc96eSHarald Freudenberger break; 77555d0a513SHarald Freudenberger case PKEY_TYPE_EP11: 77655d0a513SHarald Freudenberger if (*keybufsize < MINEP11AESKEYBLOBSIZE) 77755d0a513SHarald Freudenberger return -EINVAL; 77855d0a513SHarald Freudenberger break; 779da2863f1SHolger Dengler case PKEY_TYPE_EP11_AES: 780da2863f1SHolger Dengler if (*keybufsize < (sizeof(struct ep11kblob_header) + 781da2863f1SHolger Dengler MINEP11AESKEYBLOBSIZE)) 782da2863f1SHolger Dengler return -EINVAL; 783da2863f1SHolger Dengler break; 784f2bbc96eSHarald Freudenberger default: 785f2bbc96eSHarald Freudenberger return -EINVAL; 786f2bbc96eSHarald Freudenberger } 787f2bbc96eSHarald Freudenberger switch (ksize) { 788f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_128: 789f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_192: 790f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_256: 791f2bbc96eSHarald Freudenberger break; 792f2bbc96eSHarald Freudenberger default: 793f2bbc96eSHarald Freudenberger return -EINVAL; 794f2bbc96eSHarald Freudenberger } 795f2bbc96eSHarald Freudenberger 79643cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 79743cb5a7cSHarald Freudenberger 798f2bbc96eSHarald Freudenberger /* simple try all apqns from the list */ 799f2bbc96eSHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 800f2bbc96eSHarald Freudenberger card = apqns[i].card; 801f2bbc96eSHarald Freudenberger dom = apqns[i].domain; 802da2863f1SHolger Dengler if (ktype == PKEY_TYPE_EP11 || 803da2863f1SHolger Dengler ktype == PKEY_TYPE_EP11_AES) { 80455d0a513SHarald Freudenberger rc = ep11_clr2keyblob(card, dom, ksize, kflags, 805da2863f1SHolger Dengler clrkey, keybuf, keybufsize, 806da2863f1SHolger Dengler ktype); 80755d0a513SHarald Freudenberger } else if (ktype == PKEY_TYPE_CCA_DATA) { 808f2bbc96eSHarald Freudenberger rc = cca_clr2seckey(card, dom, ksize, 809f2bbc96eSHarald Freudenberger clrkey, keybuf); 810f2bbc96eSHarald Freudenberger *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); 8112004b57cSHarald Freudenberger } else { 8122004b57cSHarald Freudenberger /* TOKVER_CCA_VLSC */ 813f2bbc96eSHarald Freudenberger rc = cca_clr2cipherkey(card, dom, ksize, kflags, 814f2bbc96eSHarald Freudenberger clrkey, keybuf, keybufsize); 8152004b57cSHarald Freudenberger } 816f2bbc96eSHarald Freudenberger if (rc == 0) 817f2bbc96eSHarald Freudenberger break; 818f2bbc96eSHarald Freudenberger } 819f2bbc96eSHarald Freudenberger 820f2bbc96eSHarald Freudenberger return rc; 821f2bbc96eSHarald Freudenberger } 822f2bbc96eSHarald Freudenberger 823f2bbc96eSHarald Freudenberger static int pkey_verifykey2(const u8 *key, size_t keylen, 824f2bbc96eSHarald Freudenberger u16 *cardnr, u16 *domain, 825f2bbc96eSHarald Freudenberger enum pkey_key_type *ktype, 826f2bbc96eSHarald Freudenberger enum pkey_key_size *ksize, u32 *flags) 827f2bbc96eSHarald Freudenberger { 828f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 82946a29b03SHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 83046a29b03SHarald Freudenberger int rc; 831f2bbc96eSHarald Freudenberger 83255d0a513SHarald Freudenberger if (keylen < sizeof(struct keytoken_header)) 833f2bbc96eSHarald Freudenberger return -EINVAL; 834f2bbc96eSHarald Freudenberger 8352004b57cSHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL && 8362004b57cSHarald Freudenberger hdr->version == TOKVER_CCA_AES) { 837f2bbc96eSHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *)key; 838f2bbc96eSHarald Freudenberger 839f2bbc96eSHarald Freudenberger rc = cca_check_secaeskeytoken(debug_info, 3, key, 0); 840f2bbc96eSHarald Freudenberger if (rc) 841f2bbc96eSHarald Freudenberger goto out; 842f2bbc96eSHarald Freudenberger if (ktype) 843f2bbc96eSHarald Freudenberger *ktype = PKEY_TYPE_CCA_DATA; 844f2bbc96eSHarald Freudenberger if (ksize) 845f2bbc96eSHarald Freudenberger *ksize = (enum pkey_key_size)t->bitsize; 846f2bbc96eSHarald Freudenberger 847f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 84832ca04bbSHarald Freudenberger ZCRYPT_CEX3C, AES_MK_SET, t->mkvp, 0, 1); 849f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 850f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 851f2bbc96eSHarald Freudenberger if (rc == -ENODEV) { 852f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 853f2bbc96eSHarald Freudenberger *cardnr, *domain, 85432ca04bbSHarald Freudenberger ZCRYPT_CEX3C, AES_MK_SET, 85532ca04bbSHarald Freudenberger 0, t->mkvp, 1); 856f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 857f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 858f2bbc96eSHarald Freudenberger } 859f2bbc96eSHarald Freudenberger if (rc) 860f2bbc96eSHarald Freudenberger goto out; 861f2bbc96eSHarald Freudenberger 862f2bbc96eSHarald Freudenberger *cardnr = ((struct pkey_apqn *)_apqns)->card; 863f2bbc96eSHarald Freudenberger *domain = ((struct pkey_apqn *)_apqns)->domain; 864f2bbc96eSHarald Freudenberger 8652004b57cSHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 8662004b57cSHarald Freudenberger hdr->version == TOKVER_CCA_VLSC) { 867f2bbc96eSHarald Freudenberger struct cipherkeytoken *t = (struct cipherkeytoken *)key; 868f2bbc96eSHarald Freudenberger 869f2bbc96eSHarald Freudenberger rc = cca_check_secaescipherkey(debug_info, 3, key, 0, 1); 870f2bbc96eSHarald Freudenberger if (rc) 871f2bbc96eSHarald Freudenberger goto out; 872f2bbc96eSHarald Freudenberger if (ktype) 873f2bbc96eSHarald Freudenberger *ktype = PKEY_TYPE_CCA_CIPHER; 874f2bbc96eSHarald Freudenberger if (ksize) { 875f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_UNKNOWN; 876f2bbc96eSHarald Freudenberger if (!t->plfver && t->wpllen == 512) 877f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_AES_128; 878f2bbc96eSHarald Freudenberger else if (!t->plfver && t->wpllen == 576) 879f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_AES_192; 880f2bbc96eSHarald Freudenberger else if (!t->plfver && t->wpllen == 640) 881f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_AES_256; 882f2bbc96eSHarald Freudenberger } 883f2bbc96eSHarald Freudenberger 884f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 88532ca04bbSHarald Freudenberger ZCRYPT_CEX6, AES_MK_SET, t->mkvp0, 0, 1); 886f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 887f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 888f2bbc96eSHarald Freudenberger if (rc == -ENODEV) { 889f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 890f2bbc96eSHarald Freudenberger *cardnr, *domain, 89132ca04bbSHarald Freudenberger ZCRYPT_CEX6, AES_MK_SET, 89232ca04bbSHarald Freudenberger 0, t->mkvp0, 1); 893f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 894f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 895f2bbc96eSHarald Freudenberger } 896f2bbc96eSHarald Freudenberger if (rc) 897f2bbc96eSHarald Freudenberger goto out; 898f2bbc96eSHarald Freudenberger 899f2bbc96eSHarald Freudenberger *cardnr = ((struct pkey_apqn *)_apqns)->card; 900f2bbc96eSHarald Freudenberger *domain = ((struct pkey_apqn *)_apqns)->domain; 901f2bbc96eSHarald Freudenberger 9022004b57cSHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA && 9032004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_AES) { 90455d0a513SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *)key; 90555d0a513SHarald Freudenberger 906fa6999e3SHarald Freudenberger rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); 90755d0a513SHarald Freudenberger if (rc) 90855d0a513SHarald Freudenberger goto out; 90955d0a513SHarald Freudenberger if (ktype) 91055d0a513SHarald Freudenberger *ktype = PKEY_TYPE_EP11; 91155d0a513SHarald Freudenberger if (ksize) 91237a08f01SHolger Dengler *ksize = kb->head.bitlen; 91355d0a513SHarald Freudenberger 91455d0a513SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 91555d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, kb->wkvp); 91655d0a513SHarald Freudenberger if (rc) 91755d0a513SHarald Freudenberger goto out; 91855d0a513SHarald Freudenberger 91955d0a513SHarald Freudenberger if (flags) 92055d0a513SHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 92155d0a513SHarald Freudenberger 92255d0a513SHarald Freudenberger *cardnr = ((struct pkey_apqn *)_apqns)->card; 92355d0a513SHarald Freudenberger *domain = ((struct pkey_apqn *)_apqns)->domain; 92455d0a513SHarald Freudenberger 9252004b57cSHarald Freudenberger } else { 926f2bbc96eSHarald Freudenberger rc = -EINVAL; 9272004b57cSHarald Freudenberger } 928f2bbc96eSHarald Freudenberger 929f2bbc96eSHarald Freudenberger out: 930f2bbc96eSHarald Freudenberger kfree(_apqns); 931f2bbc96eSHarald Freudenberger return rc; 932f2bbc96eSHarald Freudenberger } 933f2bbc96eSHarald Freudenberger 934f2bbc96eSHarald Freudenberger static int pkey_keyblob2pkey2(const struct pkey_apqn *apqns, size_t nr_apqns, 935f2bbc96eSHarald Freudenberger const u8 *key, size_t keylen, 936f370f45cSHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 937f2bbc96eSHarald Freudenberger { 938f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 93946a29b03SHarald Freudenberger int i, card, dom, rc; 940f2bbc96eSHarald Freudenberger 941f2bbc96eSHarald Freudenberger /* check for at least one apqn given */ 942f2bbc96eSHarald Freudenberger if (!apqns || !nr_apqns) 943f2bbc96eSHarald Freudenberger return -EINVAL; 944f2bbc96eSHarald Freudenberger 945fb1136d6SIngo Franzki if (keylen < sizeof(struct keytoken_header)) 946fb1136d6SIngo Franzki return -EINVAL; 947fb1136d6SIngo Franzki 94855d0a513SHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL) { 94955d0a513SHarald Freudenberger if (hdr->version == TOKVER_CCA_AES) { 950f2bbc96eSHarald Freudenberger if (keylen != sizeof(struct secaeskeytoken)) 951f2bbc96eSHarald Freudenberger return -EINVAL; 952f2bbc96eSHarald Freudenberger if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) 953f2bbc96eSHarald Freudenberger return -EINVAL; 95455d0a513SHarald Freudenberger } else if (hdr->version == TOKVER_CCA_VLSC) { 955f2bbc96eSHarald Freudenberger if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 956f2bbc96eSHarald Freudenberger return -EINVAL; 957f2bbc96eSHarald Freudenberger if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) 958f2bbc96eSHarald Freudenberger return -EINVAL; 95955d0a513SHarald Freudenberger } else { 960f2bbc96eSHarald Freudenberger DEBUG_ERR("%s unknown CCA internal token version %d\n", 961f2bbc96eSHarald Freudenberger __func__, hdr->version); 962fb1136d6SIngo Franzki return -EINVAL; 963fb1136d6SIngo Franzki } 96455d0a513SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA) { 96555d0a513SHarald Freudenberger if (hdr->version == TOKVER_EP11_AES) { 966fa6999e3SHarald Freudenberger if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) 96755d0a513SHarald Freudenberger return -EINVAL; 968*d1fdfb0bSHolger Dengler } else if (hdr->version == TOKVER_EP11_AES_WITH_HEADER) { 969*d1fdfb0bSHolger Dengler if (ep11_check_aes_key_with_hdr(debug_info, 3, 970*d1fdfb0bSHolger Dengler key, keylen, 1)) 971*d1fdfb0bSHolger Dengler return -EINVAL; 97255d0a513SHarald Freudenberger } else { 973f370f45cSHarald Freudenberger return pkey_nonccatok2pkey(key, keylen, 974f370f45cSHarald Freudenberger protkey, protkeylen, 975f370f45cSHarald Freudenberger protkeytype); 97655d0a513SHarald Freudenberger } 97755d0a513SHarald Freudenberger } else { 978f2bbc96eSHarald Freudenberger DEBUG_ERR("%s unknown/unsupported blob type %d\n", 979f2bbc96eSHarald Freudenberger __func__, hdr->type); 980f2bbc96eSHarald Freudenberger return -EINVAL; 981fb1136d6SIngo Franzki } 982f2bbc96eSHarald Freudenberger 98343cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 98443cb5a7cSHarald Freudenberger 985f2bbc96eSHarald Freudenberger /* simple try all apqns from the list */ 986f2bbc96eSHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 987f2bbc96eSHarald Freudenberger card = apqns[i].card; 988f2bbc96eSHarald Freudenberger dom = apqns[i].domain; 9892004b57cSHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL && 9902004b57cSHarald Freudenberger hdr->version == TOKVER_CCA_AES) { 991f370f45cSHarald Freudenberger rc = cca_sec2protkey(card, dom, key, 992f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 9932004b57cSHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 9942004b57cSHarald Freudenberger hdr->version == TOKVER_CCA_VLSC) { 995f370f45cSHarald Freudenberger rc = cca_cipher2protkey(card, dom, key, 996f370f45cSHarald Freudenberger protkey, protkeylen, 997f370f45cSHarald Freudenberger protkeytype); 9982004b57cSHarald Freudenberger } else { 999*d1fdfb0bSHolger Dengler rc = ep11_kblob2protkey(card, dom, key, keylen, 1000f370f45cSHarald Freudenberger protkey, protkeylen, 1001f370f45cSHarald Freudenberger protkeytype); 100255d0a513SHarald Freudenberger } 1003f2bbc96eSHarald Freudenberger if (rc == 0) 1004f2bbc96eSHarald Freudenberger break; 1005f2bbc96eSHarald Freudenberger } 1006f2bbc96eSHarald Freudenberger 1007f2bbc96eSHarald Freudenberger return rc; 1008f2bbc96eSHarald Freudenberger } 1009f2bbc96eSHarald Freudenberger 1010f2bbc96eSHarald Freudenberger static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags, 1011f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns, size_t *nr_apqns) 1012f2bbc96eSHarald Freudenberger { 1013f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 101446a29b03SHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 101546a29b03SHarald Freudenberger int rc; 1016f2bbc96eSHarald Freudenberger 101755d0a513SHarald Freudenberger if (keylen < sizeof(struct keytoken_header) || flags == 0) 1018f2bbc96eSHarald Freudenberger return -EINVAL; 1019f2bbc96eSHarald Freudenberger 102043cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 102143cb5a7cSHarald Freudenberger 10222004b57cSHarald Freudenberger if (hdr->type == TOKTYPE_NON_CCA && 10232004b57cSHarald Freudenberger (hdr->version == TOKVER_EP11_AES_WITH_HEADER || 10242004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_ECC_WITH_HEADER) && 10252004b57cSHarald Freudenberger is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 1026fa6999e3SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *) 1027fa6999e3SHarald Freudenberger (key + sizeof(struct ep11kblob_header)); 102846a29b03SHarald Freudenberger int minhwtype = 0, api = 0; 1029fa6999e3SHarald Freudenberger 1030fa6999e3SHarald Freudenberger if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) 1031fa6999e3SHarald Freudenberger return -EINVAL; 1032fa6999e3SHarald Freudenberger if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { 1033fa6999e3SHarald Freudenberger minhwtype = ZCRYPT_CEX7; 1034fa6999e3SHarald Freudenberger api = EP11_API_V; 1035fa6999e3SHarald Freudenberger } 1036fa6999e3SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 1037fa6999e3SHarald Freudenberger minhwtype, api, kb->wkvp); 1038fa6999e3SHarald Freudenberger if (rc) 1039fa6999e3SHarald Freudenberger goto out; 10402004b57cSHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA && 10412004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_AES && 10422004b57cSHarald Freudenberger is_ep11_keyblob(key)) { 104355d0a513SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *)key; 104446a29b03SHarald Freudenberger int minhwtype = 0, api = 0; 104555d0a513SHarald Freudenberger 104655d0a513SHarald Freudenberger if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) 104755d0a513SHarald Freudenberger return -EINVAL; 104855d0a513SHarald Freudenberger if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { 104955d0a513SHarald Freudenberger minhwtype = ZCRYPT_CEX7; 105055d0a513SHarald Freudenberger api = EP11_API_V; 105155d0a513SHarald Freudenberger } 105255d0a513SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 105355d0a513SHarald Freudenberger minhwtype, api, kb->wkvp); 105455d0a513SHarald Freudenberger if (rc) 105555d0a513SHarald Freudenberger goto out; 105655d0a513SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { 1057f2bbc96eSHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 105846a29b03SHarald Freudenberger int minhwtype = ZCRYPT_CEX3C; 1059f2bbc96eSHarald Freudenberger 1060f2bbc96eSHarald Freudenberger if (hdr->version == TOKVER_CCA_AES) { 1061f2bbc96eSHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *)key; 1062f2bbc96eSHarald Freudenberger 1063f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 1064f2bbc96eSHarald Freudenberger cur_mkvp = t->mkvp; 1065f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 1066f2bbc96eSHarald Freudenberger old_mkvp = t->mkvp; 106755d0a513SHarald Freudenberger } else if (hdr->version == TOKVER_CCA_VLSC) { 1068f2bbc96eSHarald Freudenberger struct cipherkeytoken *t = (struct cipherkeytoken *)key; 1069f2bbc96eSHarald Freudenberger 1070f2bbc96eSHarald Freudenberger minhwtype = ZCRYPT_CEX6; 1071f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 1072f2bbc96eSHarald Freudenberger cur_mkvp = t->mkvp0; 1073f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 1074f2bbc96eSHarald Freudenberger old_mkvp = t->mkvp0; 107555d0a513SHarald Freudenberger } else { 107655d0a513SHarald Freudenberger /* unknown cca internal token type */ 107755d0a513SHarald Freudenberger return -EINVAL; 1078f2bbc96eSHarald Freudenberger } 1079f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 108032ca04bbSHarald Freudenberger minhwtype, AES_MK_SET, 108132ca04bbSHarald Freudenberger cur_mkvp, old_mkvp, 1); 1082f2bbc96eSHarald Freudenberger if (rc) 1083f2bbc96eSHarald Freudenberger goto out; 1084fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 1085fa6999e3SHarald Freudenberger struct eccprivkeytoken *t = (struct eccprivkeytoken *)key; 108646a29b03SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 1087fa6999e3SHarald Freudenberger 1088fa6999e3SHarald Freudenberger if (t->secid == 0x20) { 1089fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 1090fa6999e3SHarald Freudenberger cur_mkvp = t->mkvp; 1091fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 1092fa6999e3SHarald Freudenberger old_mkvp = t->mkvp; 1093fa6999e3SHarald Freudenberger } else { 1094fa6999e3SHarald Freudenberger /* unknown cca internal 2 token type */ 1095fa6999e3SHarald Freudenberger return -EINVAL; 1096fa6999e3SHarald Freudenberger } 1097fa6999e3SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 1098fa6999e3SHarald Freudenberger ZCRYPT_CEX7, APKA_MK_SET, 1099fa6999e3SHarald Freudenberger cur_mkvp, old_mkvp, 1); 1100fa6999e3SHarald Freudenberger if (rc) 1101fa6999e3SHarald Freudenberger goto out; 11022004b57cSHarald Freudenberger } else { 110355d0a513SHarald Freudenberger return -EINVAL; 11042004b57cSHarald Freudenberger } 110555d0a513SHarald Freudenberger 1106f2bbc96eSHarald Freudenberger if (apqns) { 1107f2bbc96eSHarald Freudenberger if (*nr_apqns < _nr_apqns) 1108f2bbc96eSHarald Freudenberger rc = -ENOSPC; 1109f2bbc96eSHarald Freudenberger else 1110f2bbc96eSHarald Freudenberger memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 1111f2bbc96eSHarald Freudenberger } 1112f2bbc96eSHarald Freudenberger *nr_apqns = _nr_apqns; 1113f2bbc96eSHarald Freudenberger 1114f2bbc96eSHarald Freudenberger out: 1115f2bbc96eSHarald Freudenberger kfree(_apqns); 1116f2bbc96eSHarald Freudenberger return rc; 1117f2bbc96eSHarald Freudenberger } 1118f2bbc96eSHarald Freudenberger 1119f2bbc96eSHarald Freudenberger static int pkey_apqns4keytype(enum pkey_key_type ktype, 1120f2bbc96eSHarald Freudenberger u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags, 1121f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns, size_t *nr_apqns) 1122f2bbc96eSHarald Freudenberger { 1123f2bbc96eSHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 112446a29b03SHarald Freudenberger int rc; 1125f2bbc96eSHarald Freudenberger 112643cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 112743cb5a7cSHarald Freudenberger 1128f2bbc96eSHarald Freudenberger if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) { 1129f2bbc96eSHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 1130f2bbc96eSHarald Freudenberger int minhwtype = ZCRYPT_CEX3C; 1131f2bbc96eSHarald Freudenberger 1132f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 1133f2bbc96eSHarald Freudenberger cur_mkvp = *((u64 *)cur_mkvp); 1134f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 1135f2bbc96eSHarald Freudenberger old_mkvp = *((u64 *)alt_mkvp); 1136f2bbc96eSHarald Freudenberger if (ktype == PKEY_TYPE_CCA_CIPHER) 1137f2bbc96eSHarald Freudenberger minhwtype = ZCRYPT_CEX6; 1138f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 113932ca04bbSHarald Freudenberger minhwtype, AES_MK_SET, 114032ca04bbSHarald Freudenberger cur_mkvp, old_mkvp, 1); 1141f2bbc96eSHarald Freudenberger if (rc) 1142f2bbc96eSHarald Freudenberger goto out; 1143fa6999e3SHarald Freudenberger } else if (ktype == PKEY_TYPE_CCA_ECC) { 1144fa6999e3SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 1145fa6999e3SHarald Freudenberger 1146fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 1147fa6999e3SHarald Freudenberger cur_mkvp = *((u64 *)cur_mkvp); 1148fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 1149fa6999e3SHarald Freudenberger old_mkvp = *((u64 *)alt_mkvp); 1150fa6999e3SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 1151fa6999e3SHarald Freudenberger ZCRYPT_CEX7, APKA_MK_SET, 1152fa6999e3SHarald Freudenberger cur_mkvp, old_mkvp, 1); 1153fa6999e3SHarald Freudenberger if (rc) 1154fa6999e3SHarald Freudenberger goto out; 1155fa6999e3SHarald Freudenberger 1156fa6999e3SHarald Freudenberger } else if (ktype == PKEY_TYPE_EP11 || 1157fa6999e3SHarald Freudenberger ktype == PKEY_TYPE_EP11_AES || 1158fa6999e3SHarald Freudenberger ktype == PKEY_TYPE_EP11_ECC) { 115955d0a513SHarald Freudenberger u8 *wkvp = NULL; 116055d0a513SHarald Freudenberger 116155d0a513SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 116255d0a513SHarald Freudenberger wkvp = cur_mkvp; 116355d0a513SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 116455d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, wkvp); 116555d0a513SHarald Freudenberger if (rc) 116655d0a513SHarald Freudenberger goto out; 116755d0a513SHarald Freudenberger 11682004b57cSHarald Freudenberger } else { 116955d0a513SHarald Freudenberger return -EINVAL; 11702004b57cSHarald Freudenberger } 117155d0a513SHarald Freudenberger 1172f2bbc96eSHarald Freudenberger if (apqns) { 1173f2bbc96eSHarald Freudenberger if (*nr_apqns < _nr_apqns) 1174f2bbc96eSHarald Freudenberger rc = -ENOSPC; 1175f2bbc96eSHarald Freudenberger else 1176f2bbc96eSHarald Freudenberger memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 1177f2bbc96eSHarald Freudenberger } 1178f2bbc96eSHarald Freudenberger *nr_apqns = _nr_apqns; 1179f2bbc96eSHarald Freudenberger 1180f2bbc96eSHarald Freudenberger out: 1181f2bbc96eSHarald Freudenberger kfree(_apqns); 1182f2bbc96eSHarald Freudenberger return rc; 1183f2bbc96eSHarald Freudenberger } 1184fb1136d6SIngo Franzki 1185fa6999e3SHarald Freudenberger static int pkey_keyblob2pkey3(const struct pkey_apqn *apqns, size_t nr_apqns, 1186f370f45cSHarald Freudenberger const u8 *key, size_t keylen, 1187f370f45cSHarald Freudenberger u8 *protkey, u32 *protkeylen, u32 *protkeytype) 1188fa6999e3SHarald Freudenberger { 1189fa6999e3SHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 119046a29b03SHarald Freudenberger int i, card, dom, rc; 1191fa6999e3SHarald Freudenberger 1192fa6999e3SHarald Freudenberger /* check for at least one apqn given */ 1193fa6999e3SHarald Freudenberger if (!apqns || !nr_apqns) 1194fa6999e3SHarald Freudenberger return -EINVAL; 1195fa6999e3SHarald Freudenberger 1196fa6999e3SHarald Freudenberger if (keylen < sizeof(struct keytoken_header)) 1197fa6999e3SHarald Freudenberger return -EINVAL; 1198fa6999e3SHarald Freudenberger 11992004b57cSHarald Freudenberger if (hdr->type == TOKTYPE_NON_CCA && 12002004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_AES_WITH_HEADER && 12012004b57cSHarald Freudenberger is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 1202fa6999e3SHarald Freudenberger /* EP11 AES key blob with header */ 1203fa6999e3SHarald Freudenberger if (ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1)) 1204fa6999e3SHarald Freudenberger return -EINVAL; 12052004b57cSHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA && 12062004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_ECC_WITH_HEADER && 12072004b57cSHarald Freudenberger is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 1208fa6999e3SHarald Freudenberger /* EP11 ECC key blob with header */ 1209fa6999e3SHarald Freudenberger if (ep11_check_ecc_key_with_hdr(debug_info, 3, key, keylen, 1)) 1210fa6999e3SHarald Freudenberger return -EINVAL; 12112004b57cSHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA && 12122004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_AES && 12132004b57cSHarald Freudenberger is_ep11_keyblob(key)) { 1214fa6999e3SHarald Freudenberger /* EP11 AES key blob with header in session field */ 1215fa6999e3SHarald Freudenberger if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) 1216fa6999e3SHarald Freudenberger return -EINVAL; 1217fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { 1218fa6999e3SHarald Freudenberger if (hdr->version == TOKVER_CCA_AES) { 1219fa6999e3SHarald Freudenberger /* CCA AES data key */ 1220fa6999e3SHarald Freudenberger if (keylen != sizeof(struct secaeskeytoken)) 1221fa6999e3SHarald Freudenberger return -EINVAL; 1222fa6999e3SHarald Freudenberger if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) 1223fa6999e3SHarald Freudenberger return -EINVAL; 1224fa6999e3SHarald Freudenberger } else if (hdr->version == TOKVER_CCA_VLSC) { 1225fa6999e3SHarald Freudenberger /* CCA AES cipher key */ 1226fa6999e3SHarald Freudenberger if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 1227fa6999e3SHarald Freudenberger return -EINVAL; 1228fa6999e3SHarald Freudenberger if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) 1229fa6999e3SHarald Freudenberger return -EINVAL; 1230fa6999e3SHarald Freudenberger } else { 1231fa6999e3SHarald Freudenberger DEBUG_ERR("%s unknown CCA internal token version %d\n", 1232fa6999e3SHarald Freudenberger __func__, hdr->version); 1233fa6999e3SHarald Freudenberger return -EINVAL; 1234fa6999e3SHarald Freudenberger } 1235fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 1236fa6999e3SHarald Freudenberger /* CCA ECC (private) key */ 1237fa6999e3SHarald Freudenberger if (keylen < sizeof(struct eccprivkeytoken)) 1238fa6999e3SHarald Freudenberger return -EINVAL; 1239fa6999e3SHarald Freudenberger if (cca_check_sececckeytoken(debug_info, 3, key, keylen, 1)) 1240fa6999e3SHarald Freudenberger return -EINVAL; 1241fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA) { 1242f370f45cSHarald Freudenberger return pkey_nonccatok2pkey(key, keylen, 1243f370f45cSHarald Freudenberger protkey, protkeylen, protkeytype); 1244fa6999e3SHarald Freudenberger } else { 1245fa6999e3SHarald Freudenberger DEBUG_ERR("%s unknown/unsupported blob type %d\n", 1246fa6999e3SHarald Freudenberger __func__, hdr->type); 1247fa6999e3SHarald Freudenberger return -EINVAL; 1248fa6999e3SHarald Freudenberger } 1249fa6999e3SHarald Freudenberger 1250fa6999e3SHarald Freudenberger /* simple try all apqns from the list */ 1251fa6999e3SHarald Freudenberger for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 1252fa6999e3SHarald Freudenberger card = apqns[i].card; 1253fa6999e3SHarald Freudenberger dom = apqns[i].domain; 12542004b57cSHarald Freudenberger if (hdr->type == TOKTYPE_NON_CCA && 12552004b57cSHarald Freudenberger (hdr->version == TOKVER_EP11_AES_WITH_HEADER || 12562004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_ECC_WITH_HEADER) && 12572004b57cSHarald Freudenberger is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) 1258fa6999e3SHarald Freudenberger rc = ep11_kblob2protkey(card, dom, key, hdr->len, 1259*d1fdfb0bSHolger Dengler protkey, protkeylen, 1260*d1fdfb0bSHolger Dengler protkeytype); 12612004b57cSHarald Freudenberger else if (hdr->type == TOKTYPE_NON_CCA && 12622004b57cSHarald Freudenberger hdr->version == TOKVER_EP11_AES && 12632004b57cSHarald Freudenberger is_ep11_keyblob(key)) 1264fa6999e3SHarald Freudenberger rc = ep11_kblob2protkey(card, dom, key, hdr->len, 1265*d1fdfb0bSHolger Dengler protkey, protkeylen, 1266*d1fdfb0bSHolger Dengler protkeytype); 1267fa6999e3SHarald Freudenberger else if (hdr->type == TOKTYPE_CCA_INTERNAL && 1268fa6999e3SHarald Freudenberger hdr->version == TOKVER_CCA_AES) 1269fa6999e3SHarald Freudenberger rc = cca_sec2protkey(card, dom, key, protkey, 1270fa6999e3SHarald Freudenberger protkeylen, protkeytype); 1271fa6999e3SHarald Freudenberger else if (hdr->type == TOKTYPE_CCA_INTERNAL && 1272fa6999e3SHarald Freudenberger hdr->version == TOKVER_CCA_VLSC) 1273fa6999e3SHarald Freudenberger rc = cca_cipher2protkey(card, dom, key, protkey, 1274fa6999e3SHarald Freudenberger protkeylen, protkeytype); 1275fa6999e3SHarald Freudenberger else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) 1276fa6999e3SHarald Freudenberger rc = cca_ecc2protkey(card, dom, key, protkey, 1277fa6999e3SHarald Freudenberger protkeylen, protkeytype); 1278fa6999e3SHarald Freudenberger else 1279fa6999e3SHarald Freudenberger return -EINVAL; 1280fa6999e3SHarald Freudenberger } 1281fa6999e3SHarald Freudenberger 1282fa6999e3SHarald Freudenberger return rc; 1283fa6999e3SHarald Freudenberger } 1284fa6999e3SHarald Freudenberger 1285fb1136d6SIngo Franzki /* 1286e80d4af0SHarald Freudenberger * File io functions 1287e80d4af0SHarald Freudenberger */ 1288e80d4af0SHarald Freudenberger 1289f2bbc96eSHarald Freudenberger static void *_copy_key_from_user(void __user *ukey, size_t keylen) 1290f2bbc96eSHarald Freudenberger { 12919e436c19SHarald Freudenberger if (!ukey || keylen < MINKEYBLOBBUFSIZE || keylen > KEYBLOBBUFSIZE) 1292f2bbc96eSHarald Freudenberger return ERR_PTR(-EINVAL); 1293f2bbc96eSHarald Freudenberger 12948b57e7c8SMarkus Elfring return memdup_user(ukey, keylen); 1295f2bbc96eSHarald Freudenberger } 1296f2bbc96eSHarald Freudenberger 1297f2bbc96eSHarald Freudenberger static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns) 1298f2bbc96eSHarald Freudenberger { 12998b57e7c8SMarkus Elfring if (!uapqns || nr_apqns == 0) 13008b57e7c8SMarkus Elfring return NULL; 1301f2bbc96eSHarald Freudenberger 13028b57e7c8SMarkus Elfring return memdup_user(uapqns, nr_apqns * sizeof(struct pkey_apqn)); 1303f2bbc96eSHarald Freudenberger } 1304f2bbc96eSHarald Freudenberger 1305e80d4af0SHarald Freudenberger static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, 1306e80d4af0SHarald Freudenberger unsigned long arg) 1307e80d4af0SHarald Freudenberger { 1308e80d4af0SHarald Freudenberger int rc; 1309e80d4af0SHarald Freudenberger 1310e80d4af0SHarald Freudenberger switch (cmd) { 1311e80d4af0SHarald Freudenberger case PKEY_GENSECK: { 1312e80d4af0SHarald Freudenberger struct pkey_genseck __user *ugs = (void __user *)arg; 1313e80d4af0SHarald Freudenberger struct pkey_genseck kgs; 1314e80d4af0SHarald Freudenberger 1315e80d4af0SHarald Freudenberger if (copy_from_user(&kgs, ugs, sizeof(kgs))) 1316e80d4af0SHarald Freudenberger return -EFAULT; 1317efc598e6SHarald Freudenberger rc = cca_genseckey(kgs.cardnr, kgs.domain, 1318efc598e6SHarald Freudenberger kgs.keytype, kgs.seckey.seckey); 1319efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_genseckey()=%d\n", __func__, rc); 1320e80d4af0SHarald Freudenberger if (rc) 1321e80d4af0SHarald Freudenberger break; 1322e80d4af0SHarald Freudenberger if (copy_to_user(ugs, &kgs, sizeof(kgs))) 1323e80d4af0SHarald Freudenberger return -EFAULT; 1324e80d4af0SHarald Freudenberger break; 1325e80d4af0SHarald Freudenberger } 1326e80d4af0SHarald Freudenberger case PKEY_CLR2SECK: { 1327e80d4af0SHarald Freudenberger struct pkey_clr2seck __user *ucs = (void __user *)arg; 1328e80d4af0SHarald Freudenberger struct pkey_clr2seck kcs; 1329e80d4af0SHarald Freudenberger 1330e80d4af0SHarald Freudenberger if (copy_from_user(&kcs, ucs, sizeof(kcs))) 1331e80d4af0SHarald Freudenberger return -EFAULT; 1332efc598e6SHarald Freudenberger rc = cca_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype, 1333efc598e6SHarald Freudenberger kcs.clrkey.clrkey, kcs.seckey.seckey); 1334efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_clr2seckey()=%d\n", __func__, rc); 1335e80d4af0SHarald Freudenberger if (rc) 1336e80d4af0SHarald Freudenberger break; 1337e80d4af0SHarald Freudenberger if (copy_to_user(ucs, &kcs, sizeof(kcs))) 1338e80d4af0SHarald Freudenberger return -EFAULT; 1339e80d4af0SHarald Freudenberger memzero_explicit(&kcs, sizeof(kcs)); 1340e80d4af0SHarald Freudenberger break; 1341e80d4af0SHarald Freudenberger } 1342e80d4af0SHarald Freudenberger case PKEY_SEC2PROTK: { 1343e80d4af0SHarald Freudenberger struct pkey_sec2protk __user *usp = (void __user *)arg; 1344e80d4af0SHarald Freudenberger struct pkey_sec2protk ksp; 1345e80d4af0SHarald Freudenberger 1346e80d4af0SHarald Freudenberger if (copy_from_user(&ksp, usp, sizeof(ksp))) 1347e80d4af0SHarald Freudenberger return -EFAULT; 1348f370f45cSHarald Freudenberger ksp.protkey.len = sizeof(ksp.protkey.protkey); 1349efc598e6SHarald Freudenberger rc = cca_sec2protkey(ksp.cardnr, ksp.domain, 1350efc598e6SHarald Freudenberger ksp.seckey.seckey, ksp.protkey.protkey, 1351aab73d27SHarald Freudenberger &ksp.protkey.len, &ksp.protkey.type); 1352efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_sec2protkey()=%d\n", __func__, rc); 1353e80d4af0SHarald Freudenberger if (rc) 1354e80d4af0SHarald Freudenberger break; 1355e80d4af0SHarald Freudenberger if (copy_to_user(usp, &ksp, sizeof(ksp))) 1356e80d4af0SHarald Freudenberger return -EFAULT; 1357e80d4af0SHarald Freudenberger break; 1358e80d4af0SHarald Freudenberger } 1359e80d4af0SHarald Freudenberger case PKEY_CLR2PROTK: { 1360e80d4af0SHarald Freudenberger struct pkey_clr2protk __user *ucp = (void __user *)arg; 1361e80d4af0SHarald Freudenberger struct pkey_clr2protk kcp; 1362e80d4af0SHarald Freudenberger 1363e80d4af0SHarald Freudenberger if (copy_from_user(&kcp, ucp, sizeof(kcp))) 1364e80d4af0SHarald Freudenberger return -EFAULT; 1365f370f45cSHarald Freudenberger kcp.protkey.len = sizeof(kcp.protkey.protkey); 1366f370f45cSHarald Freudenberger rc = pkey_clr2protkey(kcp.keytype, kcp.clrkey.clrkey, 1367f370f45cSHarald Freudenberger kcp.protkey.protkey, 1368f370f45cSHarald Freudenberger &kcp.protkey.len, &kcp.protkey.type); 1369ac2b96f3SHarald Freudenberger DEBUG_DBG("%s pkey_clr2protkey()=%d\n", __func__, rc); 1370e80d4af0SHarald Freudenberger if (rc) 1371e80d4af0SHarald Freudenberger break; 1372e80d4af0SHarald Freudenberger if (copy_to_user(ucp, &kcp, sizeof(kcp))) 1373e80d4af0SHarald Freudenberger return -EFAULT; 1374e80d4af0SHarald Freudenberger memzero_explicit(&kcp, sizeof(kcp)); 1375e80d4af0SHarald Freudenberger break; 1376e80d4af0SHarald Freudenberger } 1377e80d4af0SHarald Freudenberger case PKEY_FINDCARD: { 1378e80d4af0SHarald Freudenberger struct pkey_findcard __user *ufc = (void __user *)arg; 1379e80d4af0SHarald Freudenberger struct pkey_findcard kfc; 1380e80d4af0SHarald Freudenberger 1381e80d4af0SHarald Freudenberger if (copy_from_user(&kfc, ufc, sizeof(kfc))) 1382e80d4af0SHarald Freudenberger return -EFAULT; 1383efc598e6SHarald Freudenberger rc = cca_findcard(kfc.seckey.seckey, 1384e80d4af0SHarald Freudenberger &kfc.cardnr, &kfc.domain, 1); 1385efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_findcard()=%d\n", __func__, rc); 1386efc598e6SHarald Freudenberger if (rc < 0) 1387e80d4af0SHarald Freudenberger break; 1388e80d4af0SHarald Freudenberger if (copy_to_user(ufc, &kfc, sizeof(kfc))) 1389e80d4af0SHarald Freudenberger return -EFAULT; 1390e80d4af0SHarald Freudenberger break; 1391e80d4af0SHarald Freudenberger } 1392e80d4af0SHarald Freudenberger case PKEY_SKEY2PKEY: { 1393e80d4af0SHarald Freudenberger struct pkey_skey2pkey __user *usp = (void __user *)arg; 1394e80d4af0SHarald Freudenberger struct pkey_skey2pkey ksp; 1395e80d4af0SHarald Freudenberger 1396e80d4af0SHarald Freudenberger if (copy_from_user(&ksp, usp, sizeof(ksp))) 1397e80d4af0SHarald Freudenberger return -EFAULT; 1398f370f45cSHarald Freudenberger ksp.protkey.len = sizeof(ksp.protkey.protkey); 1399f370f45cSHarald Freudenberger rc = pkey_skey2pkey(ksp.seckey.seckey, ksp.protkey.protkey, 1400f370f45cSHarald Freudenberger &ksp.protkey.len, &ksp.protkey.type); 1401ac2b96f3SHarald Freudenberger DEBUG_DBG("%s pkey_skey2pkey()=%d\n", __func__, rc); 1402e80d4af0SHarald Freudenberger if (rc) 1403e80d4af0SHarald Freudenberger break; 1404e80d4af0SHarald Freudenberger if (copy_to_user(usp, &ksp, sizeof(ksp))) 1405e80d4af0SHarald Freudenberger return -EFAULT; 1406e80d4af0SHarald Freudenberger break; 1407e80d4af0SHarald Freudenberger } 1408e61a6134SHarald Freudenberger case PKEY_VERIFYKEY: { 1409e61a6134SHarald Freudenberger struct pkey_verifykey __user *uvk = (void __user *)arg; 1410e61a6134SHarald Freudenberger struct pkey_verifykey kvk; 1411e61a6134SHarald Freudenberger 1412e61a6134SHarald Freudenberger if (copy_from_user(&kvk, uvk, sizeof(kvk))) 1413e61a6134SHarald Freudenberger return -EFAULT; 1414e61a6134SHarald Freudenberger rc = pkey_verifykey(&kvk.seckey, &kvk.cardnr, &kvk.domain, 1415e61a6134SHarald Freudenberger &kvk.keysize, &kvk.attributes); 1416ac2b96f3SHarald Freudenberger DEBUG_DBG("%s pkey_verifykey()=%d\n", __func__, rc); 1417e61a6134SHarald Freudenberger if (rc) 1418e61a6134SHarald Freudenberger break; 1419e61a6134SHarald Freudenberger if (copy_to_user(uvk, &kvk, sizeof(kvk))) 1420e61a6134SHarald Freudenberger return -EFAULT; 1421e61a6134SHarald Freudenberger break; 1422e61a6134SHarald Freudenberger } 1423a45a5c7dSIngo Franzki case PKEY_GENPROTK: { 1424a45a5c7dSIngo Franzki struct pkey_genprotk __user *ugp = (void __user *)arg; 1425a45a5c7dSIngo Franzki struct pkey_genprotk kgp; 1426a45a5c7dSIngo Franzki 1427a45a5c7dSIngo Franzki if (copy_from_user(&kgp, ugp, sizeof(kgp))) 1428a45a5c7dSIngo Franzki return -EFAULT; 1429f370f45cSHarald Freudenberger kgp.protkey.len = sizeof(kgp.protkey.protkey); 1430f370f45cSHarald Freudenberger rc = pkey_genprotkey(kgp.keytype, kgp.protkey.protkey, 1431f370f45cSHarald Freudenberger &kgp.protkey.len, &kgp.protkey.type); 1432a45a5c7dSIngo Franzki DEBUG_DBG("%s pkey_genprotkey()=%d\n", __func__, rc); 1433a45a5c7dSIngo Franzki if (rc) 1434a45a5c7dSIngo Franzki break; 1435a45a5c7dSIngo Franzki if (copy_to_user(ugp, &kgp, sizeof(kgp))) 1436a45a5c7dSIngo Franzki return -EFAULT; 1437a45a5c7dSIngo Franzki break; 1438a45a5c7dSIngo Franzki } 1439cb26b9ffSIngo Franzki case PKEY_VERIFYPROTK: { 1440cb26b9ffSIngo Franzki struct pkey_verifyprotk __user *uvp = (void __user *)arg; 1441cb26b9ffSIngo Franzki struct pkey_verifyprotk kvp; 1442cb26b9ffSIngo Franzki 1443cb26b9ffSIngo Franzki if (copy_from_user(&kvp, uvp, sizeof(kvp))) 1444cb26b9ffSIngo Franzki return -EFAULT; 1445f370f45cSHarald Freudenberger rc = pkey_verifyprotkey(kvp.protkey.protkey, 1446f370f45cSHarald Freudenberger kvp.protkey.len, kvp.protkey.type); 1447cb26b9ffSIngo Franzki DEBUG_DBG("%s pkey_verifyprotkey()=%d\n", __func__, rc); 1448cb26b9ffSIngo Franzki break; 1449cb26b9ffSIngo Franzki } 1450fb1136d6SIngo Franzki case PKEY_KBLOB2PROTK: { 1451fb1136d6SIngo Franzki struct pkey_kblob2pkey __user *utp = (void __user *)arg; 1452fb1136d6SIngo Franzki struct pkey_kblob2pkey ktp; 1453183cb469SHarald Freudenberger u8 *kkey; 1454fb1136d6SIngo Franzki 1455fb1136d6SIngo Franzki if (copy_from_user(&ktp, utp, sizeof(ktp))) 1456fb1136d6SIngo Franzki return -EFAULT; 1457f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(ktp.key, ktp.keylen); 1458f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) 1459f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1460f370f45cSHarald Freudenberger ktp.protkey.len = sizeof(ktp.protkey.protkey); 1461f370f45cSHarald Freudenberger rc = pkey_keyblob2pkey(kkey, ktp.keylen, ktp.protkey.protkey, 1462f370f45cSHarald Freudenberger &ktp.protkey.len, &ktp.protkey.type); 1463fb1136d6SIngo Franzki DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n", __func__, rc); 1464844cf829SHolger Dengler memzero_explicit(kkey, ktp.keylen); 1465fb1136d6SIngo Franzki kfree(kkey); 1466fb1136d6SIngo Franzki if (rc) 1467fb1136d6SIngo Franzki break; 1468fb1136d6SIngo Franzki if (copy_to_user(utp, &ktp, sizeof(ktp))) 1469fb1136d6SIngo Franzki return -EFAULT; 1470fb1136d6SIngo Franzki break; 1471fb1136d6SIngo Franzki } 1472f2bbc96eSHarald Freudenberger case PKEY_GENSECK2: { 1473f2bbc96eSHarald Freudenberger struct pkey_genseck2 __user *ugs = (void __user *)arg; 147446a29b03SHarald Freudenberger size_t klen = KEYBLOBBUFSIZE; 1475f2bbc96eSHarald Freudenberger struct pkey_genseck2 kgs; 1476f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns; 1477f2bbc96eSHarald Freudenberger u8 *kkey; 1478f2bbc96eSHarald Freudenberger 1479f2bbc96eSHarald Freudenberger if (copy_from_user(&kgs, ugs, sizeof(kgs))) 1480f2bbc96eSHarald Freudenberger return -EFAULT; 1481f2bbc96eSHarald Freudenberger apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries); 1482f2bbc96eSHarald Freudenberger if (IS_ERR(apqns)) 1483f2bbc96eSHarald Freudenberger return PTR_ERR(apqns); 1484fb249ce7SHolger Dengler kkey = kzalloc(klen, GFP_KERNEL); 1485f2bbc96eSHarald Freudenberger if (!kkey) { 1486f2bbc96eSHarald Freudenberger kfree(apqns); 1487f2bbc96eSHarald Freudenberger return -ENOMEM; 1488f2bbc96eSHarald Freudenberger } 1489f2bbc96eSHarald Freudenberger rc = pkey_genseckey2(apqns, kgs.apqn_entries, 1490f2bbc96eSHarald Freudenberger kgs.type, kgs.size, kgs.keygenflags, 1491f2bbc96eSHarald Freudenberger kkey, &klen); 1492f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_genseckey2()=%d\n", __func__, rc); 1493f2bbc96eSHarald Freudenberger kfree(apqns); 1494f2bbc96eSHarald Freudenberger if (rc) { 1495f2bbc96eSHarald Freudenberger kfree(kkey); 1496f2bbc96eSHarald Freudenberger break; 1497f2bbc96eSHarald Freudenberger } 1498f2bbc96eSHarald Freudenberger if (kgs.key) { 1499f2bbc96eSHarald Freudenberger if (kgs.keylen < klen) { 1500f2bbc96eSHarald Freudenberger kfree(kkey); 1501f2bbc96eSHarald Freudenberger return -EINVAL; 1502f2bbc96eSHarald Freudenberger } 1503f2bbc96eSHarald Freudenberger if (copy_to_user(kgs.key, kkey, klen)) { 1504f2bbc96eSHarald Freudenberger kfree(kkey); 1505f2bbc96eSHarald Freudenberger return -EFAULT; 1506f2bbc96eSHarald Freudenberger } 1507f2bbc96eSHarald Freudenberger } 1508f2bbc96eSHarald Freudenberger kgs.keylen = klen; 1509f2bbc96eSHarald Freudenberger if (copy_to_user(ugs, &kgs, sizeof(kgs))) 1510f2bbc96eSHarald Freudenberger rc = -EFAULT; 1511f2bbc96eSHarald Freudenberger kfree(kkey); 1512f2bbc96eSHarald Freudenberger break; 1513f2bbc96eSHarald Freudenberger } 1514f2bbc96eSHarald Freudenberger case PKEY_CLR2SECK2: { 1515f2bbc96eSHarald Freudenberger struct pkey_clr2seck2 __user *ucs = (void __user *)arg; 151646a29b03SHarald Freudenberger size_t klen = KEYBLOBBUFSIZE; 1517f2bbc96eSHarald Freudenberger struct pkey_clr2seck2 kcs; 1518f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns; 1519f2bbc96eSHarald Freudenberger u8 *kkey; 1520f2bbc96eSHarald Freudenberger 1521f2bbc96eSHarald Freudenberger if (copy_from_user(&kcs, ucs, sizeof(kcs))) 1522f2bbc96eSHarald Freudenberger return -EFAULT; 1523f2bbc96eSHarald Freudenberger apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); 1524f2bbc96eSHarald Freudenberger if (IS_ERR(apqns)) 1525f2bbc96eSHarald Freudenberger return PTR_ERR(apqns); 1526da2863f1SHolger Dengler kkey = kzalloc(klen, GFP_KERNEL); 1527f2bbc96eSHarald Freudenberger if (!kkey) { 1528f2bbc96eSHarald Freudenberger kfree(apqns); 1529f2bbc96eSHarald Freudenberger return -ENOMEM; 1530f2bbc96eSHarald Freudenberger } 1531f2bbc96eSHarald Freudenberger rc = pkey_clr2seckey2(apqns, kcs.apqn_entries, 1532f2bbc96eSHarald Freudenberger kcs.type, kcs.size, kcs.keygenflags, 1533f2bbc96eSHarald Freudenberger kcs.clrkey.clrkey, kkey, &klen); 1534f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_clr2seckey2()=%d\n", __func__, rc); 1535f2bbc96eSHarald Freudenberger kfree(apqns); 1536f2bbc96eSHarald Freudenberger if (rc) { 1537f2bbc96eSHarald Freudenberger kfree(kkey); 1538f2bbc96eSHarald Freudenberger break; 1539f2bbc96eSHarald Freudenberger } 1540f2bbc96eSHarald Freudenberger if (kcs.key) { 1541f2bbc96eSHarald Freudenberger if (kcs.keylen < klen) { 1542f2bbc96eSHarald Freudenberger kfree(kkey); 1543f2bbc96eSHarald Freudenberger return -EINVAL; 1544f2bbc96eSHarald Freudenberger } 1545f2bbc96eSHarald Freudenberger if (copy_to_user(kcs.key, kkey, klen)) { 1546f2bbc96eSHarald Freudenberger kfree(kkey); 1547f2bbc96eSHarald Freudenberger return -EFAULT; 1548f2bbc96eSHarald Freudenberger } 1549f2bbc96eSHarald Freudenberger } 1550f2bbc96eSHarald Freudenberger kcs.keylen = klen; 1551f2bbc96eSHarald Freudenberger if (copy_to_user(ucs, &kcs, sizeof(kcs))) 1552f2bbc96eSHarald Freudenberger rc = -EFAULT; 1553f2bbc96eSHarald Freudenberger memzero_explicit(&kcs, sizeof(kcs)); 1554f2bbc96eSHarald Freudenberger kfree(kkey); 1555f2bbc96eSHarald Freudenberger break; 1556f2bbc96eSHarald Freudenberger } 1557f2bbc96eSHarald Freudenberger case PKEY_VERIFYKEY2: { 1558f2bbc96eSHarald Freudenberger struct pkey_verifykey2 __user *uvk = (void __user *)arg; 1559f2bbc96eSHarald Freudenberger struct pkey_verifykey2 kvk; 1560f2bbc96eSHarald Freudenberger u8 *kkey; 1561f2bbc96eSHarald Freudenberger 1562f2bbc96eSHarald Freudenberger if (copy_from_user(&kvk, uvk, sizeof(kvk))) 1563f2bbc96eSHarald Freudenberger return -EFAULT; 1564f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(kvk.key, kvk.keylen); 1565f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) 1566f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1567f2bbc96eSHarald Freudenberger rc = pkey_verifykey2(kkey, kvk.keylen, 1568f2bbc96eSHarald Freudenberger &kvk.cardnr, &kvk.domain, 1569f2bbc96eSHarald Freudenberger &kvk.type, &kvk.size, &kvk.flags); 1570f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_verifykey2()=%d\n", __func__, rc); 1571f2bbc96eSHarald Freudenberger kfree(kkey); 1572f2bbc96eSHarald Freudenberger if (rc) 1573f2bbc96eSHarald Freudenberger break; 1574f2bbc96eSHarald Freudenberger if (copy_to_user(uvk, &kvk, sizeof(kvk))) 1575f2bbc96eSHarald Freudenberger return -EFAULT; 1576f2bbc96eSHarald Freudenberger break; 1577f2bbc96eSHarald Freudenberger } 1578f2bbc96eSHarald Freudenberger case PKEY_KBLOB2PROTK2: { 1579f2bbc96eSHarald Freudenberger struct pkey_kblob2pkey2 __user *utp = (void __user *)arg; 1580f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns = NULL; 158146a29b03SHarald Freudenberger struct pkey_kblob2pkey2 ktp; 1582f2bbc96eSHarald Freudenberger u8 *kkey; 1583f2bbc96eSHarald Freudenberger 1584f2bbc96eSHarald Freudenberger if (copy_from_user(&ktp, utp, sizeof(ktp))) 1585f2bbc96eSHarald Freudenberger return -EFAULT; 1586f2bbc96eSHarald Freudenberger apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); 1587f2bbc96eSHarald Freudenberger if (IS_ERR(apqns)) 1588f2bbc96eSHarald Freudenberger return PTR_ERR(apqns); 1589f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(ktp.key, ktp.keylen); 1590f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) { 1591f2bbc96eSHarald Freudenberger kfree(apqns); 1592f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1593f2bbc96eSHarald Freudenberger } 1594f370f45cSHarald Freudenberger ktp.protkey.len = sizeof(ktp.protkey.protkey); 1595f2bbc96eSHarald Freudenberger rc = pkey_keyblob2pkey2(apqns, ktp.apqn_entries, 1596f370f45cSHarald Freudenberger kkey, ktp.keylen, 1597f370f45cSHarald Freudenberger ktp.protkey.protkey, &ktp.protkey.len, 1598f370f45cSHarald Freudenberger &ktp.protkey.type); 1599f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_keyblob2pkey2()=%d\n", __func__, rc); 1600f2bbc96eSHarald Freudenberger kfree(apqns); 1601844cf829SHolger Dengler memzero_explicit(kkey, ktp.keylen); 1602f2bbc96eSHarald Freudenberger kfree(kkey); 1603f2bbc96eSHarald Freudenberger if (rc) 1604f2bbc96eSHarald Freudenberger break; 1605f2bbc96eSHarald Freudenberger if (copy_to_user(utp, &ktp, sizeof(ktp))) 1606f2bbc96eSHarald Freudenberger return -EFAULT; 1607f2bbc96eSHarald Freudenberger break; 1608f2bbc96eSHarald Freudenberger } 1609f2bbc96eSHarald Freudenberger case PKEY_APQNS4K: { 1610f2bbc96eSHarald Freudenberger struct pkey_apqns4key __user *uak = (void __user *)arg; 1611f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns = NULL; 161246a29b03SHarald Freudenberger struct pkey_apqns4key kak; 1613f2bbc96eSHarald Freudenberger size_t nr_apqns, len; 1614f2bbc96eSHarald Freudenberger u8 *kkey; 1615f2bbc96eSHarald Freudenberger 1616f2bbc96eSHarald Freudenberger if (copy_from_user(&kak, uak, sizeof(kak))) 1617f2bbc96eSHarald Freudenberger return -EFAULT; 1618f2bbc96eSHarald Freudenberger nr_apqns = kak.apqn_entries; 1619f2bbc96eSHarald Freudenberger if (nr_apqns) { 1620f2bbc96eSHarald Freudenberger apqns = kmalloc_array(nr_apqns, 1621f2bbc96eSHarald Freudenberger sizeof(struct pkey_apqn), 1622f2bbc96eSHarald Freudenberger GFP_KERNEL); 1623f2bbc96eSHarald Freudenberger if (!apqns) 1624f2bbc96eSHarald Freudenberger return -ENOMEM; 1625f2bbc96eSHarald Freudenberger } 1626f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(kak.key, kak.keylen); 1627f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) { 1628f2bbc96eSHarald Freudenberger kfree(apqns); 1629f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1630f2bbc96eSHarald Freudenberger } 1631f2bbc96eSHarald Freudenberger rc = pkey_apqns4key(kkey, kak.keylen, kak.flags, 1632f2bbc96eSHarald Freudenberger apqns, &nr_apqns); 1633f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_apqns4key()=%d\n", __func__, rc); 1634f2bbc96eSHarald Freudenberger kfree(kkey); 1635f2bbc96eSHarald Freudenberger if (rc && rc != -ENOSPC) { 1636f2bbc96eSHarald Freudenberger kfree(apqns); 1637f2bbc96eSHarald Freudenberger break; 1638f2bbc96eSHarald Freudenberger } 1639f2bbc96eSHarald Freudenberger if (!rc && kak.apqns) { 1640f2bbc96eSHarald Freudenberger if (nr_apqns > kak.apqn_entries) { 1641f2bbc96eSHarald Freudenberger kfree(apqns); 1642f2bbc96eSHarald Freudenberger return -EINVAL; 1643f2bbc96eSHarald Freudenberger } 1644f2bbc96eSHarald Freudenberger len = nr_apqns * sizeof(struct pkey_apqn); 1645f2bbc96eSHarald Freudenberger if (len) { 1646f2bbc96eSHarald Freudenberger if (copy_to_user(kak.apqns, apqns, len)) { 1647f2bbc96eSHarald Freudenberger kfree(apqns); 1648f2bbc96eSHarald Freudenberger return -EFAULT; 1649f2bbc96eSHarald Freudenberger } 1650f2bbc96eSHarald Freudenberger } 1651f2bbc96eSHarald Freudenberger } 1652f2bbc96eSHarald Freudenberger kak.apqn_entries = nr_apqns; 1653f2bbc96eSHarald Freudenberger if (copy_to_user(uak, &kak, sizeof(kak))) 1654f2bbc96eSHarald Freudenberger rc = -EFAULT; 1655f2bbc96eSHarald Freudenberger kfree(apqns); 1656f2bbc96eSHarald Freudenberger break; 1657f2bbc96eSHarald Freudenberger } 1658f2bbc96eSHarald Freudenberger case PKEY_APQNS4KT: { 1659f2bbc96eSHarald Freudenberger struct pkey_apqns4keytype __user *uat = (void __user *)arg; 1660f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns = NULL; 166146a29b03SHarald Freudenberger struct pkey_apqns4keytype kat; 1662f2bbc96eSHarald Freudenberger size_t nr_apqns, len; 1663f2bbc96eSHarald Freudenberger 1664f2bbc96eSHarald Freudenberger if (copy_from_user(&kat, uat, sizeof(kat))) 1665f2bbc96eSHarald Freudenberger return -EFAULT; 1666f2bbc96eSHarald Freudenberger nr_apqns = kat.apqn_entries; 1667f2bbc96eSHarald Freudenberger if (nr_apqns) { 1668f2bbc96eSHarald Freudenberger apqns = kmalloc_array(nr_apqns, 1669f2bbc96eSHarald Freudenberger sizeof(struct pkey_apqn), 1670f2bbc96eSHarald Freudenberger GFP_KERNEL); 1671f2bbc96eSHarald Freudenberger if (!apqns) 1672f2bbc96eSHarald Freudenberger return -ENOMEM; 1673f2bbc96eSHarald Freudenberger } 1674f2bbc96eSHarald Freudenberger rc = pkey_apqns4keytype(kat.type, kat.cur_mkvp, kat.alt_mkvp, 1675f2bbc96eSHarald Freudenberger kat.flags, apqns, &nr_apqns); 1676f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_apqns4keytype()=%d\n", __func__, rc); 1677f2bbc96eSHarald Freudenberger if (rc && rc != -ENOSPC) { 1678f2bbc96eSHarald Freudenberger kfree(apqns); 1679f2bbc96eSHarald Freudenberger break; 1680f2bbc96eSHarald Freudenberger } 1681f2bbc96eSHarald Freudenberger if (!rc && kat.apqns) { 1682f2bbc96eSHarald Freudenberger if (nr_apqns > kat.apqn_entries) { 1683f2bbc96eSHarald Freudenberger kfree(apqns); 1684f2bbc96eSHarald Freudenberger return -EINVAL; 1685f2bbc96eSHarald Freudenberger } 1686f2bbc96eSHarald Freudenberger len = nr_apqns * sizeof(struct pkey_apqn); 1687f2bbc96eSHarald Freudenberger if (len) { 1688f2bbc96eSHarald Freudenberger if (copy_to_user(kat.apqns, apqns, len)) { 1689f2bbc96eSHarald Freudenberger kfree(apqns); 1690f2bbc96eSHarald Freudenberger return -EFAULT; 1691f2bbc96eSHarald Freudenberger } 1692f2bbc96eSHarald Freudenberger } 1693f2bbc96eSHarald Freudenberger } 1694f2bbc96eSHarald Freudenberger kat.apqn_entries = nr_apqns; 1695f2bbc96eSHarald Freudenberger if (copy_to_user(uat, &kat, sizeof(kat))) 1696f2bbc96eSHarald Freudenberger rc = -EFAULT; 1697f2bbc96eSHarald Freudenberger kfree(apqns); 1698f2bbc96eSHarald Freudenberger break; 1699f2bbc96eSHarald Freudenberger } 1700fa6999e3SHarald Freudenberger case PKEY_KBLOB2PROTK3: { 1701fa6999e3SHarald Freudenberger struct pkey_kblob2pkey3 __user *utp = (void __user *)arg; 1702fa6999e3SHarald Freudenberger u32 protkeylen = PROTKEYBLOBBUFSIZE; 170346a29b03SHarald Freudenberger struct pkey_apqn *apqns = NULL; 170446a29b03SHarald Freudenberger struct pkey_kblob2pkey3 ktp; 1705fa6999e3SHarald Freudenberger u8 *kkey, *protkey; 1706fa6999e3SHarald Freudenberger 1707fa6999e3SHarald Freudenberger if (copy_from_user(&ktp, utp, sizeof(ktp))) 1708fa6999e3SHarald Freudenberger return -EFAULT; 1709fa6999e3SHarald Freudenberger apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); 1710fa6999e3SHarald Freudenberger if (IS_ERR(apqns)) 1711fa6999e3SHarald Freudenberger return PTR_ERR(apqns); 1712fa6999e3SHarald Freudenberger kkey = _copy_key_from_user(ktp.key, ktp.keylen); 1713fa6999e3SHarald Freudenberger if (IS_ERR(kkey)) { 1714fa6999e3SHarald Freudenberger kfree(apqns); 1715fa6999e3SHarald Freudenberger return PTR_ERR(kkey); 1716fa6999e3SHarald Freudenberger } 1717fa6999e3SHarald Freudenberger protkey = kmalloc(protkeylen, GFP_KERNEL); 1718fa6999e3SHarald Freudenberger if (!protkey) { 1719fa6999e3SHarald Freudenberger kfree(apqns); 1720fa6999e3SHarald Freudenberger kfree(kkey); 1721fa6999e3SHarald Freudenberger return -ENOMEM; 1722fa6999e3SHarald Freudenberger } 1723f370f45cSHarald Freudenberger rc = pkey_keyblob2pkey3(apqns, ktp.apqn_entries, 1724f370f45cSHarald Freudenberger kkey, ktp.keylen, 1725f370f45cSHarald Freudenberger protkey, &protkeylen, &ktp.pkeytype); 1726fa6999e3SHarald Freudenberger DEBUG_DBG("%s pkey_keyblob2pkey3()=%d\n", __func__, rc); 1727fa6999e3SHarald Freudenberger kfree(apqns); 1728844cf829SHolger Dengler memzero_explicit(kkey, ktp.keylen); 1729fa6999e3SHarald Freudenberger kfree(kkey); 1730fa6999e3SHarald Freudenberger if (rc) { 1731fa6999e3SHarald Freudenberger kfree(protkey); 1732fa6999e3SHarald Freudenberger break; 1733fa6999e3SHarald Freudenberger } 1734fa6999e3SHarald Freudenberger if (ktp.pkey && ktp.pkeylen) { 1735fa6999e3SHarald Freudenberger if (protkeylen > ktp.pkeylen) { 1736fa6999e3SHarald Freudenberger kfree(protkey); 1737fa6999e3SHarald Freudenberger return -EINVAL; 1738fa6999e3SHarald Freudenberger } 1739fa6999e3SHarald Freudenberger if (copy_to_user(ktp.pkey, protkey, protkeylen)) { 1740fa6999e3SHarald Freudenberger kfree(protkey); 1741fa6999e3SHarald Freudenberger return -EFAULT; 1742fa6999e3SHarald Freudenberger } 1743fa6999e3SHarald Freudenberger } 1744fa6999e3SHarald Freudenberger kfree(protkey); 1745fa6999e3SHarald Freudenberger ktp.pkeylen = protkeylen; 1746fa6999e3SHarald Freudenberger if (copy_to_user(utp, &ktp, sizeof(ktp))) 1747fa6999e3SHarald Freudenberger return -EFAULT; 1748fa6999e3SHarald Freudenberger break; 1749fa6999e3SHarald Freudenberger } 1750e80d4af0SHarald Freudenberger default: 1751e80d4af0SHarald Freudenberger /* unknown/unsupported ioctl cmd */ 1752e80d4af0SHarald Freudenberger return -ENOTTY; 1753e80d4af0SHarald Freudenberger } 1754e80d4af0SHarald Freudenberger 1755e80d4af0SHarald Freudenberger return rc; 1756e80d4af0SHarald Freudenberger } 1757e80d4af0SHarald Freudenberger 1758e80d4af0SHarald Freudenberger /* 1759e80d4af0SHarald Freudenberger * Sysfs and file io operations 1760e80d4af0SHarald Freudenberger */ 1761d632c047SIngo Franzki 1762d632c047SIngo Franzki /* 1763d632c047SIngo Franzki * Sysfs attribute read function for all protected key binary attributes. 1764d632c047SIngo Franzki * The implementation can not deal with partial reads, because a new random 1765d632c047SIngo Franzki * protected key blob is generated with each read. In case of partial reads 1766d632c047SIngo Franzki * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 1767d632c047SIngo Franzki */ 1768d632c047SIngo Franzki static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf, 1769d632c047SIngo Franzki loff_t off, size_t count) 1770d632c047SIngo Franzki { 1771d632c047SIngo Franzki struct protaeskeytoken protkeytoken; 1772d632c047SIngo Franzki struct pkey_protkey protkey; 1773d632c047SIngo Franzki int rc; 1774d632c047SIngo Franzki 1775d632c047SIngo Franzki if (off != 0 || count < sizeof(protkeytoken)) 1776d632c047SIngo Franzki return -EINVAL; 1777d632c047SIngo Franzki if (is_xts) 1778d632c047SIngo Franzki if (count < 2 * sizeof(protkeytoken)) 1779d632c047SIngo Franzki return -EINVAL; 1780d632c047SIngo Franzki 1781d632c047SIngo Franzki memset(&protkeytoken, 0, sizeof(protkeytoken)); 1782d632c047SIngo Franzki protkeytoken.type = TOKTYPE_NON_CCA; 1783d632c047SIngo Franzki protkeytoken.version = TOKVER_PROTECTED_KEY; 1784d632c047SIngo Franzki protkeytoken.keytype = keytype; 1785d632c047SIngo Franzki 1786f370f45cSHarald Freudenberger protkey.len = sizeof(protkey.protkey); 1787f370f45cSHarald Freudenberger rc = pkey_genprotkey(protkeytoken.keytype, 1788f370f45cSHarald Freudenberger protkey.protkey, &protkey.len, &protkey.type); 1789d632c047SIngo Franzki if (rc) 1790d632c047SIngo Franzki return rc; 1791d632c047SIngo Franzki 1792d632c047SIngo Franzki protkeytoken.len = protkey.len; 1793d632c047SIngo Franzki memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len); 1794d632c047SIngo Franzki 1795d632c047SIngo Franzki memcpy(buf, &protkeytoken, sizeof(protkeytoken)); 1796d632c047SIngo Franzki 1797d632c047SIngo Franzki if (is_xts) { 1798f370f45cSHarald Freudenberger /* xts needs a second protected key, reuse protkey struct */ 1799f370f45cSHarald Freudenberger protkey.len = sizeof(protkey.protkey); 1800f370f45cSHarald Freudenberger rc = pkey_genprotkey(protkeytoken.keytype, 1801f370f45cSHarald Freudenberger protkey.protkey, &protkey.len, &protkey.type); 1802d632c047SIngo Franzki if (rc) 1803d632c047SIngo Franzki return rc; 1804d632c047SIngo Franzki 1805d632c047SIngo Franzki protkeytoken.len = protkey.len; 1806d632c047SIngo Franzki memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len); 1807d632c047SIngo Franzki 1808d632c047SIngo Franzki memcpy(buf + sizeof(protkeytoken), &protkeytoken, 1809d632c047SIngo Franzki sizeof(protkeytoken)); 1810d632c047SIngo Franzki 1811d632c047SIngo Franzki return 2 * sizeof(protkeytoken); 1812d632c047SIngo Franzki } 1813d632c047SIngo Franzki 1814d632c047SIngo Franzki return sizeof(protkeytoken); 1815d632c047SIngo Franzki } 1816d632c047SIngo Franzki 1817d632c047SIngo Franzki static ssize_t protkey_aes_128_read(struct file *filp, 1818d632c047SIngo Franzki struct kobject *kobj, 1819d632c047SIngo Franzki struct bin_attribute *attr, 1820d632c047SIngo Franzki char *buf, loff_t off, 1821d632c047SIngo Franzki size_t count) 1822d632c047SIngo Franzki { 1823d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf, 1824d632c047SIngo Franzki off, count); 1825d632c047SIngo Franzki } 1826d632c047SIngo Franzki 1827d632c047SIngo Franzki static ssize_t protkey_aes_192_read(struct file *filp, 1828d632c047SIngo Franzki struct kobject *kobj, 1829d632c047SIngo Franzki struct bin_attribute *attr, 1830d632c047SIngo Franzki char *buf, loff_t off, 1831d632c047SIngo Franzki size_t count) 1832d632c047SIngo Franzki { 1833d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf, 1834d632c047SIngo Franzki off, count); 1835d632c047SIngo Franzki } 1836d632c047SIngo Franzki 1837d632c047SIngo Franzki static ssize_t protkey_aes_256_read(struct file *filp, 1838d632c047SIngo Franzki struct kobject *kobj, 1839d632c047SIngo Franzki struct bin_attribute *attr, 1840d632c047SIngo Franzki char *buf, loff_t off, 1841d632c047SIngo Franzki size_t count) 1842d632c047SIngo Franzki { 1843d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf, 1844d632c047SIngo Franzki off, count); 1845d632c047SIngo Franzki } 1846d632c047SIngo Franzki 1847d632c047SIngo Franzki static ssize_t protkey_aes_128_xts_read(struct file *filp, 1848d632c047SIngo Franzki struct kobject *kobj, 1849d632c047SIngo Franzki struct bin_attribute *attr, 1850d632c047SIngo Franzki char *buf, loff_t off, 1851d632c047SIngo Franzki size_t count) 1852d632c047SIngo Franzki { 1853d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf, 1854d632c047SIngo Franzki off, count); 1855d632c047SIngo Franzki } 1856d632c047SIngo Franzki 1857d632c047SIngo Franzki static ssize_t protkey_aes_256_xts_read(struct file *filp, 1858d632c047SIngo Franzki struct kobject *kobj, 1859d632c047SIngo Franzki struct bin_attribute *attr, 1860d632c047SIngo Franzki char *buf, loff_t off, 1861d632c047SIngo Franzki size_t count) 1862d632c047SIngo Franzki { 1863d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf, 1864d632c047SIngo Franzki off, count); 1865d632c047SIngo Franzki } 1866d632c047SIngo Franzki 1867d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken)); 1868d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken)); 1869d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken)); 1870d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken)); 1871d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken)); 1872d632c047SIngo Franzki 1873d632c047SIngo Franzki static struct bin_attribute *protkey_attrs[] = { 1874d632c047SIngo Franzki &bin_attr_protkey_aes_128, 1875d632c047SIngo Franzki &bin_attr_protkey_aes_192, 1876d632c047SIngo Franzki &bin_attr_protkey_aes_256, 1877d632c047SIngo Franzki &bin_attr_protkey_aes_128_xts, 1878d632c047SIngo Franzki &bin_attr_protkey_aes_256_xts, 1879d632c047SIngo Franzki NULL 1880d632c047SIngo Franzki }; 1881d632c047SIngo Franzki 1882d632c047SIngo Franzki static struct attribute_group protkey_attr_group = { 1883d632c047SIngo Franzki .name = "protkey", 1884d632c047SIngo Franzki .bin_attrs = protkey_attrs, 1885d632c047SIngo Franzki }; 1886d632c047SIngo Franzki 1887af504452SIngo Franzki /* 1888af504452SIngo Franzki * Sysfs attribute read function for all secure key ccadata binary attributes. 1889af504452SIngo Franzki * The implementation can not deal with partial reads, because a new random 1890af504452SIngo Franzki * protected key blob is generated with each read. In case of partial reads 1891af504452SIngo Franzki * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 1892af504452SIngo Franzki */ 1893af504452SIngo Franzki static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf, 1894af504452SIngo Franzki loff_t off, size_t count) 1895af504452SIngo Franzki { 1896efc598e6SHarald Freudenberger struct pkey_seckey *seckey = (struct pkey_seckey *)buf; 189746a29b03SHarald Freudenberger int rc; 1898af504452SIngo Franzki 1899af504452SIngo Franzki if (off != 0 || count < sizeof(struct secaeskeytoken)) 1900af504452SIngo Franzki return -EINVAL; 1901af504452SIngo Franzki if (is_xts) 1902af504452SIngo Franzki if (count < 2 * sizeof(struct secaeskeytoken)) 1903af504452SIngo Franzki return -EINVAL; 1904af504452SIngo Franzki 1905efc598e6SHarald Freudenberger rc = cca_genseckey(-1, -1, keytype, seckey->seckey); 1906af504452SIngo Franzki if (rc) 1907af504452SIngo Franzki return rc; 1908af504452SIngo Franzki 1909af504452SIngo Franzki if (is_xts) { 1910efc598e6SHarald Freudenberger seckey++; 1911efc598e6SHarald Freudenberger rc = cca_genseckey(-1, -1, keytype, seckey->seckey); 1912af504452SIngo Franzki if (rc) 1913af504452SIngo Franzki return rc; 1914af504452SIngo Franzki 1915af504452SIngo Franzki return 2 * sizeof(struct secaeskeytoken); 1916af504452SIngo Franzki } 1917af504452SIngo Franzki 1918af504452SIngo Franzki return sizeof(struct secaeskeytoken); 1919af504452SIngo Franzki } 1920af504452SIngo Franzki 1921af504452SIngo Franzki static ssize_t ccadata_aes_128_read(struct file *filp, 1922af504452SIngo Franzki struct kobject *kobj, 1923af504452SIngo Franzki struct bin_attribute *attr, 1924af504452SIngo Franzki char *buf, loff_t off, 1925af504452SIngo Franzki size_t count) 1926af504452SIngo Franzki { 1927af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf, 1928af504452SIngo Franzki off, count); 1929af504452SIngo Franzki } 1930af504452SIngo Franzki 1931af504452SIngo Franzki static ssize_t ccadata_aes_192_read(struct file *filp, 1932af504452SIngo Franzki struct kobject *kobj, 1933af504452SIngo Franzki struct bin_attribute *attr, 1934af504452SIngo Franzki char *buf, loff_t off, 1935af504452SIngo Franzki size_t count) 1936af504452SIngo Franzki { 1937af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf, 1938af504452SIngo Franzki off, count); 1939af504452SIngo Franzki } 1940af504452SIngo Franzki 1941af504452SIngo Franzki static ssize_t ccadata_aes_256_read(struct file *filp, 1942af504452SIngo Franzki struct kobject *kobj, 1943af504452SIngo Franzki struct bin_attribute *attr, 1944af504452SIngo Franzki char *buf, loff_t off, 1945af504452SIngo Franzki size_t count) 1946af504452SIngo Franzki { 1947af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf, 1948af504452SIngo Franzki off, count); 1949af504452SIngo Franzki } 1950af504452SIngo Franzki 1951af504452SIngo Franzki static ssize_t ccadata_aes_128_xts_read(struct file *filp, 1952af504452SIngo Franzki struct kobject *kobj, 1953af504452SIngo Franzki struct bin_attribute *attr, 1954af504452SIngo Franzki char *buf, loff_t off, 1955af504452SIngo Franzki size_t count) 1956af504452SIngo Franzki { 1957af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf, 1958af504452SIngo Franzki off, count); 1959af504452SIngo Franzki } 1960af504452SIngo Franzki 1961af504452SIngo Franzki static ssize_t ccadata_aes_256_xts_read(struct file *filp, 1962af504452SIngo Franzki struct kobject *kobj, 1963af504452SIngo Franzki struct bin_attribute *attr, 1964af504452SIngo Franzki char *buf, loff_t off, 1965af504452SIngo Franzki size_t count) 1966af504452SIngo Franzki { 1967af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf, 1968af504452SIngo Franzki off, count); 1969af504452SIngo Franzki } 1970af504452SIngo Franzki 1971af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_128, sizeof(struct secaeskeytoken)); 1972af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_192, sizeof(struct secaeskeytoken)); 1973af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_256, sizeof(struct secaeskeytoken)); 1974af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_128_xts, 2 * sizeof(struct secaeskeytoken)); 1975af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_256_xts, 2 * sizeof(struct secaeskeytoken)); 1976af504452SIngo Franzki 1977af504452SIngo Franzki static struct bin_attribute *ccadata_attrs[] = { 1978af504452SIngo Franzki &bin_attr_ccadata_aes_128, 1979af504452SIngo Franzki &bin_attr_ccadata_aes_192, 1980af504452SIngo Franzki &bin_attr_ccadata_aes_256, 1981af504452SIngo Franzki &bin_attr_ccadata_aes_128_xts, 1982af504452SIngo Franzki &bin_attr_ccadata_aes_256_xts, 1983af504452SIngo Franzki NULL 1984af504452SIngo Franzki }; 1985af504452SIngo Franzki 1986af504452SIngo Franzki static struct attribute_group ccadata_attr_group = { 1987af504452SIngo Franzki .name = "ccadata", 1988af504452SIngo Franzki .bin_attrs = ccadata_attrs, 1989af504452SIngo Franzki }; 1990af504452SIngo Franzki 1991f71fee27SIngo Franzki #define CCACIPHERTOKENSIZE (sizeof(struct cipherkeytoken) + 80) 1992f71fee27SIngo Franzki 1993f71fee27SIngo Franzki /* 1994f71fee27SIngo Franzki * Sysfs attribute read function for all secure key ccacipher binary attributes. 1995f71fee27SIngo Franzki * The implementation can not deal with partial reads, because a new random 1996f71fee27SIngo Franzki * secure key blob is generated with each read. In case of partial reads 1997f71fee27SIngo Franzki * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 1998f71fee27SIngo Franzki */ 1999f71fee27SIngo Franzki static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits, 2000f71fee27SIngo Franzki bool is_xts, char *buf, loff_t off, 2001f71fee27SIngo Franzki size_t count) 2002f71fee27SIngo Franzki { 200355d0a513SHarald Freudenberger size_t keysize = CCACIPHERTOKENSIZE; 200446a29b03SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 200546a29b03SHarald Freudenberger int i, rc, card, dom; 2006f71fee27SIngo Franzki 2007f71fee27SIngo Franzki if (off != 0 || count < CCACIPHERTOKENSIZE) 2008f71fee27SIngo Franzki return -EINVAL; 2009f71fee27SIngo Franzki if (is_xts) 2010f71fee27SIngo Franzki if (count < 2 * CCACIPHERTOKENSIZE) 2011f71fee27SIngo Franzki return -EINVAL; 2012f71fee27SIngo Franzki 201355d0a513SHarald Freudenberger /* build a list of apqns able to generate an cipher key */ 201455d0a513SHarald Freudenberger rc = cca_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 201532ca04bbSHarald Freudenberger ZCRYPT_CEX6, 0, 0, 0, 0); 2016f71fee27SIngo Franzki if (rc) 2017f71fee27SIngo Franzki return rc; 201855d0a513SHarald Freudenberger 201955d0a513SHarald Freudenberger memset(buf, 0, is_xts ? 2 * keysize : keysize); 202055d0a513SHarald Freudenberger 202155d0a513SHarald Freudenberger /* simple try all apqns from the list */ 202255d0a513SHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 202355d0a513SHarald Freudenberger card = apqns[i] >> 16; 202455d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 202555d0a513SHarald Freudenberger rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize); 202655d0a513SHarald Freudenberger if (rc == 0) 202755d0a513SHarald Freudenberger break; 202855d0a513SHarald Freudenberger } 202955d0a513SHarald Freudenberger if (rc) 203055d0a513SHarald Freudenberger return rc; 2031f71fee27SIngo Franzki 2032f71fee27SIngo Franzki if (is_xts) { 2033f71fee27SIngo Franzki keysize = CCACIPHERTOKENSIZE; 203455d0a513SHarald Freudenberger buf += CCACIPHERTOKENSIZE; 203555d0a513SHarald Freudenberger rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize); 203655d0a513SHarald Freudenberger if (rc == 0) 2037f71fee27SIngo Franzki return 2 * CCACIPHERTOKENSIZE; 2038f71fee27SIngo Franzki } 2039f71fee27SIngo Franzki 2040f71fee27SIngo Franzki return CCACIPHERTOKENSIZE; 2041f71fee27SIngo Franzki } 2042f71fee27SIngo Franzki 2043f71fee27SIngo Franzki static ssize_t ccacipher_aes_128_read(struct file *filp, 2044f71fee27SIngo Franzki struct kobject *kobj, 2045f71fee27SIngo Franzki struct bin_attribute *attr, 2046f71fee27SIngo Franzki char *buf, loff_t off, 2047f71fee27SIngo Franzki size_t count) 2048f71fee27SIngo Franzki { 2049f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, false, buf, 2050f71fee27SIngo Franzki off, count); 2051f71fee27SIngo Franzki } 2052f71fee27SIngo Franzki 2053f71fee27SIngo Franzki static ssize_t ccacipher_aes_192_read(struct file *filp, 2054f71fee27SIngo Franzki struct kobject *kobj, 2055f71fee27SIngo Franzki struct bin_attribute *attr, 2056f71fee27SIngo Franzki char *buf, loff_t off, 2057f71fee27SIngo Franzki size_t count) 2058f71fee27SIngo Franzki { 2059f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_192, false, buf, 2060f71fee27SIngo Franzki off, count); 2061f71fee27SIngo Franzki } 2062f71fee27SIngo Franzki 2063f71fee27SIngo Franzki static ssize_t ccacipher_aes_256_read(struct file *filp, 2064f71fee27SIngo Franzki struct kobject *kobj, 2065f71fee27SIngo Franzki struct bin_attribute *attr, 2066f71fee27SIngo Franzki char *buf, loff_t off, 2067f71fee27SIngo Franzki size_t count) 2068f71fee27SIngo Franzki { 2069f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, false, buf, 2070f71fee27SIngo Franzki off, count); 2071f71fee27SIngo Franzki } 2072f71fee27SIngo Franzki 2073f71fee27SIngo Franzki static ssize_t ccacipher_aes_128_xts_read(struct file *filp, 2074f71fee27SIngo Franzki struct kobject *kobj, 2075f71fee27SIngo Franzki struct bin_attribute *attr, 2076f71fee27SIngo Franzki char *buf, loff_t off, 2077f71fee27SIngo Franzki size_t count) 2078f71fee27SIngo Franzki { 2079f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, true, buf, 2080f71fee27SIngo Franzki off, count); 2081f71fee27SIngo Franzki } 2082f71fee27SIngo Franzki 2083f71fee27SIngo Franzki static ssize_t ccacipher_aes_256_xts_read(struct file *filp, 2084f71fee27SIngo Franzki struct kobject *kobj, 2085f71fee27SIngo Franzki struct bin_attribute *attr, 2086f71fee27SIngo Franzki char *buf, loff_t off, 2087f71fee27SIngo Franzki size_t count) 2088f71fee27SIngo Franzki { 2089f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, true, buf, 2090f71fee27SIngo Franzki off, count); 2091f71fee27SIngo Franzki } 2092f71fee27SIngo Franzki 2093f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_128, CCACIPHERTOKENSIZE); 2094f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_192, CCACIPHERTOKENSIZE); 2095f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_256, CCACIPHERTOKENSIZE); 2096f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_128_xts, 2 * CCACIPHERTOKENSIZE); 2097f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_256_xts, 2 * CCACIPHERTOKENSIZE); 2098f71fee27SIngo Franzki 2099f71fee27SIngo Franzki static struct bin_attribute *ccacipher_attrs[] = { 2100f71fee27SIngo Franzki &bin_attr_ccacipher_aes_128, 2101f71fee27SIngo Franzki &bin_attr_ccacipher_aes_192, 2102f71fee27SIngo Franzki &bin_attr_ccacipher_aes_256, 2103f71fee27SIngo Franzki &bin_attr_ccacipher_aes_128_xts, 2104f71fee27SIngo Franzki &bin_attr_ccacipher_aes_256_xts, 2105f71fee27SIngo Franzki NULL 2106f71fee27SIngo Franzki }; 2107f71fee27SIngo Franzki 2108f71fee27SIngo Franzki static struct attribute_group ccacipher_attr_group = { 2109f71fee27SIngo Franzki .name = "ccacipher", 2110f71fee27SIngo Franzki .bin_attrs = ccacipher_attrs, 2111f71fee27SIngo Franzki }; 2112f71fee27SIngo Franzki 211355d0a513SHarald Freudenberger /* 211455d0a513SHarald Freudenberger * Sysfs attribute read function for all ep11 aes key binary attributes. 211555d0a513SHarald Freudenberger * The implementation can not deal with partial reads, because a new random 211655d0a513SHarald Freudenberger * secure key blob is generated with each read. In case of partial reads 211755d0a513SHarald Freudenberger * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 211855d0a513SHarald Freudenberger * This function and the sysfs attributes using it provide EP11 key blobs 211955d0a513SHarald Freudenberger * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently 212055d0a513SHarald Freudenberger * 320 bytes. 212155d0a513SHarald Freudenberger */ 212255d0a513SHarald Freudenberger static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, 212355d0a513SHarald Freudenberger bool is_xts, char *buf, loff_t off, 212455d0a513SHarald Freudenberger size_t count) 212555d0a513SHarald Freudenberger { 212655d0a513SHarald Freudenberger size_t keysize = MAXEP11AESKEYBLOBSIZE; 212746a29b03SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 212846a29b03SHarald Freudenberger int i, rc, card, dom; 212955d0a513SHarald Freudenberger 213055d0a513SHarald Freudenberger if (off != 0 || count < MAXEP11AESKEYBLOBSIZE) 213155d0a513SHarald Freudenberger return -EINVAL; 213255d0a513SHarald Freudenberger if (is_xts) 213355d0a513SHarald Freudenberger if (count < 2 * MAXEP11AESKEYBLOBSIZE) 213455d0a513SHarald Freudenberger return -EINVAL; 213555d0a513SHarald Freudenberger 213655d0a513SHarald Freudenberger /* build a list of apqns able to generate an cipher key */ 213755d0a513SHarald Freudenberger rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 213855d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, NULL); 213955d0a513SHarald Freudenberger if (rc) 214055d0a513SHarald Freudenberger return rc; 214155d0a513SHarald Freudenberger 214255d0a513SHarald Freudenberger memset(buf, 0, is_xts ? 2 * keysize : keysize); 214355d0a513SHarald Freudenberger 214455d0a513SHarald Freudenberger /* simple try all apqns from the list */ 214555d0a513SHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 214655d0a513SHarald Freudenberger card = apqns[i] >> 16; 214755d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 2148fb249ce7SHolger Dengler rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, 2149fb249ce7SHolger Dengler PKEY_TYPE_EP11); 215055d0a513SHarald Freudenberger if (rc == 0) 215155d0a513SHarald Freudenberger break; 215255d0a513SHarald Freudenberger } 215355d0a513SHarald Freudenberger if (rc) 215455d0a513SHarald Freudenberger return rc; 215555d0a513SHarald Freudenberger 215655d0a513SHarald Freudenberger if (is_xts) { 215755d0a513SHarald Freudenberger keysize = MAXEP11AESKEYBLOBSIZE; 215855d0a513SHarald Freudenberger buf += MAXEP11AESKEYBLOBSIZE; 2159fb249ce7SHolger Dengler rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, 2160fb249ce7SHolger Dengler PKEY_TYPE_EP11); 216155d0a513SHarald Freudenberger if (rc == 0) 216255d0a513SHarald Freudenberger return 2 * MAXEP11AESKEYBLOBSIZE; 216355d0a513SHarald Freudenberger } 216455d0a513SHarald Freudenberger 216555d0a513SHarald Freudenberger return MAXEP11AESKEYBLOBSIZE; 216655d0a513SHarald Freudenberger } 216755d0a513SHarald Freudenberger 216855d0a513SHarald Freudenberger static ssize_t ep11_aes_128_read(struct file *filp, 216955d0a513SHarald Freudenberger struct kobject *kobj, 217055d0a513SHarald Freudenberger struct bin_attribute *attr, 217155d0a513SHarald Freudenberger char *buf, loff_t off, 217255d0a513SHarald Freudenberger size_t count) 217355d0a513SHarald Freudenberger { 217455d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, false, buf, 217555d0a513SHarald Freudenberger off, count); 217655d0a513SHarald Freudenberger } 217755d0a513SHarald Freudenberger 217855d0a513SHarald Freudenberger static ssize_t ep11_aes_192_read(struct file *filp, 217955d0a513SHarald Freudenberger struct kobject *kobj, 218055d0a513SHarald Freudenberger struct bin_attribute *attr, 218155d0a513SHarald Freudenberger char *buf, loff_t off, 218255d0a513SHarald Freudenberger size_t count) 218355d0a513SHarald Freudenberger { 218455d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_192, false, buf, 218555d0a513SHarald Freudenberger off, count); 218655d0a513SHarald Freudenberger } 218755d0a513SHarald Freudenberger 218855d0a513SHarald Freudenberger static ssize_t ep11_aes_256_read(struct file *filp, 218955d0a513SHarald Freudenberger struct kobject *kobj, 219055d0a513SHarald Freudenberger struct bin_attribute *attr, 219155d0a513SHarald Freudenberger char *buf, loff_t off, 219255d0a513SHarald Freudenberger size_t count) 219355d0a513SHarald Freudenberger { 219455d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, false, buf, 219555d0a513SHarald Freudenberger off, count); 219655d0a513SHarald Freudenberger } 219755d0a513SHarald Freudenberger 219855d0a513SHarald Freudenberger static ssize_t ep11_aes_128_xts_read(struct file *filp, 219955d0a513SHarald Freudenberger struct kobject *kobj, 220055d0a513SHarald Freudenberger struct bin_attribute *attr, 220155d0a513SHarald Freudenberger char *buf, loff_t off, 220255d0a513SHarald Freudenberger size_t count) 220355d0a513SHarald Freudenberger { 220455d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, true, buf, 220555d0a513SHarald Freudenberger off, count); 220655d0a513SHarald Freudenberger } 220755d0a513SHarald Freudenberger 220855d0a513SHarald Freudenberger static ssize_t ep11_aes_256_xts_read(struct file *filp, 220955d0a513SHarald Freudenberger struct kobject *kobj, 221055d0a513SHarald Freudenberger struct bin_attribute *attr, 221155d0a513SHarald Freudenberger char *buf, loff_t off, 221255d0a513SHarald Freudenberger size_t count) 221355d0a513SHarald Freudenberger { 221455d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, true, buf, 221555d0a513SHarald Freudenberger off, count); 221655d0a513SHarald Freudenberger } 221755d0a513SHarald Freudenberger 221855d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE); 221955d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE); 222055d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE); 222155d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE); 222255d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE); 222355d0a513SHarald Freudenberger 222455d0a513SHarald Freudenberger static struct bin_attribute *ep11_attrs[] = { 222555d0a513SHarald Freudenberger &bin_attr_ep11_aes_128, 222655d0a513SHarald Freudenberger &bin_attr_ep11_aes_192, 222755d0a513SHarald Freudenberger &bin_attr_ep11_aes_256, 222855d0a513SHarald Freudenberger &bin_attr_ep11_aes_128_xts, 222955d0a513SHarald Freudenberger &bin_attr_ep11_aes_256_xts, 223055d0a513SHarald Freudenberger NULL 223155d0a513SHarald Freudenberger }; 223255d0a513SHarald Freudenberger 223355d0a513SHarald Freudenberger static struct attribute_group ep11_attr_group = { 223455d0a513SHarald Freudenberger .name = "ep11", 223555d0a513SHarald Freudenberger .bin_attrs = ep11_attrs, 223655d0a513SHarald Freudenberger }; 223755d0a513SHarald Freudenberger 2238d632c047SIngo Franzki static const struct attribute_group *pkey_attr_groups[] = { 2239d632c047SIngo Franzki &protkey_attr_group, 2240af504452SIngo Franzki &ccadata_attr_group, 2241f71fee27SIngo Franzki &ccacipher_attr_group, 224255d0a513SHarald Freudenberger &ep11_attr_group, 2243d632c047SIngo Franzki NULL, 2244d632c047SIngo Franzki }; 2245d632c047SIngo Franzki 2246e80d4af0SHarald Freudenberger static const struct file_operations pkey_fops = { 2247e80d4af0SHarald Freudenberger .owner = THIS_MODULE, 2248e80d4af0SHarald Freudenberger .open = nonseekable_open, 2249e80d4af0SHarald Freudenberger .llseek = no_llseek, 2250e80d4af0SHarald Freudenberger .unlocked_ioctl = pkey_unlocked_ioctl, 2251e80d4af0SHarald Freudenberger }; 2252e80d4af0SHarald Freudenberger 2253e80d4af0SHarald Freudenberger static struct miscdevice pkey_dev = { 2254e80d4af0SHarald Freudenberger .name = "pkey", 2255e80d4af0SHarald Freudenberger .minor = MISC_DYNAMIC_MINOR, 2256e80d4af0SHarald Freudenberger .mode = 0666, 2257e80d4af0SHarald Freudenberger .fops = &pkey_fops, 2258d632c047SIngo Franzki .groups = pkey_attr_groups, 2259e80d4af0SHarald Freudenberger }; 2260e80d4af0SHarald Freudenberger 2261e80d4af0SHarald Freudenberger /* 2262e80d4af0SHarald Freudenberger * Module init 2263e80d4af0SHarald Freudenberger */ 2264cb4ef3c2SHeiko Carstens static int __init pkey_init(void) 2265e80d4af0SHarald Freudenberger { 22665b35047eSHarald Freudenberger cpacf_mask_t func_mask; 2267e80d4af0SHarald Freudenberger 2268f822ad2cSHarald Freudenberger /* 2269f822ad2cSHarald Freudenberger * The pckmo instruction should be available - even if we don't 2270f822ad2cSHarald Freudenberger * actually invoke it. This instruction comes with MSA 3 which 2271f822ad2cSHarald Freudenberger * is also the minimum level for the kmc instructions which 2272f822ad2cSHarald Freudenberger * are able to work with protected keys. 2273f822ad2cSHarald Freudenberger */ 22745b35047eSHarald Freudenberger if (!cpacf_query(CPACF_PCKMO, &func_mask)) 227558443b67SDavid Hildenbrand return -ENODEV; 2276e80d4af0SHarald Freudenberger 2277cb26b9ffSIngo Franzki /* check for kmc instructions available */ 22785b35047eSHarald Freudenberger if (!cpacf_query(CPACF_KMC, &func_mask)) 227958443b67SDavid Hildenbrand return -ENODEV; 22805b35047eSHarald Freudenberger if (!cpacf_test_func(&func_mask, CPACF_KMC_PAES_128) || 22815b35047eSHarald Freudenberger !cpacf_test_func(&func_mask, CPACF_KMC_PAES_192) || 22825b35047eSHarald Freudenberger !cpacf_test_func(&func_mask, CPACF_KMC_PAES_256)) 228358443b67SDavid Hildenbrand return -ENODEV; 2284cb26b9ffSIngo Franzki 2285e80d4af0SHarald Freudenberger pkey_debug_init(); 2286e80d4af0SHarald Freudenberger 2287e80d4af0SHarald Freudenberger return misc_register(&pkey_dev); 2288e80d4af0SHarald Freudenberger } 2289e80d4af0SHarald Freudenberger 2290e80d4af0SHarald Freudenberger /* 2291e80d4af0SHarald Freudenberger * Module exit 2292e80d4af0SHarald Freudenberger */ 2293e80d4af0SHarald Freudenberger static void __exit pkey_exit(void) 2294e80d4af0SHarald Freudenberger { 2295e80d4af0SHarald Freudenberger misc_deregister(&pkey_dev); 2296e80d4af0SHarald Freudenberger pkey_debug_exit(); 2297e80d4af0SHarald Freudenberger } 2298e80d4af0SHarald Freudenberger 22990a5f9b38SHeiko Carstens module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_init); 2300e80d4af0SHarald Freudenberger module_exit(pkey_exit); 2301