| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * pkey module sysfs related functions
- *
- * Copyright IBM Corp. 2024
- */
- #define KMSG_COMPONENT "pkey"
- #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
- #include <linux/sysfs.h>
- #include "zcrypt_api.h"
- #include "zcrypt_ccamisc.h"
- #include "zcrypt_ep11misc.h"
- #include "pkey_base.h"
- /*
- * Wrapper around pkey_handler_gen_key() which deals with the
- * ENODEV return code and then tries to enforce a pkey handler
- * module load.
- */
- static int sys_pkey_handler_gen_key(u32 keytype, u32 keysubtype,
- u32 keybitsize, u32 flags,
- u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
- {
- int rc;
- rc = pkey_handler_gen_key(NULL, 0,
- keytype, keysubtype,
- keybitsize, flags,
- keybuf, keybuflen, keyinfo);
- if (rc == -ENODEV) {
- pkey_handler_request_modules();
- rc = pkey_handler_gen_key(NULL, 0,
- keytype, keysubtype,
- keybitsize, flags,
- keybuf, keybuflen, keyinfo);
- }
- return rc;
- }
- /*
- * Sysfs attribute read function for all protected key binary attributes.
- * The implementation can not deal with partial reads, because a new random
- * protected key blob is generated with each read. In case of partial reads
- * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
- */
- static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf,
- loff_t off, size_t count)
- {
- struct protaeskeytoken protkeytoken;
- struct pkey_protkey protkey;
- int rc;
- if (off != 0 || count < sizeof(protkeytoken))
- return -EINVAL;
- if (is_xts)
- if (count < 2 * sizeof(protkeytoken))
- return -EINVAL;
- memset(&protkeytoken, 0, sizeof(protkeytoken));
- protkeytoken.type = TOKTYPE_NON_CCA;
- protkeytoken.version = TOKVER_PROTECTED_KEY;
- protkeytoken.keytype = keytype;
- protkey.len = sizeof(protkey.protkey);
- rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
- protkey.protkey, &protkey.len,
- &protkey.type);
- if (rc)
- return rc;
- protkeytoken.len = protkey.len;
- memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len);
- memcpy(buf, &protkeytoken, sizeof(protkeytoken));
- if (is_xts) {
- /* xts needs a second protected key, reuse protkey struct */
- protkey.len = sizeof(protkey.protkey);
- rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
- protkey.protkey, &protkey.len,
- &protkey.type);
- if (rc)
- return rc;
- protkeytoken.len = protkey.len;
- memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len);
- memcpy(buf + sizeof(protkeytoken), &protkeytoken,
- sizeof(protkeytoken));
- return 2 * sizeof(protkeytoken);
- }
- return sizeof(protkeytoken);
- }
- /*
- * Sysfs attribute read function for the AES XTS prot key binary attributes.
- * The implementation can not deal with partial reads, because a new random
- * protected key blob is generated with each read. In case of partial reads
- * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
- */
- static ssize_t pkey_protkey_aes_xts_attr_read(u32 keytype, char *buf,
- loff_t off, size_t count)
- {
- struct protkeytoken *t = (struct protkeytoken *)buf;
- u32 protlen, prottype;
- int rc;
- switch (keytype) {
- case PKEY_KEYTYPE_AES_XTS_128:
- protlen = 64;
- break;
- case PKEY_KEYTYPE_AES_XTS_256:
- protlen = 96;
- break;
- default:
- return -EINVAL;
- }
- if (off != 0 || count < sizeof(*t) + protlen)
- return -EINVAL;
- memset(t, 0, sizeof(*t) + protlen);
- t->type = TOKTYPE_NON_CCA;
- t->version = TOKVER_PROTECTED_KEY;
- t->keytype = keytype;
- rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
- t->protkey, &protlen, &prottype);
- if (rc)
- return rc;
- t->len = protlen;
- return sizeof(*t) + protlen;
- }
- /*
- * Sysfs attribute read function for the HMAC prot key binary attributes.
- * The implementation can not deal with partial reads, because a new random
- * protected key blob is generated with each read. In case of partial reads
- * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
- */
- static ssize_t pkey_protkey_hmac_attr_read(u32 keytype, char *buf,
- loff_t off, size_t count)
- {
- struct protkeytoken *t = (struct protkeytoken *)buf;
- u32 protlen, prottype;
- int rc;
- switch (keytype) {
- case PKEY_KEYTYPE_HMAC_512:
- protlen = 96;
- break;
- case PKEY_KEYTYPE_HMAC_1024:
- protlen = 160;
- break;
- default:
- return -EINVAL;
- }
- if (off != 0 || count < sizeof(*t) + protlen)
- return -EINVAL;
- memset(t, 0, sizeof(*t) + protlen);
- t->type = TOKTYPE_NON_CCA;
- t->version = TOKVER_PROTECTED_KEY;
- t->keytype = keytype;
- rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
- t->protkey, &protlen, &prottype);
- if (rc)
- return rc;
- t->len = protlen;
- return sizeof(*t) + protlen;
- }
- static ssize_t protkey_aes_128_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf,
- off, count);
- }
- static ssize_t protkey_aes_192_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf,
- off, count);
- }
- static ssize_t protkey_aes_256_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf,
- off, count);
- }
- static ssize_t protkey_aes_128_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf,
- off, count);
- }
- static ssize_t protkey_aes_256_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf,
- off, count);
- }
- static ssize_t protkey_aes_xts_128_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_aes_xts_attr_read(PKEY_KEYTYPE_AES_XTS_128,
- buf, off, count);
- }
- static ssize_t protkey_aes_xts_256_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_aes_xts_attr_read(PKEY_KEYTYPE_AES_XTS_256,
- buf, off, count);
- }
- static ssize_t protkey_hmac_512_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_hmac_attr_read(PKEY_KEYTYPE_HMAC_512,
- buf, off, count);
- }
- static ssize_t protkey_hmac_1024_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_protkey_hmac_attr_read(PKEY_KEYTYPE_HMAC_1024,
- buf, off, count);
- }
- static BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken));
- static BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken));
- static BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken));
- static BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken));
- static BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken));
- static BIN_ATTR_RO(protkey_aes_xts_128, sizeof(struct protkeytoken) + 64);
- static BIN_ATTR_RO(protkey_aes_xts_256, sizeof(struct protkeytoken) + 96);
- static BIN_ATTR_RO(protkey_hmac_512, sizeof(struct protkeytoken) + 96);
- static BIN_ATTR_RO(protkey_hmac_1024, sizeof(struct protkeytoken) + 160);
- static struct bin_attribute *protkey_attrs[] = {
- &bin_attr_protkey_aes_128,
- &bin_attr_protkey_aes_192,
- &bin_attr_protkey_aes_256,
- &bin_attr_protkey_aes_128_xts,
- &bin_attr_protkey_aes_256_xts,
- &bin_attr_protkey_aes_xts_128,
- &bin_attr_protkey_aes_xts_256,
- &bin_attr_protkey_hmac_512,
- &bin_attr_protkey_hmac_1024,
- NULL
- };
- static struct attribute_group protkey_attr_group = {
- .name = "protkey",
- .bin_attrs = protkey_attrs,
- };
- /*
- * Sysfs attribute read function for all secure key ccadata binary attributes.
- * The implementation can not deal with partial reads, because a new random
- * protected key blob is generated with each read. In case of partial reads
- * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
- */
- static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf,
- loff_t off, size_t count)
- {
- struct pkey_seckey *seckey = (struct pkey_seckey *)buf;
- u32 buflen;
- int rc;
- if (off != 0 || count < sizeof(struct secaeskeytoken))
- return -EINVAL;
- if (is_xts)
- if (count < 2 * sizeof(struct secaeskeytoken))
- return -EINVAL;
- buflen = sizeof(seckey->seckey);
- rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_CCA_DATA, 0, 0,
- seckey->seckey, &buflen, NULL);
- if (rc)
- return rc;
- if (is_xts) {
- seckey++;
- buflen = sizeof(seckey->seckey);
- rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_CCA_DATA, 0, 0,
- seckey->seckey, &buflen, NULL);
- if (rc)
- return rc;
- return 2 * sizeof(struct secaeskeytoken);
- }
- return sizeof(struct secaeskeytoken);
- }
- static ssize_t ccadata_aes_128_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, false, buf,
- off, count);
- }
- static ssize_t ccadata_aes_192_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_192, false, buf,
- off, count);
- }
- static ssize_t ccadata_aes_256_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, false, buf,
- off, count);
- }
- static ssize_t ccadata_aes_128_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_128, true, buf,
- off, count);
- }
- static ssize_t ccadata_aes_256_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccadata_aes_attr_read(PKEY_KEYTYPE_AES_256, true, buf,
- off, count);
- }
- static BIN_ATTR_RO(ccadata_aes_128, sizeof(struct secaeskeytoken));
- static BIN_ATTR_RO(ccadata_aes_192, sizeof(struct secaeskeytoken));
- static BIN_ATTR_RO(ccadata_aes_256, sizeof(struct secaeskeytoken));
- static BIN_ATTR_RO(ccadata_aes_128_xts, 2 * sizeof(struct secaeskeytoken));
- static BIN_ATTR_RO(ccadata_aes_256_xts, 2 * sizeof(struct secaeskeytoken));
- static struct bin_attribute *ccadata_attrs[] = {
- &bin_attr_ccadata_aes_128,
- &bin_attr_ccadata_aes_192,
- &bin_attr_ccadata_aes_256,
- &bin_attr_ccadata_aes_128_xts,
- &bin_attr_ccadata_aes_256_xts,
- NULL
- };
- static struct attribute_group ccadata_attr_group = {
- .name = "ccadata",
- .bin_attrs = ccadata_attrs,
- };
- #define CCACIPHERTOKENSIZE (sizeof(struct cipherkeytoken) + 80)
- /*
- * Sysfs attribute read function for all secure key ccacipher binary attributes.
- * The implementation can not deal with partial reads, because a new random
- * secure key blob is generated with each read. In case of partial reads
- * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
- */
- static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits,
- bool is_xts, char *buf, loff_t off,
- size_t count)
- {
- u32 keysize = CCACIPHERTOKENSIZE;
- int rc;
- if (off != 0 || count < CCACIPHERTOKENSIZE)
- return -EINVAL;
- if (is_xts)
- if (count < 2 * CCACIPHERTOKENSIZE)
- return -EINVAL;
- memset(buf, 0, is_xts ? 2 * keysize : keysize);
- rc = sys_pkey_handler_gen_key(pkey_aes_bitsize_to_keytype(keybits),
- PKEY_TYPE_CCA_CIPHER, keybits, 0,
- buf, &keysize, NULL);
- if (rc)
- return rc;
- if (is_xts) {
- keysize = CCACIPHERTOKENSIZE;
- buf += CCACIPHERTOKENSIZE;
- rc = sys_pkey_handler_gen_key(
- pkey_aes_bitsize_to_keytype(keybits),
- PKEY_TYPE_CCA_CIPHER, keybits, 0,
- buf, &keysize, NULL);
- if (rc)
- return rc;
- return 2 * CCACIPHERTOKENSIZE;
- }
- return CCACIPHERTOKENSIZE;
- }
- static ssize_t ccacipher_aes_128_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, false, buf,
- off, count);
- }
- static ssize_t ccacipher_aes_192_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_192, false, buf,
- off, count);
- }
- static ssize_t ccacipher_aes_256_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, false, buf,
- off, count);
- }
- static ssize_t ccacipher_aes_128_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_128, true, buf,
- off, count);
- }
- static ssize_t ccacipher_aes_256_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ccacipher_aes_attr_read(PKEY_SIZE_AES_256, true, buf,
- off, count);
- }
- static BIN_ATTR_RO(ccacipher_aes_128, CCACIPHERTOKENSIZE);
- static BIN_ATTR_RO(ccacipher_aes_192, CCACIPHERTOKENSIZE);
- static BIN_ATTR_RO(ccacipher_aes_256, CCACIPHERTOKENSIZE);
- static BIN_ATTR_RO(ccacipher_aes_128_xts, 2 * CCACIPHERTOKENSIZE);
- static BIN_ATTR_RO(ccacipher_aes_256_xts, 2 * CCACIPHERTOKENSIZE);
- static struct bin_attribute *ccacipher_attrs[] = {
- &bin_attr_ccacipher_aes_128,
- &bin_attr_ccacipher_aes_192,
- &bin_attr_ccacipher_aes_256,
- &bin_attr_ccacipher_aes_128_xts,
- &bin_attr_ccacipher_aes_256_xts,
- NULL
- };
- static struct attribute_group ccacipher_attr_group = {
- .name = "ccacipher",
- .bin_attrs = ccacipher_attrs,
- };
- /*
- * Sysfs attribute read function for all ep11 aes key binary attributes.
- * The implementation can not deal with partial reads, because a new random
- * secure key blob is generated with each read. In case of partial reads
- * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
- * This function and the sysfs attributes using it provide EP11 key blobs
- * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently
- * 336 bytes.
- */
- static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
- bool is_xts, char *buf, loff_t off,
- size_t count)
- {
- u32 keysize = MAXEP11AESKEYBLOBSIZE;
- int rc;
- if (off != 0 || count < MAXEP11AESKEYBLOBSIZE)
- return -EINVAL;
- if (is_xts)
- if (count < 2 * MAXEP11AESKEYBLOBSIZE)
- return -EINVAL;
- memset(buf, 0, is_xts ? 2 * keysize : keysize);
- rc = sys_pkey_handler_gen_key(pkey_aes_bitsize_to_keytype(keybits),
- PKEY_TYPE_EP11_AES, keybits, 0,
- buf, &keysize, NULL);
- if (rc)
- return rc;
- if (is_xts) {
- keysize = MAXEP11AESKEYBLOBSIZE;
- buf += MAXEP11AESKEYBLOBSIZE;
- rc = sys_pkey_handler_gen_key(
- pkey_aes_bitsize_to_keytype(keybits),
- PKEY_TYPE_EP11_AES, keybits, 0,
- buf, &keysize, NULL);
- if (rc)
- return rc;
- return 2 * MAXEP11AESKEYBLOBSIZE;
- }
- return MAXEP11AESKEYBLOBSIZE;
- }
- static ssize_t ep11_aes_128_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, false, buf,
- off, count);
- }
- static ssize_t ep11_aes_192_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_192, false, buf,
- off, count);
- }
- static ssize_t ep11_aes_256_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, false, buf,
- off, count);
- }
- static ssize_t ep11_aes_128_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, true, buf,
- off, count);
- }
- static ssize_t ep11_aes_256_xts_read(struct file *filp,
- struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off,
- size_t count)
- {
- return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, true, buf,
- off, count);
- }
- static BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE);
- static BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE);
- static BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE);
- static BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE);
- static BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE);
- static struct bin_attribute *ep11_attrs[] = {
- &bin_attr_ep11_aes_128,
- &bin_attr_ep11_aes_192,
- &bin_attr_ep11_aes_256,
- &bin_attr_ep11_aes_128_xts,
- &bin_attr_ep11_aes_256_xts,
- NULL
- };
- static struct attribute_group ep11_attr_group = {
- .name = "ep11",
- .bin_attrs = ep11_attrs,
- };
- const struct attribute_group *pkey_attr_groups[] = {
- &protkey_attr_group,
- &ccadata_attr_group,
- &ccacipher_attr_group,
- &ep11_attr_group,
- NULL,
- };
|