1812141a9SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2e80d4af0SHarald Freudenberger /* 3e80d4af0SHarald Freudenberger * pkey device driver 4e80d4af0SHarald Freudenberger * 5183cb469SHarald Freudenberger * Copyright IBM Corp. 2017,2019 6e80d4af0SHarald Freudenberger * Author(s): Harald Freudenberger 7e80d4af0SHarald Freudenberger */ 8e80d4af0SHarald Freudenberger 9e80d4af0SHarald Freudenberger #define KMSG_COMPONENT "pkey" 10e80d4af0SHarald Freudenberger #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11e80d4af0SHarald Freudenberger 12e80d4af0SHarald Freudenberger #include <linux/fs.h> 13e80d4af0SHarald Freudenberger #include <linux/init.h> 14e80d4af0SHarald Freudenberger #include <linux/miscdevice.h> 15e80d4af0SHarald Freudenberger #include <linux/module.h> 16e80d4af0SHarald Freudenberger #include <linux/slab.h> 17e80d4af0SHarald Freudenberger #include <linux/kallsyms.h> 18e80d4af0SHarald Freudenberger #include <linux/debugfs.h> 19a45a5c7dSIngo Franzki #include <linux/random.h> 2063c19be0SIngo Franzki #include <linux/cpufeature.h> 21e80d4af0SHarald Freudenberger #include <asm/zcrypt.h> 22e80d4af0SHarald Freudenberger #include <asm/cpacf.h> 23e80d4af0SHarald Freudenberger #include <asm/pkey.h> 24cb26b9ffSIngo Franzki #include <crypto/aes.h> 25e80d4af0SHarald Freudenberger 26e80d4af0SHarald Freudenberger #include "zcrypt_api.h" 27efc598e6SHarald Freudenberger #include "zcrypt_ccamisc.h" 2855d0a513SHarald Freudenberger #include "zcrypt_ep11misc.h" 29e80d4af0SHarald Freudenberger 30e80d4af0SHarald Freudenberger MODULE_LICENSE("GPL"); 31e80d4af0SHarald Freudenberger MODULE_AUTHOR("IBM Corporation"); 32e80d4af0SHarald Freudenberger MODULE_DESCRIPTION("s390 protected key interface"); 33e80d4af0SHarald Freudenberger 34f2bbc96eSHarald Freudenberger #define KEYBLOBBUFSIZE 8192 /* key buffer size used for internal processing */ 35fa6999e3SHarald Freudenberger #define PROTKEYBLOBBUFSIZE 256 /* protected key buffer size used internal */ 36f2bbc96eSHarald Freudenberger #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ 37f2bbc96eSHarald Freudenberger 38e80d4af0SHarald Freudenberger /* 39e80d4af0SHarald Freudenberger * debug feature data and functions 40e80d4af0SHarald Freudenberger */ 41e80d4af0SHarald Freudenberger 42e80d4af0SHarald Freudenberger static debug_info_t *debug_info; 43e80d4af0SHarald Freudenberger 44e80d4af0SHarald Freudenberger #define DEBUG_DBG(...) debug_sprintf_event(debug_info, 6, ##__VA_ARGS__) 45e80d4af0SHarald Freudenberger #define DEBUG_INFO(...) debug_sprintf_event(debug_info, 5, ##__VA_ARGS__) 46e80d4af0SHarald Freudenberger #define DEBUG_WARN(...) debug_sprintf_event(debug_info, 4, ##__VA_ARGS__) 47e80d4af0SHarald Freudenberger #define DEBUG_ERR(...) debug_sprintf_event(debug_info, 3, ##__VA_ARGS__) 48e80d4af0SHarald Freudenberger 49e80d4af0SHarald Freudenberger static void __init pkey_debug_init(void) 50e80d4af0SHarald Freudenberger { 516b1f16baSHarald Freudenberger /* 5 arguments per dbf entry (including the format string ptr) */ 526b1f16baSHarald Freudenberger debug_info = debug_register("pkey", 1, 1, 5 * sizeof(long)); 53e80d4af0SHarald Freudenberger debug_register_view(debug_info, &debug_sprintf_view); 54e80d4af0SHarald Freudenberger debug_set_level(debug_info, 3); 55e80d4af0SHarald Freudenberger } 56e80d4af0SHarald Freudenberger 57e80d4af0SHarald Freudenberger static void __exit pkey_debug_exit(void) 58e80d4af0SHarald Freudenberger { 59e80d4af0SHarald Freudenberger debug_unregister(debug_info); 60e80d4af0SHarald Freudenberger } 61e80d4af0SHarald Freudenberger 620534bde7SIngo Franzki /* inside view of a protected key token (only type 0x00 version 0x01) */ 630534bde7SIngo Franzki struct protaeskeytoken { 640534bde7SIngo Franzki u8 type; /* 0x00 for PAES specific key tokens */ 650534bde7SIngo Franzki u8 res0[3]; 660534bde7SIngo Franzki u8 version; /* should be 0x01 for protected AES key token */ 670534bde7SIngo Franzki u8 res1[3]; 680534bde7SIngo Franzki u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ 690534bde7SIngo Franzki u32 len; /* bytes actually stored in protkey[] */ 700534bde7SIngo Franzki u8 protkey[MAXPROTKEYSIZE]; /* the protected key blob */ 710534bde7SIngo Franzki } __packed; 720534bde7SIngo Franzki 73888edbc4SHarald Freudenberger /* inside view of a clear key token (type 0x00 version 0x02) */ 74888edbc4SHarald Freudenberger struct clearaeskeytoken { 75888edbc4SHarald Freudenberger u8 type; /* 0x00 for PAES specific key tokens */ 76888edbc4SHarald Freudenberger u8 res0[3]; 77888edbc4SHarald Freudenberger u8 version; /* 0x02 for clear AES key token */ 78888edbc4SHarald Freudenberger u8 res1[3]; 79888edbc4SHarald Freudenberger u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ 80888edbc4SHarald Freudenberger u32 len; /* bytes actually stored in clearkey[] */ 81fa226f1dSGustavo A. R. Silva u8 clearkey[]; /* clear key value */ 82888edbc4SHarald Freudenberger } __packed; 83888edbc4SHarald Freudenberger 84e80d4af0SHarald Freudenberger /* 85e80d4af0SHarald Freudenberger * Create a protected key from a clear key value. 86e80d4af0SHarald Freudenberger */ 87183cb469SHarald Freudenberger static int pkey_clr2protkey(u32 keytype, 88e80d4af0SHarald Freudenberger const struct pkey_clrkey *clrkey, 89e80d4af0SHarald Freudenberger struct pkey_protkey *protkey) 90e80d4af0SHarald Freudenberger { 915b35047eSHarald Freudenberger /* mask of available pckmo subfunctions */ 925b35047eSHarald Freudenberger static cpacf_mask_t pckmo_functions; 935b35047eSHarald Freudenberger 94e80d4af0SHarald Freudenberger long fc; 95e80d4af0SHarald Freudenberger int keysize; 96e80d4af0SHarald Freudenberger u8 paramblock[64]; 97e80d4af0SHarald Freudenberger 98e80d4af0SHarald Freudenberger switch (keytype) { 99e80d4af0SHarald Freudenberger case PKEY_KEYTYPE_AES_128: 100e80d4af0SHarald Freudenberger keysize = 16; 101e80d4af0SHarald Freudenberger fc = CPACF_PCKMO_ENC_AES_128_KEY; 102e80d4af0SHarald Freudenberger break; 103e80d4af0SHarald Freudenberger case PKEY_KEYTYPE_AES_192: 104e80d4af0SHarald Freudenberger keysize = 24; 105e80d4af0SHarald Freudenberger fc = CPACF_PCKMO_ENC_AES_192_KEY; 106e80d4af0SHarald Freudenberger break; 107e80d4af0SHarald Freudenberger case PKEY_KEYTYPE_AES_256: 108e80d4af0SHarald Freudenberger keysize = 32; 109e80d4af0SHarald Freudenberger fc = CPACF_PCKMO_ENC_AES_256_KEY; 110e80d4af0SHarald Freudenberger break; 111e80d4af0SHarald Freudenberger default: 112ac2b96f3SHarald Freudenberger DEBUG_ERR("%s unknown/unsupported keytype %d\n", 113ac2b96f3SHarald Freudenberger __func__, keytype); 114e80d4af0SHarald Freudenberger return -EINVAL; 115e80d4af0SHarald Freudenberger } 116e80d4af0SHarald Freudenberger 1175b35047eSHarald Freudenberger /* Did we already check for PCKMO ? */ 1185b35047eSHarald Freudenberger if (!pckmo_functions.bytes[0]) { 1195b35047eSHarald Freudenberger /* no, so check now */ 1205b35047eSHarald Freudenberger if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) 1215b35047eSHarald Freudenberger return -ENODEV; 1225b35047eSHarald Freudenberger } 1235b35047eSHarald Freudenberger /* check for the pckmo subfunction we need now */ 124f822ad2cSHarald Freudenberger if (!cpacf_test_func(&pckmo_functions, fc)) { 125f822ad2cSHarald Freudenberger DEBUG_ERR("%s pckmo functions not available\n", __func__); 12658443b67SDavid Hildenbrand return -ENODEV; 127f822ad2cSHarald Freudenberger } 128f822ad2cSHarald Freudenberger 129e80d4af0SHarald Freudenberger /* prepare param block */ 130e80d4af0SHarald Freudenberger memset(paramblock, 0, sizeof(paramblock)); 131e80d4af0SHarald Freudenberger memcpy(paramblock, clrkey->clrkey, keysize); 132e80d4af0SHarald Freudenberger 133e80d4af0SHarald Freudenberger /* call the pckmo instruction */ 134e80d4af0SHarald Freudenberger cpacf_pckmo(fc, paramblock); 135e80d4af0SHarald Freudenberger 136e80d4af0SHarald Freudenberger /* copy created protected key */ 137e80d4af0SHarald Freudenberger protkey->type = keytype; 138e80d4af0SHarald Freudenberger protkey->len = keysize + 32; 139e80d4af0SHarald Freudenberger memcpy(protkey->protkey, paramblock, keysize + 32); 140e80d4af0SHarald Freudenberger 141e80d4af0SHarald Freudenberger return 0; 142e80d4af0SHarald Freudenberger } 143e80d4af0SHarald Freudenberger 144e80d4af0SHarald Freudenberger /* 145e80d4af0SHarald Freudenberger * Find card and transform secure key into protected key. 146e80d4af0SHarald Freudenberger */ 147f2bbc96eSHarald Freudenberger static int pkey_skey2pkey(const u8 *key, struct pkey_protkey *pkey) 148e80d4af0SHarald Freudenberger { 149e80d4af0SHarald Freudenberger int rc, verify; 150f2bbc96eSHarald Freudenberger u16 cardnr, domain; 151f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 152e80d4af0SHarald Freudenberger 153*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 154*43cb5a7cSHarald Freudenberger 155e80d4af0SHarald Freudenberger /* 156f2bbc96eSHarald Freudenberger * The cca_xxx2protkey call may fail when a card has been 157e80d4af0SHarald Freudenberger * addressed where the master key was changed after last fetch 158efc598e6SHarald Freudenberger * of the mkvp into the cache. Try 3 times: First witout verify 159efc598e6SHarald Freudenberger * then with verify and last round with verify and old master 160efc598e6SHarald Freudenberger * key verification pattern match not ignored. 161e80d4af0SHarald Freudenberger */ 162efc598e6SHarald Freudenberger for (verify = 0; verify < 3; verify++) { 163f2bbc96eSHarald Freudenberger rc = cca_findcard(key, &cardnr, &domain, verify); 164efc598e6SHarald Freudenberger if (rc < 0) 165e80d4af0SHarald Freudenberger continue; 166efc598e6SHarald Freudenberger if (rc > 0 && verify < 2) 167efc598e6SHarald Freudenberger continue; 168f2bbc96eSHarald Freudenberger switch (hdr->version) { 169f2bbc96eSHarald Freudenberger case TOKVER_CCA_AES: 170f2bbc96eSHarald Freudenberger rc = cca_sec2protkey(cardnr, domain, 171f2bbc96eSHarald Freudenberger key, pkey->protkey, 172f2bbc96eSHarald Freudenberger &pkey->len, &pkey->type); 173f2bbc96eSHarald Freudenberger break; 174f2bbc96eSHarald Freudenberger case TOKVER_CCA_VLSC: 175f2bbc96eSHarald Freudenberger rc = cca_cipher2protkey(cardnr, domain, 176f2bbc96eSHarald Freudenberger key, pkey->protkey, 177f2bbc96eSHarald Freudenberger &pkey->len, &pkey->type); 178f2bbc96eSHarald Freudenberger break; 179f2bbc96eSHarald Freudenberger default: 180f2bbc96eSHarald Freudenberger return -EINVAL; 181f2bbc96eSHarald Freudenberger } 182e80d4af0SHarald Freudenberger if (rc == 0) 183e80d4af0SHarald Freudenberger break; 184e80d4af0SHarald Freudenberger } 185e80d4af0SHarald Freudenberger 186e80d4af0SHarald Freudenberger if (rc) 187ac2b96f3SHarald Freudenberger DEBUG_DBG("%s failed rc=%d\n", __func__, rc); 188e80d4af0SHarald Freudenberger 189e80d4af0SHarald Freudenberger return rc; 190e80d4af0SHarald Freudenberger } 191e80d4af0SHarald Freudenberger 192e80d4af0SHarald Freudenberger /* 19355d0a513SHarald Freudenberger * Construct EP11 key with given clear key value. 19455d0a513SHarald Freudenberger */ 19555d0a513SHarald Freudenberger static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen, 19655d0a513SHarald Freudenberger u8 *keybuf, size_t *keybuflen) 19755d0a513SHarald Freudenberger { 19855d0a513SHarald Freudenberger int i, rc; 19955d0a513SHarald Freudenberger u16 card, dom; 20055d0a513SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 20155d0a513SHarald Freudenberger 202*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 203*43cb5a7cSHarald Freudenberger 20455d0a513SHarald Freudenberger /* build a list of apqns suitable for ep11 keys with cpacf support */ 20555d0a513SHarald Freudenberger rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 20655d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, NULL); 20755d0a513SHarald Freudenberger if (rc) 20855d0a513SHarald Freudenberger goto out; 20955d0a513SHarald Freudenberger 21055d0a513SHarald Freudenberger /* go through the list of apqns and try to bild an ep11 key */ 21155d0a513SHarald Freudenberger for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { 21255d0a513SHarald Freudenberger card = apqns[i] >> 16; 21355d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 21455d0a513SHarald Freudenberger rc = ep11_clr2keyblob(card, dom, clrkeylen * 8, 21555d0a513SHarald Freudenberger 0, clrkey, keybuf, keybuflen); 21655d0a513SHarald Freudenberger if (rc == 0) 21755d0a513SHarald Freudenberger break; 21855d0a513SHarald Freudenberger } 21955d0a513SHarald Freudenberger 22055d0a513SHarald Freudenberger out: 22155d0a513SHarald Freudenberger kfree(apqns); 22255d0a513SHarald Freudenberger if (rc) 22355d0a513SHarald Freudenberger DEBUG_DBG("%s failed rc=%d\n", __func__, rc); 22455d0a513SHarald Freudenberger return rc; 22555d0a513SHarald Freudenberger } 22655d0a513SHarald Freudenberger 22755d0a513SHarald Freudenberger /* 22855d0a513SHarald Freudenberger * Find card and transform EP11 secure key into protected key. 22955d0a513SHarald Freudenberger */ 23055d0a513SHarald Freudenberger static int pkey_ep11key2pkey(const u8 *key, struct pkey_protkey *pkey) 23155d0a513SHarald Freudenberger { 23255d0a513SHarald Freudenberger int i, rc; 23355d0a513SHarald Freudenberger u16 card, dom; 23455d0a513SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 23555d0a513SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *) key; 23655d0a513SHarald Freudenberger 237*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 238*43cb5a7cSHarald Freudenberger 23955d0a513SHarald Freudenberger /* build a list of apqns suitable for this key */ 24055d0a513SHarald Freudenberger rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 24155d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, kb->wkvp); 24255d0a513SHarald Freudenberger if (rc) 24355d0a513SHarald Freudenberger goto out; 24455d0a513SHarald Freudenberger 24555d0a513SHarald Freudenberger /* go through the list of apqns and try to derive an pkey */ 24655d0a513SHarald Freudenberger for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { 24755d0a513SHarald Freudenberger card = apqns[i] >> 16; 24855d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 249fa6999e3SHarald Freudenberger pkey->len = sizeof(pkey->protkey); 250fa6999e3SHarald Freudenberger rc = ep11_kblob2protkey(card, dom, key, kb->head.len, 25155d0a513SHarald Freudenberger pkey->protkey, &pkey->len, &pkey->type); 25255d0a513SHarald Freudenberger if (rc == 0) 25355d0a513SHarald Freudenberger break; 25455d0a513SHarald Freudenberger } 25555d0a513SHarald Freudenberger 25655d0a513SHarald Freudenberger out: 25755d0a513SHarald Freudenberger kfree(apqns); 25855d0a513SHarald Freudenberger if (rc) 25955d0a513SHarald Freudenberger DEBUG_DBG("%s failed rc=%d\n", __func__, rc); 26055d0a513SHarald Freudenberger return rc; 26155d0a513SHarald Freudenberger } 26255d0a513SHarald Freudenberger 26355d0a513SHarald Freudenberger /* 264e61a6134SHarald Freudenberger * Verify key and give back some info about the key. 265e61a6134SHarald Freudenberger */ 266183cb469SHarald Freudenberger static int pkey_verifykey(const struct pkey_seckey *seckey, 267e61a6134SHarald Freudenberger u16 *pcardnr, u16 *pdomain, 268e61a6134SHarald Freudenberger u16 *pkeysize, u32 *pattributes) 269e61a6134SHarald Freudenberger { 270e61a6134SHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *) seckey; 271e61a6134SHarald Freudenberger u16 cardnr, domain; 272e61a6134SHarald Freudenberger int rc; 273e61a6134SHarald Freudenberger 274e61a6134SHarald Freudenberger /* check the secure key for valid AES secure key */ 275efc598e6SHarald Freudenberger rc = cca_check_secaeskeytoken(debug_info, 3, (u8 *) seckey, 0); 276e61a6134SHarald Freudenberger if (rc) 277e61a6134SHarald Freudenberger goto out; 278e61a6134SHarald Freudenberger if (pattributes) 279e61a6134SHarald Freudenberger *pattributes = PKEY_VERIFY_ATTR_AES; 280e61a6134SHarald Freudenberger if (pkeysize) 281e61a6134SHarald Freudenberger *pkeysize = t->bitsize; 282e61a6134SHarald Freudenberger 283e61a6134SHarald Freudenberger /* try to find a card which can handle this key */ 284efc598e6SHarald Freudenberger rc = cca_findcard(seckey->seckey, &cardnr, &domain, 1); 285efc598e6SHarald Freudenberger if (rc < 0) 286e61a6134SHarald Freudenberger goto out; 287e61a6134SHarald Freudenberger 288efc598e6SHarald Freudenberger if (rc > 0) { 289efc598e6SHarald Freudenberger /* key mkvp matches to old master key mkvp */ 290ac2b96f3SHarald Freudenberger DEBUG_DBG("%s secure key has old mkvp\n", __func__); 291e61a6134SHarald Freudenberger if (pattributes) 292e61a6134SHarald Freudenberger *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP; 293efc598e6SHarald Freudenberger rc = 0; 294e61a6134SHarald Freudenberger } 295e61a6134SHarald Freudenberger 296e61a6134SHarald Freudenberger if (pcardnr) 297e61a6134SHarald Freudenberger *pcardnr = cardnr; 298e61a6134SHarald Freudenberger if (pdomain) 299e61a6134SHarald Freudenberger *pdomain = domain; 300e61a6134SHarald Freudenberger 301e61a6134SHarald Freudenberger out: 302ac2b96f3SHarald Freudenberger DEBUG_DBG("%s rc=%d\n", __func__, rc); 303e61a6134SHarald Freudenberger return rc; 304e61a6134SHarald Freudenberger } 305e61a6134SHarald Freudenberger 306e61a6134SHarald Freudenberger /* 307a45a5c7dSIngo Franzki * Generate a random protected key 308a45a5c7dSIngo Franzki */ 309183cb469SHarald Freudenberger static int pkey_genprotkey(u32 keytype, struct pkey_protkey *protkey) 310a45a5c7dSIngo Franzki { 311a45a5c7dSIngo Franzki struct pkey_clrkey clrkey; 312a45a5c7dSIngo Franzki int keysize; 313a45a5c7dSIngo Franzki int rc; 314a45a5c7dSIngo Franzki 315a45a5c7dSIngo Franzki switch (keytype) { 316a45a5c7dSIngo Franzki case PKEY_KEYTYPE_AES_128: 317a45a5c7dSIngo Franzki keysize = 16; 318a45a5c7dSIngo Franzki break; 319a45a5c7dSIngo Franzki case PKEY_KEYTYPE_AES_192: 320a45a5c7dSIngo Franzki keysize = 24; 321a45a5c7dSIngo Franzki break; 322a45a5c7dSIngo Franzki case PKEY_KEYTYPE_AES_256: 323a45a5c7dSIngo Franzki keysize = 32; 324a45a5c7dSIngo Franzki break; 325a45a5c7dSIngo Franzki default: 326a45a5c7dSIngo Franzki DEBUG_ERR("%s unknown/unsupported keytype %d\n", __func__, 327a45a5c7dSIngo Franzki keytype); 328a45a5c7dSIngo Franzki return -EINVAL; 329a45a5c7dSIngo Franzki } 330a45a5c7dSIngo Franzki 331a45a5c7dSIngo Franzki /* generate a dummy random clear key */ 332a45a5c7dSIngo Franzki get_random_bytes(clrkey.clrkey, keysize); 333a45a5c7dSIngo Franzki 334a45a5c7dSIngo Franzki /* convert it to a dummy protected key */ 335a45a5c7dSIngo Franzki rc = pkey_clr2protkey(keytype, &clrkey, protkey); 336a45a5c7dSIngo Franzki if (rc) 337a45a5c7dSIngo Franzki return rc; 338a45a5c7dSIngo Franzki 339a45a5c7dSIngo Franzki /* replace the key part of the protected key with random bytes */ 340a45a5c7dSIngo Franzki get_random_bytes(protkey->protkey, keysize); 341a45a5c7dSIngo Franzki 342a45a5c7dSIngo Franzki return 0; 343a45a5c7dSIngo Franzki } 344a45a5c7dSIngo Franzki 345a45a5c7dSIngo Franzki /* 346cb26b9ffSIngo Franzki * Verify if a protected key is still valid 347cb26b9ffSIngo Franzki */ 348183cb469SHarald Freudenberger static int pkey_verifyprotkey(const struct pkey_protkey *protkey) 349cb26b9ffSIngo Franzki { 350cb26b9ffSIngo Franzki unsigned long fc; 351cb26b9ffSIngo Franzki struct { 352cb26b9ffSIngo Franzki u8 iv[AES_BLOCK_SIZE]; 353cb26b9ffSIngo Franzki u8 key[MAXPROTKEYSIZE]; 354cb26b9ffSIngo Franzki } param; 355cb26b9ffSIngo Franzki u8 null_msg[AES_BLOCK_SIZE]; 356cb26b9ffSIngo Franzki u8 dest_buf[AES_BLOCK_SIZE]; 357cb26b9ffSIngo Franzki unsigned int k; 358cb26b9ffSIngo Franzki 359cb26b9ffSIngo Franzki switch (protkey->type) { 360cb26b9ffSIngo Franzki case PKEY_KEYTYPE_AES_128: 361cb26b9ffSIngo Franzki fc = CPACF_KMC_PAES_128; 362cb26b9ffSIngo Franzki break; 363cb26b9ffSIngo Franzki case PKEY_KEYTYPE_AES_192: 364cb26b9ffSIngo Franzki fc = CPACF_KMC_PAES_192; 365cb26b9ffSIngo Franzki break; 366cb26b9ffSIngo Franzki case PKEY_KEYTYPE_AES_256: 367cb26b9ffSIngo Franzki fc = CPACF_KMC_PAES_256; 368cb26b9ffSIngo Franzki break; 369cb26b9ffSIngo Franzki default: 370cb26b9ffSIngo Franzki DEBUG_ERR("%s unknown/unsupported keytype %d\n", __func__, 371cb26b9ffSIngo Franzki protkey->type); 372cb26b9ffSIngo Franzki return -EINVAL; 373cb26b9ffSIngo Franzki } 374cb26b9ffSIngo Franzki 375cb26b9ffSIngo Franzki memset(null_msg, 0, sizeof(null_msg)); 376cb26b9ffSIngo Franzki 377cb26b9ffSIngo Franzki memset(param.iv, 0, sizeof(param.iv)); 378cb26b9ffSIngo Franzki memcpy(param.key, protkey->protkey, sizeof(param.key)); 379cb26b9ffSIngo Franzki 380cb26b9ffSIngo Franzki k = cpacf_kmc(fc | CPACF_ENCRYPT, ¶m, null_msg, dest_buf, 381cb26b9ffSIngo Franzki sizeof(null_msg)); 382cb26b9ffSIngo Franzki if (k != sizeof(null_msg)) { 383cb26b9ffSIngo Franzki DEBUG_ERR("%s protected key is not valid\n", __func__); 384cb26b9ffSIngo Franzki return -EKEYREJECTED; 385cb26b9ffSIngo Franzki } 386cb26b9ffSIngo Franzki 387cb26b9ffSIngo Franzki return 0; 388cb26b9ffSIngo Franzki } 389cb26b9ffSIngo Franzki 390cb26b9ffSIngo Franzki /* 391fb1136d6SIngo Franzki * Transform a non-CCA key token into a protected key 392fb1136d6SIngo Franzki */ 393183cb469SHarald Freudenberger static int pkey_nonccatok2pkey(const u8 *key, u32 keylen, 394fb1136d6SIngo Franzki struct pkey_protkey *protkey) 395fb1136d6SIngo Franzki { 396888edbc4SHarald Freudenberger int rc = -EINVAL; 39755d0a513SHarald Freudenberger u8 *tmpbuf = NULL; 398fb1136d6SIngo Franzki struct keytoken_header *hdr = (struct keytoken_header *)key; 399fb1136d6SIngo Franzki 400fb1136d6SIngo Franzki switch (hdr->version) { 401888edbc4SHarald Freudenberger case TOKVER_PROTECTED_KEY: { 402888edbc4SHarald Freudenberger struct protaeskeytoken *t; 403fb1136d6SIngo Franzki 404888edbc4SHarald Freudenberger if (keylen != sizeof(struct protaeskeytoken)) 405888edbc4SHarald Freudenberger goto out; 406fb1136d6SIngo Franzki t = (struct protaeskeytoken *)key; 407fb1136d6SIngo Franzki protkey->len = t->len; 408fb1136d6SIngo Franzki protkey->type = t->keytype; 409fb1136d6SIngo Franzki memcpy(protkey->protkey, t->protkey, 410fb1136d6SIngo Franzki sizeof(protkey->protkey)); 411888edbc4SHarald Freudenberger rc = pkey_verifyprotkey(protkey); 412888edbc4SHarald Freudenberger break; 413888edbc4SHarald Freudenberger } 414888edbc4SHarald Freudenberger case TOKVER_CLEAR_KEY: { 415888edbc4SHarald Freudenberger struct clearaeskeytoken *t; 416888edbc4SHarald Freudenberger struct pkey_clrkey ckey; 41755d0a513SHarald Freudenberger union u_tmpbuf { 41855d0a513SHarald Freudenberger u8 skey[SECKEYBLOBSIZE]; 41955d0a513SHarald Freudenberger u8 ep11key[MAXEP11AESKEYBLOBSIZE]; 42055d0a513SHarald Freudenberger }; 42155d0a513SHarald Freudenberger size_t tmpbuflen = sizeof(union u_tmpbuf); 422fb1136d6SIngo Franzki 423888edbc4SHarald Freudenberger if (keylen < sizeof(struct clearaeskeytoken)) 424888edbc4SHarald Freudenberger goto out; 425888edbc4SHarald Freudenberger t = (struct clearaeskeytoken *)key; 426888edbc4SHarald Freudenberger if (keylen != sizeof(*t) + t->len) 427888edbc4SHarald Freudenberger goto out; 428888edbc4SHarald Freudenberger if ((t->keytype == PKEY_KEYTYPE_AES_128 && t->len == 16) 429888edbc4SHarald Freudenberger || (t->keytype == PKEY_KEYTYPE_AES_192 && t->len == 24) 430888edbc4SHarald Freudenberger || (t->keytype == PKEY_KEYTYPE_AES_256 && t->len == 32)) 431888edbc4SHarald Freudenberger memcpy(ckey.clrkey, t->clearkey, t->len); 432888edbc4SHarald Freudenberger else 433888edbc4SHarald Freudenberger goto out; 43455d0a513SHarald Freudenberger /* alloc temp key buffer space */ 43555d0a513SHarald Freudenberger tmpbuf = kmalloc(tmpbuflen, GFP_ATOMIC); 43655d0a513SHarald Freudenberger if (!tmpbuf) { 43755d0a513SHarald Freudenberger rc = -ENOMEM; 43855d0a513SHarald Freudenberger goto out; 43955d0a513SHarald Freudenberger } 440888edbc4SHarald Freudenberger /* try direct way with the PCKMO instruction */ 441888edbc4SHarald Freudenberger rc = pkey_clr2protkey(t->keytype, &ckey, protkey); 442888edbc4SHarald Freudenberger if (rc == 0) 443888edbc4SHarald Freudenberger break; 444888edbc4SHarald Freudenberger /* PCKMO failed, so try the CCA secure key way */ 445*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 446888edbc4SHarald Freudenberger rc = cca_clr2seckey(0xFFFF, 0xFFFF, t->keytype, 44755d0a513SHarald Freudenberger ckey.clrkey, tmpbuf); 448888edbc4SHarald Freudenberger if (rc == 0) 44955d0a513SHarald Freudenberger rc = pkey_skey2pkey(tmpbuf, protkey); 450888edbc4SHarald Freudenberger if (rc == 0) 451888edbc4SHarald Freudenberger break; 45255d0a513SHarald Freudenberger /* if the CCA way also failed, let's try via EP11 */ 45355d0a513SHarald Freudenberger rc = pkey_clr2ep11key(ckey.clrkey, t->len, 45455d0a513SHarald Freudenberger tmpbuf, &tmpbuflen); 45555d0a513SHarald Freudenberger if (rc == 0) 45655d0a513SHarald Freudenberger rc = pkey_ep11key2pkey(tmpbuf, protkey); 45755d0a513SHarald Freudenberger /* now we should really have an protected key */ 458888edbc4SHarald Freudenberger DEBUG_ERR("%s unable to build protected key from clear", 459888edbc4SHarald Freudenberger __func__); 460888edbc4SHarald Freudenberger break; 461888edbc4SHarald Freudenberger } 46255d0a513SHarald Freudenberger case TOKVER_EP11_AES: { 46355d0a513SHarald Freudenberger /* check ep11 key for exportable as protected key */ 464fa6999e3SHarald Freudenberger rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); 46555d0a513SHarald Freudenberger if (rc) 46655d0a513SHarald Freudenberger goto out; 46755d0a513SHarald Freudenberger rc = pkey_ep11key2pkey(key, protkey); 46855d0a513SHarald Freudenberger break; 46955d0a513SHarald Freudenberger } 470fa6999e3SHarald Freudenberger case TOKVER_EP11_AES_WITH_HEADER: 471fa6999e3SHarald Freudenberger /* check ep11 key with header for exportable as protected key */ 472fa6999e3SHarald Freudenberger rc = ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1); 473fa6999e3SHarald Freudenberger if (rc) 474fa6999e3SHarald Freudenberger goto out; 475fa6999e3SHarald Freudenberger rc = pkey_ep11key2pkey(key + sizeof(struct ep11kblob_header), 476fa6999e3SHarald Freudenberger protkey); 477fa6999e3SHarald Freudenberger break; 478fb1136d6SIngo Franzki default: 479fb1136d6SIngo Franzki DEBUG_ERR("%s unknown/unsupported non-CCA token version %d\n", 480fb1136d6SIngo Franzki __func__, hdr->version); 481888edbc4SHarald Freudenberger rc = -EINVAL; 482fb1136d6SIngo Franzki } 483888edbc4SHarald Freudenberger 484888edbc4SHarald Freudenberger out: 48555d0a513SHarald Freudenberger kfree(tmpbuf); 486888edbc4SHarald Freudenberger return rc; 487fb1136d6SIngo Franzki } 488fb1136d6SIngo Franzki 489fb1136d6SIngo Franzki /* 490fb1136d6SIngo Franzki * Transform a CCA internal key token into a protected key 491fb1136d6SIngo Franzki */ 492183cb469SHarald Freudenberger static int pkey_ccainttok2pkey(const u8 *key, u32 keylen, 493fb1136d6SIngo Franzki struct pkey_protkey *protkey) 494fb1136d6SIngo Franzki { 495fb1136d6SIngo Franzki struct keytoken_header *hdr = (struct keytoken_header *)key; 496fb1136d6SIngo Franzki 497fb1136d6SIngo Franzki switch (hdr->version) { 498fb1136d6SIngo Franzki case TOKVER_CCA_AES: 499fb1136d6SIngo Franzki if (keylen != sizeof(struct secaeskeytoken)) 500fb1136d6SIngo Franzki return -EINVAL; 501f2bbc96eSHarald Freudenberger break; 502f2bbc96eSHarald Freudenberger case TOKVER_CCA_VLSC: 503f2bbc96eSHarald Freudenberger if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 504f2bbc96eSHarald Freudenberger return -EINVAL; 505f2bbc96eSHarald Freudenberger break; 506fb1136d6SIngo Franzki default: 507fb1136d6SIngo Franzki DEBUG_ERR("%s unknown/unsupported CCA internal token version %d\n", 508fb1136d6SIngo Franzki __func__, hdr->version); 509fb1136d6SIngo Franzki return -EINVAL; 510fb1136d6SIngo Franzki } 511f2bbc96eSHarald Freudenberger 512f2bbc96eSHarald Freudenberger return pkey_skey2pkey(key, protkey); 513fb1136d6SIngo Franzki } 514fb1136d6SIngo Franzki 515fb1136d6SIngo Franzki /* 516fb1136d6SIngo Franzki * Transform a key blob (of any type) into a protected key 517fb1136d6SIngo Franzki */ 518183cb469SHarald Freudenberger int pkey_keyblob2pkey(const u8 *key, u32 keylen, 519fb1136d6SIngo Franzki struct pkey_protkey *protkey) 520fb1136d6SIngo Franzki { 521f2bbc96eSHarald Freudenberger int rc; 522fb1136d6SIngo Franzki struct keytoken_header *hdr = (struct keytoken_header *)key; 523fb1136d6SIngo Franzki 524f2bbc96eSHarald Freudenberger if (keylen < sizeof(struct keytoken_header)) { 525f2bbc96eSHarald Freudenberger DEBUG_ERR("%s invalid keylen %d\n", __func__, keylen); 526f2bbc96eSHarald Freudenberger return -EINVAL; 527f2bbc96eSHarald Freudenberger } 528f2bbc96eSHarald Freudenberger 529f2bbc96eSHarald Freudenberger switch (hdr->type) { 530f2bbc96eSHarald Freudenberger case TOKTYPE_NON_CCA: 531f2bbc96eSHarald Freudenberger rc = pkey_nonccatok2pkey(key, keylen, protkey); 532f2bbc96eSHarald Freudenberger break; 533f2bbc96eSHarald Freudenberger case TOKTYPE_CCA_INTERNAL: 534f2bbc96eSHarald Freudenberger rc = pkey_ccainttok2pkey(key, keylen, protkey); 535f2bbc96eSHarald Freudenberger break; 536f2bbc96eSHarald Freudenberger default: 537f2bbc96eSHarald Freudenberger DEBUG_ERR("%s unknown/unsupported blob type %d\n", 538f2bbc96eSHarald Freudenberger __func__, hdr->type); 539f2bbc96eSHarald Freudenberger return -EINVAL; 540f2bbc96eSHarald Freudenberger } 541f2bbc96eSHarald Freudenberger 542f2bbc96eSHarald Freudenberger DEBUG_DBG("%s rc=%d\n", __func__, rc); 543f2bbc96eSHarald Freudenberger return rc; 544f2bbc96eSHarald Freudenberger 545f2bbc96eSHarald Freudenberger } 546f2bbc96eSHarald Freudenberger EXPORT_SYMBOL(pkey_keyblob2pkey); 547f2bbc96eSHarald Freudenberger 548f2bbc96eSHarald Freudenberger static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns, 549f2bbc96eSHarald Freudenberger enum pkey_key_type ktype, enum pkey_key_size ksize, 550f2bbc96eSHarald Freudenberger u32 kflags, u8 *keybuf, size_t *keybufsize) 551f2bbc96eSHarald Freudenberger { 552f2bbc96eSHarald Freudenberger int i, card, dom, rc; 553f2bbc96eSHarald Freudenberger 554f2bbc96eSHarald Freudenberger /* check for at least one apqn given */ 555f2bbc96eSHarald Freudenberger if (!apqns || !nr_apqns) 556f2bbc96eSHarald Freudenberger return -EINVAL; 557f2bbc96eSHarald Freudenberger 558f2bbc96eSHarald Freudenberger /* check key type and size */ 559f2bbc96eSHarald Freudenberger switch (ktype) { 560f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_DATA: 561f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_CIPHER: 562f2bbc96eSHarald Freudenberger if (*keybufsize < SECKEYBLOBSIZE) 563f2bbc96eSHarald Freudenberger return -EINVAL; 564f2bbc96eSHarald Freudenberger break; 56555d0a513SHarald Freudenberger case PKEY_TYPE_EP11: 56655d0a513SHarald Freudenberger if (*keybufsize < MINEP11AESKEYBLOBSIZE) 56755d0a513SHarald Freudenberger return -EINVAL; 56855d0a513SHarald Freudenberger break; 569f2bbc96eSHarald Freudenberger default: 570f2bbc96eSHarald Freudenberger return -EINVAL; 571f2bbc96eSHarald Freudenberger } 572f2bbc96eSHarald Freudenberger switch (ksize) { 573f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_128: 574f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_192: 575f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_256: 576f2bbc96eSHarald Freudenberger break; 577f2bbc96eSHarald Freudenberger default: 578f2bbc96eSHarald Freudenberger return -EINVAL; 579f2bbc96eSHarald Freudenberger } 580f2bbc96eSHarald Freudenberger 581f2bbc96eSHarald Freudenberger /* simple try all apqns from the list */ 582f2bbc96eSHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 583f2bbc96eSHarald Freudenberger card = apqns[i].card; 584f2bbc96eSHarald Freudenberger dom = apqns[i].domain; 58555d0a513SHarald Freudenberger if (ktype == PKEY_TYPE_EP11) { 58655d0a513SHarald Freudenberger rc = ep11_genaeskey(card, dom, ksize, kflags, 58755d0a513SHarald Freudenberger keybuf, keybufsize); 58855d0a513SHarald Freudenberger } else if (ktype == PKEY_TYPE_CCA_DATA) { 589f2bbc96eSHarald Freudenberger rc = cca_genseckey(card, dom, ksize, keybuf); 590f2bbc96eSHarald Freudenberger *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); 591f2bbc96eSHarald Freudenberger } else /* TOKVER_CCA_VLSC */ 592f2bbc96eSHarald Freudenberger rc = cca_gencipherkey(card, dom, ksize, kflags, 593f2bbc96eSHarald Freudenberger keybuf, keybufsize); 594f2bbc96eSHarald Freudenberger if (rc == 0) 595f2bbc96eSHarald Freudenberger break; 596f2bbc96eSHarald Freudenberger } 597f2bbc96eSHarald Freudenberger 598f2bbc96eSHarald Freudenberger return rc; 599f2bbc96eSHarald Freudenberger } 600f2bbc96eSHarald Freudenberger 601f2bbc96eSHarald Freudenberger static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns, 602f2bbc96eSHarald Freudenberger enum pkey_key_type ktype, enum pkey_key_size ksize, 603f2bbc96eSHarald Freudenberger u32 kflags, const u8 *clrkey, 604f2bbc96eSHarald Freudenberger u8 *keybuf, size_t *keybufsize) 605f2bbc96eSHarald Freudenberger { 606f2bbc96eSHarald Freudenberger int i, card, dom, rc; 607f2bbc96eSHarald Freudenberger 608f2bbc96eSHarald Freudenberger /* check for at least one apqn given */ 609f2bbc96eSHarald Freudenberger if (!apqns || !nr_apqns) 610f2bbc96eSHarald Freudenberger return -EINVAL; 611f2bbc96eSHarald Freudenberger 612f2bbc96eSHarald Freudenberger /* check key type and size */ 613f2bbc96eSHarald Freudenberger switch (ktype) { 614f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_DATA: 615f2bbc96eSHarald Freudenberger case PKEY_TYPE_CCA_CIPHER: 616f2bbc96eSHarald Freudenberger if (*keybufsize < SECKEYBLOBSIZE) 617f2bbc96eSHarald Freudenberger return -EINVAL; 618f2bbc96eSHarald Freudenberger break; 61955d0a513SHarald Freudenberger case PKEY_TYPE_EP11: 62055d0a513SHarald Freudenberger if (*keybufsize < MINEP11AESKEYBLOBSIZE) 62155d0a513SHarald Freudenberger return -EINVAL; 62255d0a513SHarald Freudenberger break; 623f2bbc96eSHarald Freudenberger default: 624f2bbc96eSHarald Freudenberger return -EINVAL; 625f2bbc96eSHarald Freudenberger } 626f2bbc96eSHarald Freudenberger switch (ksize) { 627f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_128: 628f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_192: 629f2bbc96eSHarald Freudenberger case PKEY_SIZE_AES_256: 630f2bbc96eSHarald Freudenberger break; 631f2bbc96eSHarald Freudenberger default: 632f2bbc96eSHarald Freudenberger return -EINVAL; 633f2bbc96eSHarald Freudenberger } 634f2bbc96eSHarald Freudenberger 635*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 636*43cb5a7cSHarald Freudenberger 637f2bbc96eSHarald Freudenberger /* simple try all apqns from the list */ 638f2bbc96eSHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 639f2bbc96eSHarald Freudenberger card = apqns[i].card; 640f2bbc96eSHarald Freudenberger dom = apqns[i].domain; 64155d0a513SHarald Freudenberger if (ktype == PKEY_TYPE_EP11) { 64255d0a513SHarald Freudenberger rc = ep11_clr2keyblob(card, dom, ksize, kflags, 64355d0a513SHarald Freudenberger clrkey, keybuf, keybufsize); 64455d0a513SHarald Freudenberger } else if (ktype == PKEY_TYPE_CCA_DATA) { 645f2bbc96eSHarald Freudenberger rc = cca_clr2seckey(card, dom, ksize, 646f2bbc96eSHarald Freudenberger clrkey, keybuf); 647f2bbc96eSHarald Freudenberger *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); 648f2bbc96eSHarald Freudenberger } else /* TOKVER_CCA_VLSC */ 649f2bbc96eSHarald Freudenberger rc = cca_clr2cipherkey(card, dom, ksize, kflags, 650f2bbc96eSHarald Freudenberger clrkey, keybuf, keybufsize); 651f2bbc96eSHarald Freudenberger if (rc == 0) 652f2bbc96eSHarald Freudenberger break; 653f2bbc96eSHarald Freudenberger } 654f2bbc96eSHarald Freudenberger 655f2bbc96eSHarald Freudenberger return rc; 656f2bbc96eSHarald Freudenberger } 657f2bbc96eSHarald Freudenberger 658f2bbc96eSHarald Freudenberger static int pkey_verifykey2(const u8 *key, size_t keylen, 659f2bbc96eSHarald Freudenberger u16 *cardnr, u16 *domain, 660f2bbc96eSHarald Freudenberger enum pkey_key_type *ktype, 661f2bbc96eSHarald Freudenberger enum pkey_key_size *ksize, u32 *flags) 662f2bbc96eSHarald Freudenberger { 663f2bbc96eSHarald Freudenberger int rc; 664f2bbc96eSHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 665f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 666f2bbc96eSHarald Freudenberger 66755d0a513SHarald Freudenberger if (keylen < sizeof(struct keytoken_header)) 668f2bbc96eSHarald Freudenberger return -EINVAL; 669f2bbc96eSHarald Freudenberger 67055d0a513SHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL 67155d0a513SHarald Freudenberger && hdr->version == TOKVER_CCA_AES) { 672f2bbc96eSHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *)key; 673f2bbc96eSHarald Freudenberger 674f2bbc96eSHarald Freudenberger rc = cca_check_secaeskeytoken(debug_info, 3, key, 0); 675f2bbc96eSHarald Freudenberger if (rc) 676f2bbc96eSHarald Freudenberger goto out; 677f2bbc96eSHarald Freudenberger if (ktype) 678f2bbc96eSHarald Freudenberger *ktype = PKEY_TYPE_CCA_DATA; 679f2bbc96eSHarald Freudenberger if (ksize) 680f2bbc96eSHarald Freudenberger *ksize = (enum pkey_key_size) t->bitsize; 681f2bbc96eSHarald Freudenberger 682f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 68332ca04bbSHarald Freudenberger ZCRYPT_CEX3C, AES_MK_SET, t->mkvp, 0, 1); 684f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 685f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 686f2bbc96eSHarald Freudenberger if (rc == -ENODEV) { 687f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 688f2bbc96eSHarald Freudenberger *cardnr, *domain, 68932ca04bbSHarald Freudenberger ZCRYPT_CEX3C, AES_MK_SET, 69032ca04bbSHarald Freudenberger 0, t->mkvp, 1); 691f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 692f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 693f2bbc96eSHarald Freudenberger } 694f2bbc96eSHarald Freudenberger if (rc) 695f2bbc96eSHarald Freudenberger goto out; 696f2bbc96eSHarald Freudenberger 697f2bbc96eSHarald Freudenberger *cardnr = ((struct pkey_apqn *)_apqns)->card; 698f2bbc96eSHarald Freudenberger *domain = ((struct pkey_apqn *)_apqns)->domain; 699f2bbc96eSHarald Freudenberger 70055d0a513SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL 70155d0a513SHarald Freudenberger && hdr->version == TOKVER_CCA_VLSC) { 702f2bbc96eSHarald Freudenberger struct cipherkeytoken *t = (struct cipherkeytoken *)key; 703f2bbc96eSHarald Freudenberger 704f2bbc96eSHarald Freudenberger rc = cca_check_secaescipherkey(debug_info, 3, key, 0, 1); 705f2bbc96eSHarald Freudenberger if (rc) 706f2bbc96eSHarald Freudenberger goto out; 707f2bbc96eSHarald Freudenberger if (ktype) 708f2bbc96eSHarald Freudenberger *ktype = PKEY_TYPE_CCA_CIPHER; 709f2bbc96eSHarald Freudenberger if (ksize) { 710f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_UNKNOWN; 711f2bbc96eSHarald Freudenberger if (!t->plfver && t->wpllen == 512) 712f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_AES_128; 713f2bbc96eSHarald Freudenberger else if (!t->plfver && t->wpllen == 576) 714f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_AES_192; 715f2bbc96eSHarald Freudenberger else if (!t->plfver && t->wpllen == 640) 716f2bbc96eSHarald Freudenberger *ksize = PKEY_SIZE_AES_256; 717f2bbc96eSHarald Freudenberger } 718f2bbc96eSHarald Freudenberger 719f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 72032ca04bbSHarald Freudenberger ZCRYPT_CEX6, AES_MK_SET, t->mkvp0, 0, 1); 721f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 722f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 723f2bbc96eSHarald Freudenberger if (rc == -ENODEV) { 724f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 725f2bbc96eSHarald Freudenberger *cardnr, *domain, 72632ca04bbSHarald Freudenberger ZCRYPT_CEX6, AES_MK_SET, 72732ca04bbSHarald Freudenberger 0, t->mkvp0, 1); 728f2bbc96eSHarald Freudenberger if (rc == 0 && flags) 729f2bbc96eSHarald Freudenberger *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 730f2bbc96eSHarald Freudenberger } 731f2bbc96eSHarald Freudenberger if (rc) 732f2bbc96eSHarald Freudenberger goto out; 733f2bbc96eSHarald Freudenberger 734f2bbc96eSHarald Freudenberger *cardnr = ((struct pkey_apqn *)_apqns)->card; 735f2bbc96eSHarald Freudenberger *domain = ((struct pkey_apqn *)_apqns)->domain; 736f2bbc96eSHarald Freudenberger 73755d0a513SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA 73855d0a513SHarald Freudenberger && hdr->version == TOKVER_EP11_AES) { 73955d0a513SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *)key; 74055d0a513SHarald Freudenberger 741fa6999e3SHarald Freudenberger rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1); 74255d0a513SHarald Freudenberger if (rc) 74355d0a513SHarald Freudenberger goto out; 74455d0a513SHarald Freudenberger if (ktype) 74555d0a513SHarald Freudenberger *ktype = PKEY_TYPE_EP11; 74655d0a513SHarald Freudenberger if (ksize) 74755d0a513SHarald Freudenberger *ksize = kb->head.keybitlen; 74855d0a513SHarald Freudenberger 74955d0a513SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, 75055d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, kb->wkvp); 75155d0a513SHarald Freudenberger if (rc) 75255d0a513SHarald Freudenberger goto out; 75355d0a513SHarald Freudenberger 75455d0a513SHarald Freudenberger if (flags) 75555d0a513SHarald Freudenberger *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 75655d0a513SHarald Freudenberger 75755d0a513SHarald Freudenberger *cardnr = ((struct pkey_apqn *)_apqns)->card; 75855d0a513SHarald Freudenberger *domain = ((struct pkey_apqn *)_apqns)->domain; 75955d0a513SHarald Freudenberger 760f2bbc96eSHarald Freudenberger } else 761f2bbc96eSHarald Freudenberger rc = -EINVAL; 762f2bbc96eSHarald Freudenberger 763f2bbc96eSHarald Freudenberger out: 764f2bbc96eSHarald Freudenberger kfree(_apqns); 765f2bbc96eSHarald Freudenberger return rc; 766f2bbc96eSHarald Freudenberger } 767f2bbc96eSHarald Freudenberger 768f2bbc96eSHarald Freudenberger static int pkey_keyblob2pkey2(const struct pkey_apqn *apqns, size_t nr_apqns, 769f2bbc96eSHarald Freudenberger const u8 *key, size_t keylen, 770f2bbc96eSHarald Freudenberger struct pkey_protkey *pkey) 771f2bbc96eSHarald Freudenberger { 772f2bbc96eSHarald Freudenberger int i, card, dom, rc; 773f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 774f2bbc96eSHarald Freudenberger 775f2bbc96eSHarald Freudenberger /* check for at least one apqn given */ 776f2bbc96eSHarald Freudenberger if (!apqns || !nr_apqns) 777f2bbc96eSHarald Freudenberger return -EINVAL; 778f2bbc96eSHarald Freudenberger 779fb1136d6SIngo Franzki if (keylen < sizeof(struct keytoken_header)) 780fb1136d6SIngo Franzki return -EINVAL; 781fb1136d6SIngo Franzki 78255d0a513SHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL) { 78355d0a513SHarald Freudenberger if (hdr->version == TOKVER_CCA_AES) { 784f2bbc96eSHarald Freudenberger if (keylen != sizeof(struct secaeskeytoken)) 785f2bbc96eSHarald Freudenberger return -EINVAL; 786f2bbc96eSHarald Freudenberger if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) 787f2bbc96eSHarald Freudenberger return -EINVAL; 78855d0a513SHarald Freudenberger } else if (hdr->version == TOKVER_CCA_VLSC) { 789f2bbc96eSHarald Freudenberger if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 790f2bbc96eSHarald Freudenberger return -EINVAL; 791f2bbc96eSHarald Freudenberger if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) 792f2bbc96eSHarald Freudenberger return -EINVAL; 79355d0a513SHarald Freudenberger } else { 794f2bbc96eSHarald Freudenberger DEBUG_ERR("%s unknown CCA internal token version %d\n", 795f2bbc96eSHarald Freudenberger __func__, hdr->version); 796fb1136d6SIngo Franzki return -EINVAL; 797fb1136d6SIngo Franzki } 79855d0a513SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA) { 79955d0a513SHarald Freudenberger if (hdr->version == TOKVER_EP11_AES) { 80055d0a513SHarald Freudenberger if (keylen < sizeof(struct ep11keyblob)) 80155d0a513SHarald Freudenberger return -EINVAL; 802fa6999e3SHarald Freudenberger if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) 80355d0a513SHarald Freudenberger return -EINVAL; 80455d0a513SHarald Freudenberger } else { 80555d0a513SHarald Freudenberger return pkey_nonccatok2pkey(key, keylen, pkey); 80655d0a513SHarald Freudenberger } 80755d0a513SHarald Freudenberger } else { 808f2bbc96eSHarald Freudenberger DEBUG_ERR("%s unknown/unsupported blob type %d\n", 809f2bbc96eSHarald Freudenberger __func__, hdr->type); 810f2bbc96eSHarald Freudenberger return -EINVAL; 811fb1136d6SIngo Franzki } 812f2bbc96eSHarald Freudenberger 813*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 814*43cb5a7cSHarald Freudenberger 815f2bbc96eSHarald Freudenberger /* simple try all apqns from the list */ 816f2bbc96eSHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 817f2bbc96eSHarald Freudenberger card = apqns[i].card; 818f2bbc96eSHarald Freudenberger dom = apqns[i].domain; 81955d0a513SHarald Freudenberger if (hdr->type == TOKTYPE_CCA_INTERNAL 82055d0a513SHarald Freudenberger && hdr->version == TOKVER_CCA_AES) 821f2bbc96eSHarald Freudenberger rc = cca_sec2protkey(card, dom, key, pkey->protkey, 822f2bbc96eSHarald Freudenberger &pkey->len, &pkey->type); 82355d0a513SHarald Freudenberger else if (hdr->type == TOKTYPE_CCA_INTERNAL 82455d0a513SHarald Freudenberger && hdr->version == TOKVER_CCA_VLSC) 825f2bbc96eSHarald Freudenberger rc = cca_cipher2protkey(card, dom, key, pkey->protkey, 826f2bbc96eSHarald Freudenberger &pkey->len, &pkey->type); 82755d0a513SHarald Freudenberger else { /* EP11 AES secure key blob */ 82855d0a513SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *) key; 82955d0a513SHarald Freudenberger 830fa6999e3SHarald Freudenberger pkey->len = sizeof(pkey->protkey); 831fa6999e3SHarald Freudenberger rc = ep11_kblob2protkey(card, dom, key, kb->head.len, 83255d0a513SHarald Freudenberger pkey->protkey, &pkey->len, 83355d0a513SHarald Freudenberger &pkey->type); 83455d0a513SHarald Freudenberger } 835f2bbc96eSHarald Freudenberger if (rc == 0) 836f2bbc96eSHarald Freudenberger break; 837f2bbc96eSHarald Freudenberger } 838f2bbc96eSHarald Freudenberger 839f2bbc96eSHarald Freudenberger return rc; 840f2bbc96eSHarald Freudenberger } 841f2bbc96eSHarald Freudenberger 842f2bbc96eSHarald Freudenberger static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags, 843f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns, size_t *nr_apqns) 844f2bbc96eSHarald Freudenberger { 84575be6b98STianjia Zhang int rc; 846f2bbc96eSHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 847f2bbc96eSHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 848f2bbc96eSHarald Freudenberger 84955d0a513SHarald Freudenberger if (keylen < sizeof(struct keytoken_header) || flags == 0) 850f2bbc96eSHarald Freudenberger return -EINVAL; 851f2bbc96eSHarald Freudenberger 852*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 853*43cb5a7cSHarald Freudenberger 854fa6999e3SHarald Freudenberger if (hdr->type == TOKTYPE_NON_CCA 855fa6999e3SHarald Freudenberger && (hdr->version == TOKVER_EP11_AES_WITH_HEADER 856fa6999e3SHarald Freudenberger || hdr->version == TOKVER_EP11_ECC_WITH_HEADER) 857fa6999e3SHarald Freudenberger && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 858fa6999e3SHarald Freudenberger int minhwtype = 0, api = 0; 859fa6999e3SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *) 860fa6999e3SHarald Freudenberger (key + sizeof(struct ep11kblob_header)); 861fa6999e3SHarald Freudenberger 862fa6999e3SHarald Freudenberger if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) 863fa6999e3SHarald Freudenberger return -EINVAL; 864fa6999e3SHarald Freudenberger if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { 865fa6999e3SHarald Freudenberger minhwtype = ZCRYPT_CEX7; 866fa6999e3SHarald Freudenberger api = EP11_API_V; 867fa6999e3SHarald Freudenberger } 868fa6999e3SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 869fa6999e3SHarald Freudenberger minhwtype, api, kb->wkvp); 870fa6999e3SHarald Freudenberger if (rc) 871fa6999e3SHarald Freudenberger goto out; 872fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA 873fa6999e3SHarald Freudenberger && hdr->version == TOKVER_EP11_AES 874fa6999e3SHarald Freudenberger && is_ep11_keyblob(key)) { 87555d0a513SHarald Freudenberger int minhwtype = 0, api = 0; 87655d0a513SHarald Freudenberger struct ep11keyblob *kb = (struct ep11keyblob *) key; 87755d0a513SHarald Freudenberger 87855d0a513SHarald Freudenberger if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) 87955d0a513SHarald Freudenberger return -EINVAL; 88055d0a513SHarald Freudenberger if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { 88155d0a513SHarald Freudenberger minhwtype = ZCRYPT_CEX7; 88255d0a513SHarald Freudenberger api = EP11_API_V; 88355d0a513SHarald Freudenberger } 88455d0a513SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 88555d0a513SHarald Freudenberger minhwtype, api, kb->wkvp); 88655d0a513SHarald Freudenberger if (rc) 88755d0a513SHarald Freudenberger goto out; 88855d0a513SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { 889f2bbc96eSHarald Freudenberger int minhwtype = ZCRYPT_CEX3C; 890f2bbc96eSHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 891f2bbc96eSHarald Freudenberger 892f2bbc96eSHarald Freudenberger if (hdr->version == TOKVER_CCA_AES) { 893f2bbc96eSHarald Freudenberger struct secaeskeytoken *t = (struct secaeskeytoken *)key; 894f2bbc96eSHarald Freudenberger 895f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 896f2bbc96eSHarald Freudenberger cur_mkvp = t->mkvp; 897f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 898f2bbc96eSHarald Freudenberger old_mkvp = t->mkvp; 89955d0a513SHarald Freudenberger } else if (hdr->version == TOKVER_CCA_VLSC) { 900f2bbc96eSHarald Freudenberger struct cipherkeytoken *t = (struct cipherkeytoken *)key; 901f2bbc96eSHarald Freudenberger 902f2bbc96eSHarald Freudenberger minhwtype = ZCRYPT_CEX6; 903f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 904f2bbc96eSHarald Freudenberger cur_mkvp = t->mkvp0; 905f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 906f2bbc96eSHarald Freudenberger old_mkvp = t->mkvp0; 90755d0a513SHarald Freudenberger } else { 90855d0a513SHarald Freudenberger /* unknown cca internal token type */ 90955d0a513SHarald Freudenberger return -EINVAL; 910f2bbc96eSHarald Freudenberger } 911f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 91232ca04bbSHarald Freudenberger minhwtype, AES_MK_SET, 91332ca04bbSHarald Freudenberger cur_mkvp, old_mkvp, 1); 914f2bbc96eSHarald Freudenberger if (rc) 915f2bbc96eSHarald Freudenberger goto out; 916fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 917fa6999e3SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 918fa6999e3SHarald Freudenberger struct eccprivkeytoken *t = (struct eccprivkeytoken *)key; 919fa6999e3SHarald Freudenberger 920fa6999e3SHarald Freudenberger if (t->secid == 0x20) { 921fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 922fa6999e3SHarald Freudenberger cur_mkvp = t->mkvp; 923fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 924fa6999e3SHarald Freudenberger old_mkvp = t->mkvp; 925fa6999e3SHarald Freudenberger } else { 926fa6999e3SHarald Freudenberger /* unknown cca internal 2 token type */ 927fa6999e3SHarald Freudenberger return -EINVAL; 928fa6999e3SHarald Freudenberger } 929fa6999e3SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 930fa6999e3SHarald Freudenberger ZCRYPT_CEX7, APKA_MK_SET, 931fa6999e3SHarald Freudenberger cur_mkvp, old_mkvp, 1); 932fa6999e3SHarald Freudenberger if (rc) 933fa6999e3SHarald Freudenberger goto out; 93455d0a513SHarald Freudenberger } else 93555d0a513SHarald Freudenberger return -EINVAL; 93655d0a513SHarald Freudenberger 937f2bbc96eSHarald Freudenberger if (apqns) { 938f2bbc96eSHarald Freudenberger if (*nr_apqns < _nr_apqns) 939f2bbc96eSHarald Freudenberger rc = -ENOSPC; 940f2bbc96eSHarald Freudenberger else 941f2bbc96eSHarald Freudenberger memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 942f2bbc96eSHarald Freudenberger } 943f2bbc96eSHarald Freudenberger *nr_apqns = _nr_apqns; 944f2bbc96eSHarald Freudenberger 945f2bbc96eSHarald Freudenberger out: 946f2bbc96eSHarald Freudenberger kfree(_apqns); 947f2bbc96eSHarald Freudenberger return rc; 948f2bbc96eSHarald Freudenberger } 949f2bbc96eSHarald Freudenberger 950f2bbc96eSHarald Freudenberger static int pkey_apqns4keytype(enum pkey_key_type ktype, 951f2bbc96eSHarald Freudenberger u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags, 952f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns, size_t *nr_apqns) 953f2bbc96eSHarald Freudenberger { 95475be6b98STianjia Zhang int rc; 955f2bbc96eSHarald Freudenberger u32 _nr_apqns, *_apqns = NULL; 956f2bbc96eSHarald Freudenberger 957*43cb5a7cSHarald Freudenberger zcrypt_wait_api_operational(); 958*43cb5a7cSHarald Freudenberger 959f2bbc96eSHarald Freudenberger if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) { 960f2bbc96eSHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 961f2bbc96eSHarald Freudenberger int minhwtype = ZCRYPT_CEX3C; 962f2bbc96eSHarald Freudenberger 963f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 964f2bbc96eSHarald Freudenberger cur_mkvp = *((u64 *) cur_mkvp); 965f2bbc96eSHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 966f2bbc96eSHarald Freudenberger old_mkvp = *((u64 *) alt_mkvp); 967f2bbc96eSHarald Freudenberger if (ktype == PKEY_TYPE_CCA_CIPHER) 968f2bbc96eSHarald Freudenberger minhwtype = ZCRYPT_CEX6; 969f2bbc96eSHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 97032ca04bbSHarald Freudenberger minhwtype, AES_MK_SET, 97132ca04bbSHarald Freudenberger cur_mkvp, old_mkvp, 1); 972f2bbc96eSHarald Freudenberger if (rc) 973f2bbc96eSHarald Freudenberger goto out; 974fa6999e3SHarald Freudenberger } else if (ktype == PKEY_TYPE_CCA_ECC) { 975fa6999e3SHarald Freudenberger u64 cur_mkvp = 0, old_mkvp = 0; 976fa6999e3SHarald Freudenberger 977fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 978fa6999e3SHarald Freudenberger cur_mkvp = *((u64 *) cur_mkvp); 979fa6999e3SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 980fa6999e3SHarald Freudenberger old_mkvp = *((u64 *) alt_mkvp); 981fa6999e3SHarald Freudenberger rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 982fa6999e3SHarald Freudenberger ZCRYPT_CEX7, APKA_MK_SET, 983fa6999e3SHarald Freudenberger cur_mkvp, old_mkvp, 1); 984fa6999e3SHarald Freudenberger if (rc) 985fa6999e3SHarald Freudenberger goto out; 986fa6999e3SHarald Freudenberger 987fa6999e3SHarald Freudenberger } else if (ktype == PKEY_TYPE_EP11 || 988fa6999e3SHarald Freudenberger ktype == PKEY_TYPE_EP11_AES || 989fa6999e3SHarald Freudenberger ktype == PKEY_TYPE_EP11_ECC) { 99055d0a513SHarald Freudenberger u8 *wkvp = NULL; 99155d0a513SHarald Freudenberger 99255d0a513SHarald Freudenberger if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 99355d0a513SHarald Freudenberger wkvp = cur_mkvp; 99455d0a513SHarald Freudenberger rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 99555d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, wkvp); 99655d0a513SHarald Freudenberger if (rc) 99755d0a513SHarald Freudenberger goto out; 99855d0a513SHarald Freudenberger 99955d0a513SHarald Freudenberger } else 100055d0a513SHarald Freudenberger return -EINVAL; 100155d0a513SHarald Freudenberger 1002f2bbc96eSHarald Freudenberger if (apqns) { 1003f2bbc96eSHarald Freudenberger if (*nr_apqns < _nr_apqns) 1004f2bbc96eSHarald Freudenberger rc = -ENOSPC; 1005f2bbc96eSHarald Freudenberger else 1006f2bbc96eSHarald Freudenberger memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 1007f2bbc96eSHarald Freudenberger } 1008f2bbc96eSHarald Freudenberger *nr_apqns = _nr_apqns; 1009f2bbc96eSHarald Freudenberger 1010f2bbc96eSHarald Freudenberger out: 1011f2bbc96eSHarald Freudenberger kfree(_apqns); 1012f2bbc96eSHarald Freudenberger return rc; 1013f2bbc96eSHarald Freudenberger } 1014fb1136d6SIngo Franzki 1015fa6999e3SHarald Freudenberger static int pkey_keyblob2pkey3(const struct pkey_apqn *apqns, size_t nr_apqns, 1016fa6999e3SHarald Freudenberger const u8 *key, size_t keylen, u32 *protkeytype, 1017fa6999e3SHarald Freudenberger u8 *protkey, u32 *protkeylen) 1018fa6999e3SHarald Freudenberger { 1019fa6999e3SHarald Freudenberger int i, card, dom, rc; 1020fa6999e3SHarald Freudenberger struct keytoken_header *hdr = (struct keytoken_header *)key; 1021fa6999e3SHarald Freudenberger 1022fa6999e3SHarald Freudenberger /* check for at least one apqn given */ 1023fa6999e3SHarald Freudenberger if (!apqns || !nr_apqns) 1024fa6999e3SHarald Freudenberger return -EINVAL; 1025fa6999e3SHarald Freudenberger 1026fa6999e3SHarald Freudenberger if (keylen < sizeof(struct keytoken_header)) 1027fa6999e3SHarald Freudenberger return -EINVAL; 1028fa6999e3SHarald Freudenberger 1029fa6999e3SHarald Freudenberger if (hdr->type == TOKTYPE_NON_CCA 1030fa6999e3SHarald Freudenberger && hdr->version == TOKVER_EP11_AES_WITH_HEADER 1031fa6999e3SHarald Freudenberger && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 1032fa6999e3SHarald Freudenberger /* EP11 AES key blob with header */ 1033fa6999e3SHarald Freudenberger if (ep11_check_aes_key_with_hdr(debug_info, 3, key, keylen, 1)) 1034fa6999e3SHarald Freudenberger return -EINVAL; 1035fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA 1036fa6999e3SHarald Freudenberger && hdr->version == TOKVER_EP11_ECC_WITH_HEADER 1037fa6999e3SHarald Freudenberger && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) { 1038fa6999e3SHarald Freudenberger /* EP11 ECC key blob with header */ 1039fa6999e3SHarald Freudenberger if (ep11_check_ecc_key_with_hdr(debug_info, 3, key, keylen, 1)) 1040fa6999e3SHarald Freudenberger return -EINVAL; 1041fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA 1042fa6999e3SHarald Freudenberger && hdr->version == TOKVER_EP11_AES 1043fa6999e3SHarald Freudenberger && is_ep11_keyblob(key)) { 1044fa6999e3SHarald Freudenberger /* EP11 AES key blob with header in session field */ 1045fa6999e3SHarald Freudenberger if (ep11_check_aes_key(debug_info, 3, key, keylen, 1)) 1046fa6999e3SHarald Freudenberger return -EINVAL; 1047fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { 1048fa6999e3SHarald Freudenberger if (hdr->version == TOKVER_CCA_AES) { 1049fa6999e3SHarald Freudenberger /* CCA AES data key */ 1050fa6999e3SHarald Freudenberger if (keylen != sizeof(struct secaeskeytoken)) 1051fa6999e3SHarald Freudenberger return -EINVAL; 1052fa6999e3SHarald Freudenberger if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) 1053fa6999e3SHarald Freudenberger return -EINVAL; 1054fa6999e3SHarald Freudenberger } else if (hdr->version == TOKVER_CCA_VLSC) { 1055fa6999e3SHarald Freudenberger /* CCA AES cipher key */ 1056fa6999e3SHarald Freudenberger if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) 1057fa6999e3SHarald Freudenberger return -EINVAL; 1058fa6999e3SHarald Freudenberger if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) 1059fa6999e3SHarald Freudenberger return -EINVAL; 1060fa6999e3SHarald Freudenberger } else { 1061fa6999e3SHarald Freudenberger DEBUG_ERR("%s unknown CCA internal token version %d\n", 1062fa6999e3SHarald Freudenberger __func__, hdr->version); 1063fa6999e3SHarald Freudenberger return -EINVAL; 1064fa6999e3SHarald Freudenberger } 1065fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 1066fa6999e3SHarald Freudenberger /* CCA ECC (private) key */ 1067fa6999e3SHarald Freudenberger if (keylen < sizeof(struct eccprivkeytoken)) 1068fa6999e3SHarald Freudenberger return -EINVAL; 1069fa6999e3SHarald Freudenberger if (cca_check_sececckeytoken(debug_info, 3, key, keylen, 1)) 1070fa6999e3SHarald Freudenberger return -EINVAL; 1071fa6999e3SHarald Freudenberger } else if (hdr->type == TOKTYPE_NON_CCA) { 1072fa6999e3SHarald Freudenberger struct pkey_protkey pkey; 1073fa6999e3SHarald Freudenberger 1074fa6999e3SHarald Freudenberger rc = pkey_nonccatok2pkey(key, keylen, &pkey); 1075fa6999e3SHarald Freudenberger if (rc) 1076fa6999e3SHarald Freudenberger return rc; 1077fa6999e3SHarald Freudenberger memcpy(protkey, pkey.protkey, pkey.len); 1078fa6999e3SHarald Freudenberger *protkeylen = pkey.len; 1079fa6999e3SHarald Freudenberger *protkeytype = pkey.type; 1080fa6999e3SHarald Freudenberger return 0; 1081fa6999e3SHarald Freudenberger } else { 1082fa6999e3SHarald Freudenberger DEBUG_ERR("%s unknown/unsupported blob type %d\n", 1083fa6999e3SHarald Freudenberger __func__, hdr->type); 1084fa6999e3SHarald Freudenberger return -EINVAL; 1085fa6999e3SHarald Freudenberger } 1086fa6999e3SHarald Freudenberger 1087fa6999e3SHarald Freudenberger /* simple try all apqns from the list */ 1088fa6999e3SHarald Freudenberger for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 1089fa6999e3SHarald Freudenberger card = apqns[i].card; 1090fa6999e3SHarald Freudenberger dom = apqns[i].domain; 1091fa6999e3SHarald Freudenberger if (hdr->type == TOKTYPE_NON_CCA 1092fa6999e3SHarald Freudenberger && (hdr->version == TOKVER_EP11_AES_WITH_HEADER 1093fa6999e3SHarald Freudenberger || hdr->version == TOKVER_EP11_ECC_WITH_HEADER) 1094fa6999e3SHarald Freudenberger && is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) 1095fa6999e3SHarald Freudenberger rc = ep11_kblob2protkey(card, dom, key, hdr->len, 1096fa6999e3SHarald Freudenberger protkey, protkeylen, protkeytype); 1097fa6999e3SHarald Freudenberger else if (hdr->type == TOKTYPE_NON_CCA 1098fa6999e3SHarald Freudenberger && hdr->version == TOKVER_EP11_AES 1099fa6999e3SHarald Freudenberger && is_ep11_keyblob(key)) 1100fa6999e3SHarald Freudenberger rc = ep11_kblob2protkey(card, dom, key, hdr->len, 1101fa6999e3SHarald Freudenberger protkey, protkeylen, protkeytype); 1102fa6999e3SHarald Freudenberger else if (hdr->type == TOKTYPE_CCA_INTERNAL && 1103fa6999e3SHarald Freudenberger hdr->version == TOKVER_CCA_AES) 1104fa6999e3SHarald Freudenberger rc = cca_sec2protkey(card, dom, key, protkey, 1105fa6999e3SHarald Freudenberger protkeylen, protkeytype); 1106fa6999e3SHarald Freudenberger else if (hdr->type == TOKTYPE_CCA_INTERNAL && 1107fa6999e3SHarald Freudenberger hdr->version == TOKVER_CCA_VLSC) 1108fa6999e3SHarald Freudenberger rc = cca_cipher2protkey(card, dom, key, protkey, 1109fa6999e3SHarald Freudenberger protkeylen, protkeytype); 1110fa6999e3SHarald Freudenberger else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) 1111fa6999e3SHarald Freudenberger rc = cca_ecc2protkey(card, dom, key, protkey, 1112fa6999e3SHarald Freudenberger protkeylen, protkeytype); 1113fa6999e3SHarald Freudenberger else 1114fa6999e3SHarald Freudenberger return -EINVAL; 1115fa6999e3SHarald Freudenberger } 1116fa6999e3SHarald Freudenberger 1117fa6999e3SHarald Freudenberger return rc; 1118fa6999e3SHarald Freudenberger } 1119fa6999e3SHarald Freudenberger 1120fb1136d6SIngo Franzki /* 1121e80d4af0SHarald Freudenberger * File io functions 1122e80d4af0SHarald Freudenberger */ 1123e80d4af0SHarald Freudenberger 1124f2bbc96eSHarald Freudenberger static void *_copy_key_from_user(void __user *ukey, size_t keylen) 1125f2bbc96eSHarald Freudenberger { 1126f2bbc96eSHarald Freudenberger if (!ukey || keylen < MINKEYBLOBSIZE || keylen > KEYBLOBBUFSIZE) 1127f2bbc96eSHarald Freudenberger return ERR_PTR(-EINVAL); 1128f2bbc96eSHarald Freudenberger 11298b57e7c8SMarkus Elfring return memdup_user(ukey, keylen); 1130f2bbc96eSHarald Freudenberger } 1131f2bbc96eSHarald Freudenberger 1132f2bbc96eSHarald Freudenberger static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns) 1133f2bbc96eSHarald Freudenberger { 11348b57e7c8SMarkus Elfring if (!uapqns || nr_apqns == 0) 11358b57e7c8SMarkus Elfring return NULL; 1136f2bbc96eSHarald Freudenberger 11378b57e7c8SMarkus Elfring return memdup_user(uapqns, nr_apqns * sizeof(struct pkey_apqn)); 1138f2bbc96eSHarald Freudenberger } 1139f2bbc96eSHarald Freudenberger 1140e80d4af0SHarald Freudenberger static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, 1141e80d4af0SHarald Freudenberger unsigned long arg) 1142e80d4af0SHarald Freudenberger { 1143e80d4af0SHarald Freudenberger int rc; 1144e80d4af0SHarald Freudenberger 1145e80d4af0SHarald Freudenberger switch (cmd) { 1146e80d4af0SHarald Freudenberger case PKEY_GENSECK: { 1147e80d4af0SHarald Freudenberger struct pkey_genseck __user *ugs = (void __user *) arg; 1148e80d4af0SHarald Freudenberger struct pkey_genseck kgs; 1149e80d4af0SHarald Freudenberger 1150e80d4af0SHarald Freudenberger if (copy_from_user(&kgs, ugs, sizeof(kgs))) 1151e80d4af0SHarald Freudenberger return -EFAULT; 1152efc598e6SHarald Freudenberger rc = cca_genseckey(kgs.cardnr, kgs.domain, 1153efc598e6SHarald Freudenberger kgs.keytype, kgs.seckey.seckey); 1154efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_genseckey()=%d\n", __func__, rc); 1155e80d4af0SHarald Freudenberger if (rc) 1156e80d4af0SHarald Freudenberger break; 1157e80d4af0SHarald Freudenberger if (copy_to_user(ugs, &kgs, sizeof(kgs))) 1158e80d4af0SHarald Freudenberger return -EFAULT; 1159e80d4af0SHarald Freudenberger break; 1160e80d4af0SHarald Freudenberger } 1161e80d4af0SHarald Freudenberger case PKEY_CLR2SECK: { 1162e80d4af0SHarald Freudenberger struct pkey_clr2seck __user *ucs = (void __user *) arg; 1163e80d4af0SHarald Freudenberger struct pkey_clr2seck kcs; 1164e80d4af0SHarald Freudenberger 1165e80d4af0SHarald Freudenberger if (copy_from_user(&kcs, ucs, sizeof(kcs))) 1166e80d4af0SHarald Freudenberger return -EFAULT; 1167efc598e6SHarald Freudenberger rc = cca_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype, 1168efc598e6SHarald Freudenberger kcs.clrkey.clrkey, kcs.seckey.seckey); 1169efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_clr2seckey()=%d\n", __func__, rc); 1170e80d4af0SHarald Freudenberger if (rc) 1171e80d4af0SHarald Freudenberger break; 1172e80d4af0SHarald Freudenberger if (copy_to_user(ucs, &kcs, sizeof(kcs))) 1173e80d4af0SHarald Freudenberger return -EFAULT; 1174e80d4af0SHarald Freudenberger memzero_explicit(&kcs, sizeof(kcs)); 1175e80d4af0SHarald Freudenberger break; 1176e80d4af0SHarald Freudenberger } 1177e80d4af0SHarald Freudenberger case PKEY_SEC2PROTK: { 1178e80d4af0SHarald Freudenberger struct pkey_sec2protk __user *usp = (void __user *) arg; 1179e80d4af0SHarald Freudenberger struct pkey_sec2protk ksp; 1180e80d4af0SHarald Freudenberger 1181e80d4af0SHarald Freudenberger if (copy_from_user(&ksp, usp, sizeof(ksp))) 1182e80d4af0SHarald Freudenberger return -EFAULT; 1183efc598e6SHarald Freudenberger rc = cca_sec2protkey(ksp.cardnr, ksp.domain, 1184efc598e6SHarald Freudenberger ksp.seckey.seckey, ksp.protkey.protkey, 1185aab73d27SHarald Freudenberger &ksp.protkey.len, &ksp.protkey.type); 1186efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_sec2protkey()=%d\n", __func__, rc); 1187e80d4af0SHarald Freudenberger if (rc) 1188e80d4af0SHarald Freudenberger break; 1189e80d4af0SHarald Freudenberger if (copy_to_user(usp, &ksp, sizeof(ksp))) 1190e80d4af0SHarald Freudenberger return -EFAULT; 1191e80d4af0SHarald Freudenberger break; 1192e80d4af0SHarald Freudenberger } 1193e80d4af0SHarald Freudenberger case PKEY_CLR2PROTK: { 1194e80d4af0SHarald Freudenberger struct pkey_clr2protk __user *ucp = (void __user *) arg; 1195e80d4af0SHarald Freudenberger struct pkey_clr2protk kcp; 1196e80d4af0SHarald Freudenberger 1197e80d4af0SHarald Freudenberger if (copy_from_user(&kcp, ucp, sizeof(kcp))) 1198e80d4af0SHarald Freudenberger return -EFAULT; 1199e80d4af0SHarald Freudenberger rc = pkey_clr2protkey(kcp.keytype, 1200e80d4af0SHarald Freudenberger &kcp.clrkey, &kcp.protkey); 1201ac2b96f3SHarald Freudenberger DEBUG_DBG("%s pkey_clr2protkey()=%d\n", __func__, rc); 1202e80d4af0SHarald Freudenberger if (rc) 1203e80d4af0SHarald Freudenberger break; 1204e80d4af0SHarald Freudenberger if (copy_to_user(ucp, &kcp, sizeof(kcp))) 1205e80d4af0SHarald Freudenberger return -EFAULT; 1206e80d4af0SHarald Freudenberger memzero_explicit(&kcp, sizeof(kcp)); 1207e80d4af0SHarald Freudenberger break; 1208e80d4af0SHarald Freudenberger } 1209e80d4af0SHarald Freudenberger case PKEY_FINDCARD: { 1210e80d4af0SHarald Freudenberger struct pkey_findcard __user *ufc = (void __user *) arg; 1211e80d4af0SHarald Freudenberger struct pkey_findcard kfc; 1212e80d4af0SHarald Freudenberger 1213e80d4af0SHarald Freudenberger if (copy_from_user(&kfc, ufc, sizeof(kfc))) 1214e80d4af0SHarald Freudenberger return -EFAULT; 1215efc598e6SHarald Freudenberger rc = cca_findcard(kfc.seckey.seckey, 1216e80d4af0SHarald Freudenberger &kfc.cardnr, &kfc.domain, 1); 1217efc598e6SHarald Freudenberger DEBUG_DBG("%s cca_findcard()=%d\n", __func__, rc); 1218efc598e6SHarald Freudenberger if (rc < 0) 1219e80d4af0SHarald Freudenberger break; 1220e80d4af0SHarald Freudenberger if (copy_to_user(ufc, &kfc, sizeof(kfc))) 1221e80d4af0SHarald Freudenberger return -EFAULT; 1222e80d4af0SHarald Freudenberger break; 1223e80d4af0SHarald Freudenberger } 1224e80d4af0SHarald Freudenberger case PKEY_SKEY2PKEY: { 1225e80d4af0SHarald Freudenberger struct pkey_skey2pkey __user *usp = (void __user *) arg; 1226e80d4af0SHarald Freudenberger struct pkey_skey2pkey ksp; 1227e80d4af0SHarald Freudenberger 1228e80d4af0SHarald Freudenberger if (copy_from_user(&ksp, usp, sizeof(ksp))) 1229e80d4af0SHarald Freudenberger return -EFAULT; 1230f2bbc96eSHarald Freudenberger rc = pkey_skey2pkey(ksp.seckey.seckey, &ksp.protkey); 1231ac2b96f3SHarald Freudenberger DEBUG_DBG("%s pkey_skey2pkey()=%d\n", __func__, rc); 1232e80d4af0SHarald Freudenberger if (rc) 1233e80d4af0SHarald Freudenberger break; 1234e80d4af0SHarald Freudenberger if (copy_to_user(usp, &ksp, sizeof(ksp))) 1235e80d4af0SHarald Freudenberger return -EFAULT; 1236e80d4af0SHarald Freudenberger break; 1237e80d4af0SHarald Freudenberger } 1238e61a6134SHarald Freudenberger case PKEY_VERIFYKEY: { 1239e61a6134SHarald Freudenberger struct pkey_verifykey __user *uvk = (void __user *) arg; 1240e61a6134SHarald Freudenberger struct pkey_verifykey kvk; 1241e61a6134SHarald Freudenberger 1242e61a6134SHarald Freudenberger if (copy_from_user(&kvk, uvk, sizeof(kvk))) 1243e61a6134SHarald Freudenberger return -EFAULT; 1244e61a6134SHarald Freudenberger rc = pkey_verifykey(&kvk.seckey, &kvk.cardnr, &kvk.domain, 1245e61a6134SHarald Freudenberger &kvk.keysize, &kvk.attributes); 1246ac2b96f3SHarald Freudenberger DEBUG_DBG("%s pkey_verifykey()=%d\n", __func__, rc); 1247e61a6134SHarald Freudenberger if (rc) 1248e61a6134SHarald Freudenberger break; 1249e61a6134SHarald Freudenberger if (copy_to_user(uvk, &kvk, sizeof(kvk))) 1250e61a6134SHarald Freudenberger return -EFAULT; 1251e61a6134SHarald Freudenberger break; 1252e61a6134SHarald Freudenberger } 1253a45a5c7dSIngo Franzki case PKEY_GENPROTK: { 1254a45a5c7dSIngo Franzki struct pkey_genprotk __user *ugp = (void __user *) arg; 1255a45a5c7dSIngo Franzki struct pkey_genprotk kgp; 1256a45a5c7dSIngo Franzki 1257a45a5c7dSIngo Franzki if (copy_from_user(&kgp, ugp, sizeof(kgp))) 1258a45a5c7dSIngo Franzki return -EFAULT; 1259a45a5c7dSIngo Franzki rc = pkey_genprotkey(kgp.keytype, &kgp.protkey); 1260a45a5c7dSIngo Franzki DEBUG_DBG("%s pkey_genprotkey()=%d\n", __func__, rc); 1261a45a5c7dSIngo Franzki if (rc) 1262a45a5c7dSIngo Franzki break; 1263a45a5c7dSIngo Franzki if (copy_to_user(ugp, &kgp, sizeof(kgp))) 1264a45a5c7dSIngo Franzki return -EFAULT; 1265a45a5c7dSIngo Franzki break; 1266a45a5c7dSIngo Franzki } 1267cb26b9ffSIngo Franzki case PKEY_VERIFYPROTK: { 1268cb26b9ffSIngo Franzki struct pkey_verifyprotk __user *uvp = (void __user *) arg; 1269cb26b9ffSIngo Franzki struct pkey_verifyprotk kvp; 1270cb26b9ffSIngo Franzki 1271cb26b9ffSIngo Franzki if (copy_from_user(&kvp, uvp, sizeof(kvp))) 1272cb26b9ffSIngo Franzki return -EFAULT; 1273cb26b9ffSIngo Franzki rc = pkey_verifyprotkey(&kvp.protkey); 1274cb26b9ffSIngo Franzki DEBUG_DBG("%s pkey_verifyprotkey()=%d\n", __func__, rc); 1275cb26b9ffSIngo Franzki break; 1276cb26b9ffSIngo Franzki } 1277fb1136d6SIngo Franzki case PKEY_KBLOB2PROTK: { 1278fb1136d6SIngo Franzki struct pkey_kblob2pkey __user *utp = (void __user *) arg; 1279fb1136d6SIngo Franzki struct pkey_kblob2pkey ktp; 1280183cb469SHarald Freudenberger u8 *kkey; 1281fb1136d6SIngo Franzki 1282fb1136d6SIngo Franzki if (copy_from_user(&ktp, utp, sizeof(ktp))) 1283fb1136d6SIngo Franzki return -EFAULT; 1284f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(ktp.key, ktp.keylen); 1285f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) 1286f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1287fb1136d6SIngo Franzki rc = pkey_keyblob2pkey(kkey, ktp.keylen, &ktp.protkey); 1288fb1136d6SIngo Franzki DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n", __func__, rc); 1289fb1136d6SIngo Franzki kfree(kkey); 1290fb1136d6SIngo Franzki if (rc) 1291fb1136d6SIngo Franzki break; 1292fb1136d6SIngo Franzki if (copy_to_user(utp, &ktp, sizeof(ktp))) 1293fb1136d6SIngo Franzki return -EFAULT; 1294fb1136d6SIngo Franzki break; 1295fb1136d6SIngo Franzki } 1296f2bbc96eSHarald Freudenberger case PKEY_GENSECK2: { 1297f2bbc96eSHarald Freudenberger struct pkey_genseck2 __user *ugs = (void __user *) arg; 1298f2bbc96eSHarald Freudenberger struct pkey_genseck2 kgs; 1299f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns; 1300f2bbc96eSHarald Freudenberger size_t klen = KEYBLOBBUFSIZE; 1301f2bbc96eSHarald Freudenberger u8 *kkey; 1302f2bbc96eSHarald Freudenberger 1303f2bbc96eSHarald Freudenberger if (copy_from_user(&kgs, ugs, sizeof(kgs))) 1304f2bbc96eSHarald Freudenberger return -EFAULT; 1305f2bbc96eSHarald Freudenberger apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries); 1306f2bbc96eSHarald Freudenberger if (IS_ERR(apqns)) 1307f2bbc96eSHarald Freudenberger return PTR_ERR(apqns); 1308f2bbc96eSHarald Freudenberger kkey = kmalloc(klen, GFP_KERNEL); 1309f2bbc96eSHarald Freudenberger if (!kkey) { 1310f2bbc96eSHarald Freudenberger kfree(apqns); 1311f2bbc96eSHarald Freudenberger return -ENOMEM; 1312f2bbc96eSHarald Freudenberger } 1313f2bbc96eSHarald Freudenberger rc = pkey_genseckey2(apqns, kgs.apqn_entries, 1314f2bbc96eSHarald Freudenberger kgs.type, kgs.size, kgs.keygenflags, 1315f2bbc96eSHarald Freudenberger kkey, &klen); 1316f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_genseckey2()=%d\n", __func__, rc); 1317f2bbc96eSHarald Freudenberger kfree(apqns); 1318f2bbc96eSHarald Freudenberger if (rc) { 1319f2bbc96eSHarald Freudenberger kfree(kkey); 1320f2bbc96eSHarald Freudenberger break; 1321f2bbc96eSHarald Freudenberger } 1322f2bbc96eSHarald Freudenberger if (kgs.key) { 1323f2bbc96eSHarald Freudenberger if (kgs.keylen < klen) { 1324f2bbc96eSHarald Freudenberger kfree(kkey); 1325f2bbc96eSHarald Freudenberger return -EINVAL; 1326f2bbc96eSHarald Freudenberger } 1327f2bbc96eSHarald Freudenberger if (copy_to_user(kgs.key, kkey, klen)) { 1328f2bbc96eSHarald Freudenberger kfree(kkey); 1329f2bbc96eSHarald Freudenberger return -EFAULT; 1330f2bbc96eSHarald Freudenberger } 1331f2bbc96eSHarald Freudenberger } 1332f2bbc96eSHarald Freudenberger kgs.keylen = klen; 1333f2bbc96eSHarald Freudenberger if (copy_to_user(ugs, &kgs, sizeof(kgs))) 1334f2bbc96eSHarald Freudenberger rc = -EFAULT; 1335f2bbc96eSHarald Freudenberger kfree(kkey); 1336f2bbc96eSHarald Freudenberger break; 1337f2bbc96eSHarald Freudenberger } 1338f2bbc96eSHarald Freudenberger case PKEY_CLR2SECK2: { 1339f2bbc96eSHarald Freudenberger struct pkey_clr2seck2 __user *ucs = (void __user *) arg; 1340f2bbc96eSHarald Freudenberger struct pkey_clr2seck2 kcs; 1341f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns; 1342f2bbc96eSHarald Freudenberger size_t klen = KEYBLOBBUFSIZE; 1343f2bbc96eSHarald Freudenberger u8 *kkey; 1344f2bbc96eSHarald Freudenberger 1345f2bbc96eSHarald Freudenberger if (copy_from_user(&kcs, ucs, sizeof(kcs))) 1346f2bbc96eSHarald Freudenberger return -EFAULT; 1347f2bbc96eSHarald Freudenberger apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); 1348f2bbc96eSHarald Freudenberger if (IS_ERR(apqns)) 1349f2bbc96eSHarald Freudenberger return PTR_ERR(apqns); 1350f2bbc96eSHarald Freudenberger kkey = kmalloc(klen, GFP_KERNEL); 1351f2bbc96eSHarald Freudenberger if (!kkey) { 1352f2bbc96eSHarald Freudenberger kfree(apqns); 1353f2bbc96eSHarald Freudenberger return -ENOMEM; 1354f2bbc96eSHarald Freudenberger } 1355f2bbc96eSHarald Freudenberger rc = pkey_clr2seckey2(apqns, kcs.apqn_entries, 1356f2bbc96eSHarald Freudenberger kcs.type, kcs.size, kcs.keygenflags, 1357f2bbc96eSHarald Freudenberger kcs.clrkey.clrkey, kkey, &klen); 1358f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_clr2seckey2()=%d\n", __func__, rc); 1359f2bbc96eSHarald Freudenberger kfree(apqns); 1360f2bbc96eSHarald Freudenberger if (rc) { 1361f2bbc96eSHarald Freudenberger kfree(kkey); 1362f2bbc96eSHarald Freudenberger break; 1363f2bbc96eSHarald Freudenberger } 1364f2bbc96eSHarald Freudenberger if (kcs.key) { 1365f2bbc96eSHarald Freudenberger if (kcs.keylen < klen) { 1366f2bbc96eSHarald Freudenberger kfree(kkey); 1367f2bbc96eSHarald Freudenberger return -EINVAL; 1368f2bbc96eSHarald Freudenberger } 1369f2bbc96eSHarald Freudenberger if (copy_to_user(kcs.key, kkey, klen)) { 1370f2bbc96eSHarald Freudenberger kfree(kkey); 1371f2bbc96eSHarald Freudenberger return -EFAULT; 1372f2bbc96eSHarald Freudenberger } 1373f2bbc96eSHarald Freudenberger } 1374f2bbc96eSHarald Freudenberger kcs.keylen = klen; 1375f2bbc96eSHarald Freudenberger if (copy_to_user(ucs, &kcs, sizeof(kcs))) 1376f2bbc96eSHarald Freudenberger rc = -EFAULT; 1377f2bbc96eSHarald Freudenberger memzero_explicit(&kcs, sizeof(kcs)); 1378f2bbc96eSHarald Freudenberger kfree(kkey); 1379f2bbc96eSHarald Freudenberger break; 1380f2bbc96eSHarald Freudenberger } 1381f2bbc96eSHarald Freudenberger case PKEY_VERIFYKEY2: { 1382f2bbc96eSHarald Freudenberger struct pkey_verifykey2 __user *uvk = (void __user *) arg; 1383f2bbc96eSHarald Freudenberger struct pkey_verifykey2 kvk; 1384f2bbc96eSHarald Freudenberger u8 *kkey; 1385f2bbc96eSHarald Freudenberger 1386f2bbc96eSHarald Freudenberger if (copy_from_user(&kvk, uvk, sizeof(kvk))) 1387f2bbc96eSHarald Freudenberger return -EFAULT; 1388f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(kvk.key, kvk.keylen); 1389f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) 1390f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1391f2bbc96eSHarald Freudenberger rc = pkey_verifykey2(kkey, kvk.keylen, 1392f2bbc96eSHarald Freudenberger &kvk.cardnr, &kvk.domain, 1393f2bbc96eSHarald Freudenberger &kvk.type, &kvk.size, &kvk.flags); 1394f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_verifykey2()=%d\n", __func__, rc); 1395f2bbc96eSHarald Freudenberger kfree(kkey); 1396f2bbc96eSHarald Freudenberger if (rc) 1397f2bbc96eSHarald Freudenberger break; 1398f2bbc96eSHarald Freudenberger if (copy_to_user(uvk, &kvk, sizeof(kvk))) 1399f2bbc96eSHarald Freudenberger return -EFAULT; 1400f2bbc96eSHarald Freudenberger break; 1401f2bbc96eSHarald Freudenberger } 1402f2bbc96eSHarald Freudenberger case PKEY_KBLOB2PROTK2: { 1403f2bbc96eSHarald Freudenberger struct pkey_kblob2pkey2 __user *utp = (void __user *) arg; 1404f2bbc96eSHarald Freudenberger struct pkey_kblob2pkey2 ktp; 1405f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns = NULL; 1406f2bbc96eSHarald Freudenberger u8 *kkey; 1407f2bbc96eSHarald Freudenberger 1408f2bbc96eSHarald Freudenberger if (copy_from_user(&ktp, utp, sizeof(ktp))) 1409f2bbc96eSHarald Freudenberger return -EFAULT; 1410f2bbc96eSHarald Freudenberger apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); 1411f2bbc96eSHarald Freudenberger if (IS_ERR(apqns)) 1412f2bbc96eSHarald Freudenberger return PTR_ERR(apqns); 1413f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(ktp.key, ktp.keylen); 1414f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) { 1415f2bbc96eSHarald Freudenberger kfree(apqns); 1416f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1417f2bbc96eSHarald Freudenberger } 1418f2bbc96eSHarald Freudenberger rc = pkey_keyblob2pkey2(apqns, ktp.apqn_entries, 1419f2bbc96eSHarald Freudenberger kkey, ktp.keylen, &ktp.protkey); 1420f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_keyblob2pkey2()=%d\n", __func__, rc); 1421f2bbc96eSHarald Freudenberger kfree(apqns); 1422f2bbc96eSHarald Freudenberger kfree(kkey); 1423f2bbc96eSHarald Freudenberger if (rc) 1424f2bbc96eSHarald Freudenberger break; 1425f2bbc96eSHarald Freudenberger if (copy_to_user(utp, &ktp, sizeof(ktp))) 1426f2bbc96eSHarald Freudenberger return -EFAULT; 1427f2bbc96eSHarald Freudenberger break; 1428f2bbc96eSHarald Freudenberger } 1429f2bbc96eSHarald Freudenberger case PKEY_APQNS4K: { 1430f2bbc96eSHarald Freudenberger struct pkey_apqns4key __user *uak = (void __user *) arg; 1431f2bbc96eSHarald Freudenberger struct pkey_apqns4key kak; 1432f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns = NULL; 1433f2bbc96eSHarald Freudenberger size_t nr_apqns, len; 1434f2bbc96eSHarald Freudenberger u8 *kkey; 1435f2bbc96eSHarald Freudenberger 1436f2bbc96eSHarald Freudenberger if (copy_from_user(&kak, uak, sizeof(kak))) 1437f2bbc96eSHarald Freudenberger return -EFAULT; 1438f2bbc96eSHarald Freudenberger nr_apqns = kak.apqn_entries; 1439f2bbc96eSHarald Freudenberger if (nr_apqns) { 1440f2bbc96eSHarald Freudenberger apqns = kmalloc_array(nr_apqns, 1441f2bbc96eSHarald Freudenberger sizeof(struct pkey_apqn), 1442f2bbc96eSHarald Freudenberger GFP_KERNEL); 1443f2bbc96eSHarald Freudenberger if (!apqns) 1444f2bbc96eSHarald Freudenberger return -ENOMEM; 1445f2bbc96eSHarald Freudenberger } 1446f2bbc96eSHarald Freudenberger kkey = _copy_key_from_user(kak.key, kak.keylen); 1447f2bbc96eSHarald Freudenberger if (IS_ERR(kkey)) { 1448f2bbc96eSHarald Freudenberger kfree(apqns); 1449f2bbc96eSHarald Freudenberger return PTR_ERR(kkey); 1450f2bbc96eSHarald Freudenberger } 1451f2bbc96eSHarald Freudenberger rc = pkey_apqns4key(kkey, kak.keylen, kak.flags, 1452f2bbc96eSHarald Freudenberger apqns, &nr_apqns); 1453f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_apqns4key()=%d\n", __func__, rc); 1454f2bbc96eSHarald Freudenberger kfree(kkey); 1455f2bbc96eSHarald Freudenberger if (rc && rc != -ENOSPC) { 1456f2bbc96eSHarald Freudenberger kfree(apqns); 1457f2bbc96eSHarald Freudenberger break; 1458f2bbc96eSHarald Freudenberger } 1459f2bbc96eSHarald Freudenberger if (!rc && kak.apqns) { 1460f2bbc96eSHarald Freudenberger if (nr_apqns > kak.apqn_entries) { 1461f2bbc96eSHarald Freudenberger kfree(apqns); 1462f2bbc96eSHarald Freudenberger return -EINVAL; 1463f2bbc96eSHarald Freudenberger } 1464f2bbc96eSHarald Freudenberger len = nr_apqns * sizeof(struct pkey_apqn); 1465f2bbc96eSHarald Freudenberger if (len) { 1466f2bbc96eSHarald Freudenberger if (copy_to_user(kak.apqns, apqns, len)) { 1467f2bbc96eSHarald Freudenberger kfree(apqns); 1468f2bbc96eSHarald Freudenberger return -EFAULT; 1469f2bbc96eSHarald Freudenberger } 1470f2bbc96eSHarald Freudenberger } 1471f2bbc96eSHarald Freudenberger } 1472f2bbc96eSHarald Freudenberger kak.apqn_entries = nr_apqns; 1473f2bbc96eSHarald Freudenberger if (copy_to_user(uak, &kak, sizeof(kak))) 1474f2bbc96eSHarald Freudenberger rc = -EFAULT; 1475f2bbc96eSHarald Freudenberger kfree(apqns); 1476f2bbc96eSHarald Freudenberger break; 1477f2bbc96eSHarald Freudenberger } 1478f2bbc96eSHarald Freudenberger case PKEY_APQNS4KT: { 1479f2bbc96eSHarald Freudenberger struct pkey_apqns4keytype __user *uat = (void __user *) arg; 1480f2bbc96eSHarald Freudenberger struct pkey_apqns4keytype kat; 1481f2bbc96eSHarald Freudenberger struct pkey_apqn *apqns = NULL; 1482f2bbc96eSHarald Freudenberger size_t nr_apqns, len; 1483f2bbc96eSHarald Freudenberger 1484f2bbc96eSHarald Freudenberger if (copy_from_user(&kat, uat, sizeof(kat))) 1485f2bbc96eSHarald Freudenberger return -EFAULT; 1486f2bbc96eSHarald Freudenberger nr_apqns = kat.apqn_entries; 1487f2bbc96eSHarald Freudenberger if (nr_apqns) { 1488f2bbc96eSHarald Freudenberger apqns = kmalloc_array(nr_apqns, 1489f2bbc96eSHarald Freudenberger sizeof(struct pkey_apqn), 1490f2bbc96eSHarald Freudenberger GFP_KERNEL); 1491f2bbc96eSHarald Freudenberger if (!apqns) 1492f2bbc96eSHarald Freudenberger return -ENOMEM; 1493f2bbc96eSHarald Freudenberger } 1494f2bbc96eSHarald Freudenberger rc = pkey_apqns4keytype(kat.type, kat.cur_mkvp, kat.alt_mkvp, 1495f2bbc96eSHarald Freudenberger kat.flags, apqns, &nr_apqns); 1496f2bbc96eSHarald Freudenberger DEBUG_DBG("%s pkey_apqns4keytype()=%d\n", __func__, rc); 1497f2bbc96eSHarald Freudenberger if (rc && rc != -ENOSPC) { 1498f2bbc96eSHarald Freudenberger kfree(apqns); 1499f2bbc96eSHarald Freudenberger break; 1500f2bbc96eSHarald Freudenberger } 1501f2bbc96eSHarald Freudenberger if (!rc && kat.apqns) { 1502f2bbc96eSHarald Freudenberger if (nr_apqns > kat.apqn_entries) { 1503f2bbc96eSHarald Freudenberger kfree(apqns); 1504f2bbc96eSHarald Freudenberger return -EINVAL; 1505f2bbc96eSHarald Freudenberger } 1506f2bbc96eSHarald Freudenberger len = nr_apqns * sizeof(struct pkey_apqn); 1507f2bbc96eSHarald Freudenberger if (len) { 1508f2bbc96eSHarald Freudenberger if (copy_to_user(kat.apqns, apqns, len)) { 1509f2bbc96eSHarald Freudenberger kfree(apqns); 1510f2bbc96eSHarald Freudenberger return -EFAULT; 1511f2bbc96eSHarald Freudenberger } 1512f2bbc96eSHarald Freudenberger } 1513f2bbc96eSHarald Freudenberger } 1514f2bbc96eSHarald Freudenberger kat.apqn_entries = nr_apqns; 1515f2bbc96eSHarald Freudenberger if (copy_to_user(uat, &kat, sizeof(kat))) 1516f2bbc96eSHarald Freudenberger rc = -EFAULT; 1517f2bbc96eSHarald Freudenberger kfree(apqns); 1518f2bbc96eSHarald Freudenberger break; 1519f2bbc96eSHarald Freudenberger } 1520fa6999e3SHarald Freudenberger case PKEY_KBLOB2PROTK3: { 1521fa6999e3SHarald Freudenberger struct pkey_kblob2pkey3 __user *utp = (void __user *) arg; 1522fa6999e3SHarald Freudenberger struct pkey_kblob2pkey3 ktp; 1523fa6999e3SHarald Freudenberger struct pkey_apqn *apqns = NULL; 1524fa6999e3SHarald Freudenberger u32 protkeylen = PROTKEYBLOBBUFSIZE; 1525fa6999e3SHarald Freudenberger u8 *kkey, *protkey; 1526fa6999e3SHarald Freudenberger 1527fa6999e3SHarald Freudenberger if (copy_from_user(&ktp, utp, sizeof(ktp))) 1528fa6999e3SHarald Freudenberger return -EFAULT; 1529fa6999e3SHarald Freudenberger apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); 1530fa6999e3SHarald Freudenberger if (IS_ERR(apqns)) 1531fa6999e3SHarald Freudenberger return PTR_ERR(apqns); 1532fa6999e3SHarald Freudenberger kkey = _copy_key_from_user(ktp.key, ktp.keylen); 1533fa6999e3SHarald Freudenberger if (IS_ERR(kkey)) { 1534fa6999e3SHarald Freudenberger kfree(apqns); 1535fa6999e3SHarald Freudenberger return PTR_ERR(kkey); 1536fa6999e3SHarald Freudenberger } 1537fa6999e3SHarald Freudenberger protkey = kmalloc(protkeylen, GFP_KERNEL); 1538fa6999e3SHarald Freudenberger if (!protkey) { 1539fa6999e3SHarald Freudenberger kfree(apqns); 1540fa6999e3SHarald Freudenberger kfree(kkey); 1541fa6999e3SHarald Freudenberger return -ENOMEM; 1542fa6999e3SHarald Freudenberger } 1543fa6999e3SHarald Freudenberger rc = pkey_keyblob2pkey3(apqns, ktp.apqn_entries, kkey, 1544fa6999e3SHarald Freudenberger ktp.keylen, &ktp.pkeytype, 1545fa6999e3SHarald Freudenberger protkey, &protkeylen); 1546fa6999e3SHarald Freudenberger DEBUG_DBG("%s pkey_keyblob2pkey3()=%d\n", __func__, rc); 1547fa6999e3SHarald Freudenberger kfree(apqns); 1548fa6999e3SHarald Freudenberger kfree(kkey); 1549fa6999e3SHarald Freudenberger if (rc) { 1550fa6999e3SHarald Freudenberger kfree(protkey); 1551fa6999e3SHarald Freudenberger break; 1552fa6999e3SHarald Freudenberger } 1553fa6999e3SHarald Freudenberger if (ktp.pkey && ktp.pkeylen) { 1554fa6999e3SHarald Freudenberger if (protkeylen > ktp.pkeylen) { 1555fa6999e3SHarald Freudenberger kfree(protkey); 1556fa6999e3SHarald Freudenberger return -EINVAL; 1557fa6999e3SHarald Freudenberger } 1558fa6999e3SHarald Freudenberger if (copy_to_user(ktp.pkey, protkey, protkeylen)) { 1559fa6999e3SHarald Freudenberger kfree(protkey); 1560fa6999e3SHarald Freudenberger return -EFAULT; 1561fa6999e3SHarald Freudenberger } 1562fa6999e3SHarald Freudenberger } 1563fa6999e3SHarald Freudenberger kfree(protkey); 1564fa6999e3SHarald Freudenberger ktp.pkeylen = protkeylen; 1565fa6999e3SHarald Freudenberger if (copy_to_user(utp, &ktp, sizeof(ktp))) 1566fa6999e3SHarald Freudenberger return -EFAULT; 1567fa6999e3SHarald Freudenberger break; 1568fa6999e3SHarald Freudenberger } 1569e80d4af0SHarald Freudenberger default: 1570e80d4af0SHarald Freudenberger /* unknown/unsupported ioctl cmd */ 1571e80d4af0SHarald Freudenberger return -ENOTTY; 1572e80d4af0SHarald Freudenberger } 1573e80d4af0SHarald Freudenberger 1574e80d4af0SHarald Freudenberger return rc; 1575e80d4af0SHarald Freudenberger } 1576e80d4af0SHarald Freudenberger 1577e80d4af0SHarald Freudenberger /* 1578e80d4af0SHarald Freudenberger * Sysfs and file io operations 1579e80d4af0SHarald Freudenberger */ 1580d632c047SIngo Franzki 1581d632c047SIngo Franzki /* 1582d632c047SIngo Franzki * Sysfs attribute read function for all protected key binary attributes. 1583d632c047SIngo Franzki * The implementation can not deal with partial reads, because a new random 1584d632c047SIngo Franzki * protected key blob is generated with each read. In case of partial reads 1585d632c047SIngo Franzki * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 1586d632c047SIngo Franzki */ 1587d632c047SIngo Franzki static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf, 1588d632c047SIngo Franzki loff_t off, size_t count) 1589d632c047SIngo Franzki { 1590d632c047SIngo Franzki struct protaeskeytoken protkeytoken; 1591d632c047SIngo Franzki struct pkey_protkey protkey; 1592d632c047SIngo Franzki int rc; 1593d632c047SIngo Franzki 1594d632c047SIngo Franzki if (off != 0 || count < sizeof(protkeytoken)) 1595d632c047SIngo Franzki return -EINVAL; 1596d632c047SIngo Franzki if (is_xts) 1597d632c047SIngo Franzki if (count < 2 * sizeof(protkeytoken)) 1598d632c047SIngo Franzki return -EINVAL; 1599d632c047SIngo Franzki 1600d632c047SIngo Franzki memset(&protkeytoken, 0, sizeof(protkeytoken)); 1601d632c047SIngo Franzki protkeytoken.type = TOKTYPE_NON_CCA; 1602d632c047SIngo Franzki protkeytoken.version = TOKVER_PROTECTED_KEY; 1603d632c047SIngo Franzki protkeytoken.keytype = keytype; 1604d632c047SIngo Franzki 1605d632c047SIngo Franzki rc = pkey_genprotkey(protkeytoken.keytype, &protkey); 1606d632c047SIngo Franzki if (rc) 1607d632c047SIngo Franzki return rc; 1608d632c047SIngo Franzki 1609d632c047SIngo Franzki protkeytoken.len = protkey.len; 1610d632c047SIngo Franzki memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len); 1611d632c047SIngo Franzki 1612d632c047SIngo Franzki memcpy(buf, &protkeytoken, sizeof(protkeytoken)); 1613d632c047SIngo Franzki 1614d632c047SIngo Franzki if (is_xts) { 1615d632c047SIngo Franzki rc = pkey_genprotkey(protkeytoken.keytype, &protkey); 1616d632c047SIngo Franzki if (rc) 1617d632c047SIngo Franzki return rc; 1618d632c047SIngo Franzki 1619d632c047SIngo Franzki protkeytoken.len = protkey.len; 1620d632c047SIngo Franzki memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len); 1621d632c047SIngo Franzki 1622d632c047SIngo Franzki memcpy(buf + sizeof(protkeytoken), &protkeytoken, 1623d632c047SIngo Franzki sizeof(protkeytoken)); 1624d632c047SIngo Franzki 1625d632c047SIngo Franzki return 2 * sizeof(protkeytoken); 1626d632c047SIngo Franzki } 1627d632c047SIngo Franzki 1628d632c047SIngo Franzki return sizeof(protkeytoken); 1629d632c047SIngo Franzki } 1630d632c047SIngo Franzki 1631d632c047SIngo Franzki static ssize_t protkey_aes_128_read(struct file *filp, 1632d632c047SIngo Franzki struct kobject *kobj, 1633d632c047SIngo Franzki struct bin_attribute *attr, 1634d632c047SIngo Franzki char *buf, loff_t off, 1635d632c047SIngo Franzki size_t count) 1636d632c047SIngo Franzki { 1637d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf, 1638d632c047SIngo Franzki off, count); 1639d632c047SIngo Franzki } 1640d632c047SIngo Franzki 1641d632c047SIngo Franzki static ssize_t protkey_aes_192_read(struct file *filp, 1642d632c047SIngo Franzki struct kobject *kobj, 1643d632c047SIngo Franzki struct bin_attribute *attr, 1644d632c047SIngo Franzki char *buf, loff_t off, 1645d632c047SIngo Franzki size_t count) 1646d632c047SIngo Franzki { 1647d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf, 1648d632c047SIngo Franzki off, count); 1649d632c047SIngo Franzki } 1650d632c047SIngo Franzki 1651d632c047SIngo Franzki static ssize_t protkey_aes_256_read(struct file *filp, 1652d632c047SIngo Franzki struct kobject *kobj, 1653d632c047SIngo Franzki struct bin_attribute *attr, 1654d632c047SIngo Franzki char *buf, loff_t off, 1655d632c047SIngo Franzki size_t count) 1656d632c047SIngo Franzki { 1657d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf, 1658d632c047SIngo Franzki off, count); 1659d632c047SIngo Franzki } 1660d632c047SIngo Franzki 1661d632c047SIngo Franzki static ssize_t protkey_aes_128_xts_read(struct file *filp, 1662d632c047SIngo Franzki struct kobject *kobj, 1663d632c047SIngo Franzki struct bin_attribute *attr, 1664d632c047SIngo Franzki char *buf, loff_t off, 1665d632c047SIngo Franzki size_t count) 1666d632c047SIngo Franzki { 1667d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf, 1668d632c047SIngo Franzki off, count); 1669d632c047SIngo Franzki } 1670d632c047SIngo Franzki 1671d632c047SIngo Franzki static ssize_t protkey_aes_256_xts_read(struct file *filp, 1672d632c047SIngo Franzki struct kobject *kobj, 1673d632c047SIngo Franzki struct bin_attribute *attr, 1674d632c047SIngo Franzki char *buf, loff_t off, 1675d632c047SIngo Franzki size_t count) 1676d632c047SIngo Franzki { 1677d632c047SIngo Franzki return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf, 1678d632c047SIngo Franzki off, count); 1679d632c047SIngo Franzki } 1680d632c047SIngo Franzki 1681d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken)); 1682d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken)); 1683d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken)); 1684d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken)); 1685d632c047SIngo Franzki static BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken)); 1686d632c047SIngo Franzki 1687d632c047SIngo Franzki static struct bin_attribute *protkey_attrs[] = { 1688d632c047SIngo Franzki &bin_attr_protkey_aes_128, 1689d632c047SIngo Franzki &bin_attr_protkey_aes_192, 1690d632c047SIngo Franzki &bin_attr_protkey_aes_256, 1691d632c047SIngo Franzki &bin_attr_protkey_aes_128_xts, 1692d632c047SIngo Franzki &bin_attr_protkey_aes_256_xts, 1693d632c047SIngo Franzki NULL 1694d632c047SIngo Franzki }; 1695d632c047SIngo Franzki 1696d632c047SIngo Franzki static struct attribute_group protkey_attr_group = { 1697d632c047SIngo Franzki .name = "protkey", 1698d632c047SIngo Franzki .bin_attrs = protkey_attrs, 1699d632c047SIngo Franzki }; 1700d632c047SIngo Franzki 1701af504452SIngo Franzki /* 1702af504452SIngo Franzki * Sysfs attribute read function for all secure key ccadata binary attributes. 1703af504452SIngo Franzki * The implementation can not deal with partial reads, because a new random 1704af504452SIngo Franzki * protected key blob is generated with each read. In case of partial reads 1705af504452SIngo Franzki * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 1706af504452SIngo Franzki */ 1707af504452SIngo Franzki static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf, 1708af504452SIngo Franzki loff_t off, size_t count) 1709af504452SIngo Franzki { 1710af504452SIngo Franzki int rc; 1711efc598e6SHarald Freudenberger struct pkey_seckey *seckey = (struct pkey_seckey *) buf; 1712af504452SIngo Franzki 1713af504452SIngo Franzki if (off != 0 || count < sizeof(struct secaeskeytoken)) 1714af504452SIngo Franzki return -EINVAL; 1715af504452SIngo Franzki if (is_xts) 1716af504452SIngo Franzki if (count < 2 * sizeof(struct secaeskeytoken)) 1717af504452SIngo Franzki return -EINVAL; 1718af504452SIngo Franzki 1719efc598e6SHarald Freudenberger rc = cca_genseckey(-1, -1, keytype, seckey->seckey); 1720af504452SIngo Franzki if (rc) 1721af504452SIngo Franzki return rc; 1722af504452SIngo Franzki 1723af504452SIngo Franzki if (is_xts) { 1724efc598e6SHarald Freudenberger seckey++; 1725efc598e6SHarald Freudenberger rc = cca_genseckey(-1, -1, keytype, seckey->seckey); 1726af504452SIngo Franzki if (rc) 1727af504452SIngo Franzki return rc; 1728af504452SIngo Franzki 1729af504452SIngo Franzki return 2 * sizeof(struct secaeskeytoken); 1730af504452SIngo Franzki } 1731af504452SIngo Franzki 1732af504452SIngo Franzki return sizeof(struct secaeskeytoken); 1733af504452SIngo Franzki } 1734af504452SIngo Franzki 1735af504452SIngo Franzki static ssize_t ccadata_aes_128_read(struct file *filp, 1736af504452SIngo Franzki struct kobject *kobj, 1737af504452SIngo Franzki struct bin_attribute *attr, 1738af504452SIngo Franzki char *buf, loff_t off, 1739af504452SIngo Franzki size_t count) 1740af504452SIngo Franzki { 1741af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf, 1742af504452SIngo Franzki off, count); 1743af504452SIngo Franzki } 1744af504452SIngo Franzki 1745af504452SIngo Franzki static ssize_t ccadata_aes_192_read(struct file *filp, 1746af504452SIngo Franzki struct kobject *kobj, 1747af504452SIngo Franzki struct bin_attribute *attr, 1748af504452SIngo Franzki char *buf, loff_t off, 1749af504452SIngo Franzki size_t count) 1750af504452SIngo Franzki { 1751af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf, 1752af504452SIngo Franzki off, count); 1753af504452SIngo Franzki } 1754af504452SIngo Franzki 1755af504452SIngo Franzki static ssize_t ccadata_aes_256_read(struct file *filp, 1756af504452SIngo Franzki struct kobject *kobj, 1757af504452SIngo Franzki struct bin_attribute *attr, 1758af504452SIngo Franzki char *buf, loff_t off, 1759af504452SIngo Franzki size_t count) 1760af504452SIngo Franzki { 1761af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf, 1762af504452SIngo Franzki off, count); 1763af504452SIngo Franzki } 1764af504452SIngo Franzki 1765af504452SIngo Franzki static ssize_t ccadata_aes_128_xts_read(struct file *filp, 1766af504452SIngo Franzki struct kobject *kobj, 1767af504452SIngo Franzki struct bin_attribute *attr, 1768af504452SIngo Franzki char *buf, loff_t off, 1769af504452SIngo Franzki size_t count) 1770af504452SIngo Franzki { 1771af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf, 1772af504452SIngo Franzki off, count); 1773af504452SIngo Franzki } 1774af504452SIngo Franzki 1775af504452SIngo Franzki static ssize_t ccadata_aes_256_xts_read(struct file *filp, 1776af504452SIngo Franzki struct kobject *kobj, 1777af504452SIngo Franzki struct bin_attribute *attr, 1778af504452SIngo Franzki char *buf, loff_t off, 1779af504452SIngo Franzki size_t count) 1780af504452SIngo Franzki { 1781af504452SIngo Franzki return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf, 1782af504452SIngo Franzki off, count); 1783af504452SIngo Franzki } 1784af504452SIngo Franzki 1785af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_128, sizeof(struct secaeskeytoken)); 1786af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_192, sizeof(struct secaeskeytoken)); 1787af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_256, sizeof(struct secaeskeytoken)); 1788af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_128_xts, 2 * sizeof(struct secaeskeytoken)); 1789af504452SIngo Franzki static BIN_ATTR_RO(ccadata_aes_256_xts, 2 * sizeof(struct secaeskeytoken)); 1790af504452SIngo Franzki 1791af504452SIngo Franzki static struct bin_attribute *ccadata_attrs[] = { 1792af504452SIngo Franzki &bin_attr_ccadata_aes_128, 1793af504452SIngo Franzki &bin_attr_ccadata_aes_192, 1794af504452SIngo Franzki &bin_attr_ccadata_aes_256, 1795af504452SIngo Franzki &bin_attr_ccadata_aes_128_xts, 1796af504452SIngo Franzki &bin_attr_ccadata_aes_256_xts, 1797af504452SIngo Franzki NULL 1798af504452SIngo Franzki }; 1799af504452SIngo Franzki 1800af504452SIngo Franzki static struct attribute_group ccadata_attr_group = { 1801af504452SIngo Franzki .name = "ccadata", 1802af504452SIngo Franzki .bin_attrs = ccadata_attrs, 1803af504452SIngo Franzki }; 1804af504452SIngo Franzki 1805f71fee27SIngo Franzki #define CCACIPHERTOKENSIZE (sizeof(struct cipherkeytoken) + 80) 1806f71fee27SIngo Franzki 1807f71fee27SIngo Franzki /* 1808f71fee27SIngo Franzki * Sysfs attribute read function for all secure key ccacipher binary attributes. 1809f71fee27SIngo Franzki * The implementation can not deal with partial reads, because a new random 1810f71fee27SIngo Franzki * secure key blob is generated with each read. In case of partial reads 1811f71fee27SIngo Franzki * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 1812f71fee27SIngo Franzki */ 1813f71fee27SIngo Franzki static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits, 1814f71fee27SIngo Franzki bool is_xts, char *buf, loff_t off, 1815f71fee27SIngo Franzki size_t count) 1816f71fee27SIngo Franzki { 181755d0a513SHarald Freudenberger int i, rc, card, dom; 181855d0a513SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 181955d0a513SHarald Freudenberger size_t keysize = CCACIPHERTOKENSIZE; 1820f71fee27SIngo Franzki 1821f71fee27SIngo Franzki if (off != 0 || count < CCACIPHERTOKENSIZE) 1822f71fee27SIngo Franzki return -EINVAL; 1823f71fee27SIngo Franzki if (is_xts) 1824f71fee27SIngo Franzki if (count < 2 * CCACIPHERTOKENSIZE) 1825f71fee27SIngo Franzki return -EINVAL; 1826f71fee27SIngo Franzki 182755d0a513SHarald Freudenberger /* build a list of apqns able to generate an cipher key */ 182855d0a513SHarald Freudenberger rc = cca_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 182932ca04bbSHarald Freudenberger ZCRYPT_CEX6, 0, 0, 0, 0); 1830f71fee27SIngo Franzki if (rc) 1831f71fee27SIngo Franzki return rc; 183255d0a513SHarald Freudenberger 183355d0a513SHarald Freudenberger memset(buf, 0, is_xts ? 2 * keysize : keysize); 183455d0a513SHarald Freudenberger 183555d0a513SHarald Freudenberger /* simple try all apqns from the list */ 183655d0a513SHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 183755d0a513SHarald Freudenberger card = apqns[i] >> 16; 183855d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 183955d0a513SHarald Freudenberger rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize); 184055d0a513SHarald Freudenberger if (rc == 0) 184155d0a513SHarald Freudenberger break; 184255d0a513SHarald Freudenberger } 184355d0a513SHarald Freudenberger if (rc) 184455d0a513SHarald Freudenberger return rc; 1845f71fee27SIngo Franzki 1846f71fee27SIngo Franzki if (is_xts) { 1847f71fee27SIngo Franzki keysize = CCACIPHERTOKENSIZE; 184855d0a513SHarald Freudenberger buf += CCACIPHERTOKENSIZE; 184955d0a513SHarald Freudenberger rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize); 185055d0a513SHarald Freudenberger if (rc == 0) 1851f71fee27SIngo Franzki return 2 * CCACIPHERTOKENSIZE; 1852f71fee27SIngo Franzki } 1853f71fee27SIngo Franzki 1854f71fee27SIngo Franzki return CCACIPHERTOKENSIZE; 1855f71fee27SIngo Franzki } 1856f71fee27SIngo Franzki 1857f71fee27SIngo Franzki static ssize_t ccacipher_aes_128_read(struct file *filp, 1858f71fee27SIngo Franzki struct kobject *kobj, 1859f71fee27SIngo Franzki struct bin_attribute *attr, 1860f71fee27SIngo Franzki char *buf, loff_t off, 1861f71fee27SIngo Franzki size_t count) 1862f71fee27SIngo Franzki { 1863f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, false, buf, 1864f71fee27SIngo Franzki off, count); 1865f71fee27SIngo Franzki } 1866f71fee27SIngo Franzki 1867f71fee27SIngo Franzki static ssize_t ccacipher_aes_192_read(struct file *filp, 1868f71fee27SIngo Franzki struct kobject *kobj, 1869f71fee27SIngo Franzki struct bin_attribute *attr, 1870f71fee27SIngo Franzki char *buf, loff_t off, 1871f71fee27SIngo Franzki size_t count) 1872f71fee27SIngo Franzki { 1873f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_192, false, buf, 1874f71fee27SIngo Franzki off, count); 1875f71fee27SIngo Franzki } 1876f71fee27SIngo Franzki 1877f71fee27SIngo Franzki static ssize_t ccacipher_aes_256_read(struct file *filp, 1878f71fee27SIngo Franzki struct kobject *kobj, 1879f71fee27SIngo Franzki struct bin_attribute *attr, 1880f71fee27SIngo Franzki char *buf, loff_t off, 1881f71fee27SIngo Franzki size_t count) 1882f71fee27SIngo Franzki { 1883f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, false, buf, 1884f71fee27SIngo Franzki off, count); 1885f71fee27SIngo Franzki } 1886f71fee27SIngo Franzki 1887f71fee27SIngo Franzki static ssize_t ccacipher_aes_128_xts_read(struct file *filp, 1888f71fee27SIngo Franzki struct kobject *kobj, 1889f71fee27SIngo Franzki struct bin_attribute *attr, 1890f71fee27SIngo Franzki char *buf, loff_t off, 1891f71fee27SIngo Franzki size_t count) 1892f71fee27SIngo Franzki { 1893f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, true, buf, 1894f71fee27SIngo Franzki off, count); 1895f71fee27SIngo Franzki } 1896f71fee27SIngo Franzki 1897f71fee27SIngo Franzki static ssize_t ccacipher_aes_256_xts_read(struct file *filp, 1898f71fee27SIngo Franzki struct kobject *kobj, 1899f71fee27SIngo Franzki struct bin_attribute *attr, 1900f71fee27SIngo Franzki char *buf, loff_t off, 1901f71fee27SIngo Franzki size_t count) 1902f71fee27SIngo Franzki { 1903f71fee27SIngo Franzki return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, true, buf, 1904f71fee27SIngo Franzki off, count); 1905f71fee27SIngo Franzki } 1906f71fee27SIngo Franzki 1907f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_128, CCACIPHERTOKENSIZE); 1908f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_192, CCACIPHERTOKENSIZE); 1909f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_256, CCACIPHERTOKENSIZE); 1910f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_128_xts, 2 * CCACIPHERTOKENSIZE); 1911f71fee27SIngo Franzki static BIN_ATTR_RO(ccacipher_aes_256_xts, 2 * CCACIPHERTOKENSIZE); 1912f71fee27SIngo Franzki 1913f71fee27SIngo Franzki static struct bin_attribute *ccacipher_attrs[] = { 1914f71fee27SIngo Franzki &bin_attr_ccacipher_aes_128, 1915f71fee27SIngo Franzki &bin_attr_ccacipher_aes_192, 1916f71fee27SIngo Franzki &bin_attr_ccacipher_aes_256, 1917f71fee27SIngo Franzki &bin_attr_ccacipher_aes_128_xts, 1918f71fee27SIngo Franzki &bin_attr_ccacipher_aes_256_xts, 1919f71fee27SIngo Franzki NULL 1920f71fee27SIngo Franzki }; 1921f71fee27SIngo Franzki 1922f71fee27SIngo Franzki static struct attribute_group ccacipher_attr_group = { 1923f71fee27SIngo Franzki .name = "ccacipher", 1924f71fee27SIngo Franzki .bin_attrs = ccacipher_attrs, 1925f71fee27SIngo Franzki }; 1926f71fee27SIngo Franzki 192755d0a513SHarald Freudenberger /* 192855d0a513SHarald Freudenberger * Sysfs attribute read function for all ep11 aes key binary attributes. 192955d0a513SHarald Freudenberger * The implementation can not deal with partial reads, because a new random 193055d0a513SHarald Freudenberger * secure key blob is generated with each read. In case of partial reads 193155d0a513SHarald Freudenberger * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 193255d0a513SHarald Freudenberger * This function and the sysfs attributes using it provide EP11 key blobs 193355d0a513SHarald Freudenberger * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently 193455d0a513SHarald Freudenberger * 320 bytes. 193555d0a513SHarald Freudenberger */ 193655d0a513SHarald Freudenberger static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, 193755d0a513SHarald Freudenberger bool is_xts, char *buf, loff_t off, 193855d0a513SHarald Freudenberger size_t count) 193955d0a513SHarald Freudenberger { 194055d0a513SHarald Freudenberger int i, rc, card, dom; 194155d0a513SHarald Freudenberger u32 nr_apqns, *apqns = NULL; 194255d0a513SHarald Freudenberger size_t keysize = MAXEP11AESKEYBLOBSIZE; 194355d0a513SHarald Freudenberger 194455d0a513SHarald Freudenberger if (off != 0 || count < MAXEP11AESKEYBLOBSIZE) 194555d0a513SHarald Freudenberger return -EINVAL; 194655d0a513SHarald Freudenberger if (is_xts) 194755d0a513SHarald Freudenberger if (count < 2 * MAXEP11AESKEYBLOBSIZE) 194855d0a513SHarald Freudenberger return -EINVAL; 194955d0a513SHarald Freudenberger 195055d0a513SHarald Freudenberger /* build a list of apqns able to generate an cipher key */ 195155d0a513SHarald Freudenberger rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, 195255d0a513SHarald Freudenberger ZCRYPT_CEX7, EP11_API_V, NULL); 195355d0a513SHarald Freudenberger if (rc) 195455d0a513SHarald Freudenberger return rc; 195555d0a513SHarald Freudenberger 195655d0a513SHarald Freudenberger memset(buf, 0, is_xts ? 2 * keysize : keysize); 195755d0a513SHarald Freudenberger 195855d0a513SHarald Freudenberger /* simple try all apqns from the list */ 195955d0a513SHarald Freudenberger for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { 196055d0a513SHarald Freudenberger card = apqns[i] >> 16; 196155d0a513SHarald Freudenberger dom = apqns[i] & 0xFFFF; 196255d0a513SHarald Freudenberger rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); 196355d0a513SHarald Freudenberger if (rc == 0) 196455d0a513SHarald Freudenberger break; 196555d0a513SHarald Freudenberger } 196655d0a513SHarald Freudenberger if (rc) 196755d0a513SHarald Freudenberger return rc; 196855d0a513SHarald Freudenberger 196955d0a513SHarald Freudenberger if (is_xts) { 197055d0a513SHarald Freudenberger keysize = MAXEP11AESKEYBLOBSIZE; 197155d0a513SHarald Freudenberger buf += MAXEP11AESKEYBLOBSIZE; 197255d0a513SHarald Freudenberger rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); 197355d0a513SHarald Freudenberger if (rc == 0) 197455d0a513SHarald Freudenberger return 2 * MAXEP11AESKEYBLOBSIZE; 197555d0a513SHarald Freudenberger } 197655d0a513SHarald Freudenberger 197755d0a513SHarald Freudenberger return MAXEP11AESKEYBLOBSIZE; 197855d0a513SHarald Freudenberger } 197955d0a513SHarald Freudenberger 198055d0a513SHarald Freudenberger static ssize_t ep11_aes_128_read(struct file *filp, 198155d0a513SHarald Freudenberger struct kobject *kobj, 198255d0a513SHarald Freudenberger struct bin_attribute *attr, 198355d0a513SHarald Freudenberger char *buf, loff_t off, 198455d0a513SHarald Freudenberger size_t count) 198555d0a513SHarald Freudenberger { 198655d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, false, buf, 198755d0a513SHarald Freudenberger off, count); 198855d0a513SHarald Freudenberger } 198955d0a513SHarald Freudenberger 199055d0a513SHarald Freudenberger static ssize_t ep11_aes_192_read(struct file *filp, 199155d0a513SHarald Freudenberger struct kobject *kobj, 199255d0a513SHarald Freudenberger struct bin_attribute *attr, 199355d0a513SHarald Freudenberger char *buf, loff_t off, 199455d0a513SHarald Freudenberger size_t count) 199555d0a513SHarald Freudenberger { 199655d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_192, false, buf, 199755d0a513SHarald Freudenberger off, count); 199855d0a513SHarald Freudenberger } 199955d0a513SHarald Freudenberger 200055d0a513SHarald Freudenberger static ssize_t ep11_aes_256_read(struct file *filp, 200155d0a513SHarald Freudenberger struct kobject *kobj, 200255d0a513SHarald Freudenberger struct bin_attribute *attr, 200355d0a513SHarald Freudenberger char *buf, loff_t off, 200455d0a513SHarald Freudenberger size_t count) 200555d0a513SHarald Freudenberger { 200655d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, false, buf, 200755d0a513SHarald Freudenberger off, count); 200855d0a513SHarald Freudenberger } 200955d0a513SHarald Freudenberger 201055d0a513SHarald Freudenberger static ssize_t ep11_aes_128_xts_read(struct file *filp, 201155d0a513SHarald Freudenberger struct kobject *kobj, 201255d0a513SHarald Freudenberger struct bin_attribute *attr, 201355d0a513SHarald Freudenberger char *buf, loff_t off, 201455d0a513SHarald Freudenberger size_t count) 201555d0a513SHarald Freudenberger { 201655d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, true, buf, 201755d0a513SHarald Freudenberger off, count); 201855d0a513SHarald Freudenberger } 201955d0a513SHarald Freudenberger 202055d0a513SHarald Freudenberger static ssize_t ep11_aes_256_xts_read(struct file *filp, 202155d0a513SHarald Freudenberger struct kobject *kobj, 202255d0a513SHarald Freudenberger struct bin_attribute *attr, 202355d0a513SHarald Freudenberger char *buf, loff_t off, 202455d0a513SHarald Freudenberger size_t count) 202555d0a513SHarald Freudenberger { 202655d0a513SHarald Freudenberger return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, true, buf, 202755d0a513SHarald Freudenberger off, count); 202855d0a513SHarald Freudenberger } 202955d0a513SHarald Freudenberger 203055d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE); 203155d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE); 203255d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE); 203355d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE); 203455d0a513SHarald Freudenberger static BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE); 203555d0a513SHarald Freudenberger 203655d0a513SHarald Freudenberger static struct bin_attribute *ep11_attrs[] = { 203755d0a513SHarald Freudenberger &bin_attr_ep11_aes_128, 203855d0a513SHarald Freudenberger &bin_attr_ep11_aes_192, 203955d0a513SHarald Freudenberger &bin_attr_ep11_aes_256, 204055d0a513SHarald Freudenberger &bin_attr_ep11_aes_128_xts, 204155d0a513SHarald Freudenberger &bin_attr_ep11_aes_256_xts, 204255d0a513SHarald Freudenberger NULL 204355d0a513SHarald Freudenberger }; 204455d0a513SHarald Freudenberger 204555d0a513SHarald Freudenberger static struct attribute_group ep11_attr_group = { 204655d0a513SHarald Freudenberger .name = "ep11", 204755d0a513SHarald Freudenberger .bin_attrs = ep11_attrs, 204855d0a513SHarald Freudenberger }; 204955d0a513SHarald Freudenberger 2050d632c047SIngo Franzki static const struct attribute_group *pkey_attr_groups[] = { 2051d632c047SIngo Franzki &protkey_attr_group, 2052af504452SIngo Franzki &ccadata_attr_group, 2053f71fee27SIngo Franzki &ccacipher_attr_group, 205455d0a513SHarald Freudenberger &ep11_attr_group, 2055d632c047SIngo Franzki NULL, 2056d632c047SIngo Franzki }; 2057d632c047SIngo Franzki 2058e80d4af0SHarald Freudenberger static const struct file_operations pkey_fops = { 2059e80d4af0SHarald Freudenberger .owner = THIS_MODULE, 2060e80d4af0SHarald Freudenberger .open = nonseekable_open, 2061e80d4af0SHarald Freudenberger .llseek = no_llseek, 2062e80d4af0SHarald Freudenberger .unlocked_ioctl = pkey_unlocked_ioctl, 2063e80d4af0SHarald Freudenberger }; 2064e80d4af0SHarald Freudenberger 2065e80d4af0SHarald Freudenberger static struct miscdevice pkey_dev = { 2066e80d4af0SHarald Freudenberger .name = "pkey", 2067e80d4af0SHarald Freudenberger .minor = MISC_DYNAMIC_MINOR, 2068e80d4af0SHarald Freudenberger .mode = 0666, 2069e80d4af0SHarald Freudenberger .fops = &pkey_fops, 2070d632c047SIngo Franzki .groups = pkey_attr_groups, 2071e80d4af0SHarald Freudenberger }; 2072e80d4af0SHarald Freudenberger 2073e80d4af0SHarald Freudenberger /* 2074e80d4af0SHarald Freudenberger * Module init 2075e80d4af0SHarald Freudenberger */ 2076cb4ef3c2SHeiko Carstens static int __init pkey_init(void) 2077e80d4af0SHarald Freudenberger { 20785b35047eSHarald Freudenberger cpacf_mask_t func_mask; 2079e80d4af0SHarald Freudenberger 2080f822ad2cSHarald Freudenberger /* 2081f822ad2cSHarald Freudenberger * The pckmo instruction should be available - even if we don't 2082f822ad2cSHarald Freudenberger * actually invoke it. This instruction comes with MSA 3 which 2083f822ad2cSHarald Freudenberger * is also the minimum level for the kmc instructions which 2084f822ad2cSHarald Freudenberger * are able to work with protected keys. 2085f822ad2cSHarald Freudenberger */ 20865b35047eSHarald Freudenberger if (!cpacf_query(CPACF_PCKMO, &func_mask)) 208758443b67SDavid Hildenbrand return -ENODEV; 2088e80d4af0SHarald Freudenberger 2089cb26b9ffSIngo Franzki /* check for kmc instructions available */ 20905b35047eSHarald Freudenberger if (!cpacf_query(CPACF_KMC, &func_mask)) 209158443b67SDavid Hildenbrand return -ENODEV; 20925b35047eSHarald Freudenberger if (!cpacf_test_func(&func_mask, CPACF_KMC_PAES_128) || 20935b35047eSHarald Freudenberger !cpacf_test_func(&func_mask, CPACF_KMC_PAES_192) || 20945b35047eSHarald Freudenberger !cpacf_test_func(&func_mask, CPACF_KMC_PAES_256)) 209558443b67SDavid Hildenbrand return -ENODEV; 2096cb26b9ffSIngo Franzki 2097e80d4af0SHarald Freudenberger pkey_debug_init(); 2098e80d4af0SHarald Freudenberger 2099e80d4af0SHarald Freudenberger return misc_register(&pkey_dev); 2100e80d4af0SHarald Freudenberger } 2101e80d4af0SHarald Freudenberger 2102e80d4af0SHarald Freudenberger /* 2103e80d4af0SHarald Freudenberger * Module exit 2104e80d4af0SHarald Freudenberger */ 2105e80d4af0SHarald Freudenberger static void __exit pkey_exit(void) 2106e80d4af0SHarald Freudenberger { 2107e80d4af0SHarald Freudenberger misc_deregister(&pkey_dev); 2108e80d4af0SHarald Freudenberger pkey_debug_exit(); 2109e80d4af0SHarald Freudenberger } 2110e80d4af0SHarald Freudenberger 211163c19be0SIngo Franzki module_cpu_feature_match(MSA, pkey_init); 2112e80d4af0SHarald Freudenberger module_exit(pkey_exit); 2113