diff options
author | Ingo Franzki <ifranzki@linux.ibm.com> | 2018-08-24 10:29:43 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-10-10 07:37:17 +0200 |
commit | af504452d10ece7c6d68bc9f90f478ebecd7ce76 (patch) | |
tree | 904566d846351ce6bff8fa1d454dd67f6ae81de1 /drivers | |
parent | d632c0478d64427cfbca999955e02b26986ae09e (diff) | |
download | linux-af504452d10ece7c6d68bc9f90f478ebecd7ce76.tar.bz2 |
s390/pkey: Add sysfs attributes to emit secure key blobs
Add binary read-only sysfs attributes for the pkey module
that can be used to read random ccadata secure keys from.
Keys are read from these attributes using a cat-like interface.
A typical use case for those keys is to encrypt a swap device
using the paes cipher. During processing of /etc/crypttab, the
random random ccadata secure key to encrypt the swap device is
read from one of the attributes.
The following attributes are added:
ccadata/aes_128
ccadata/aes_192
ccadata/aes_256
ccadata/aes_128_xts
ccadata/aes_256_xts
Each attribute emits a secure key blob for the corresponding
key size and cipher mode.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/crypto/pkey_api.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index b4d88411b1bd..d0160a18081a 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -1375,8 +1375,112 @@ static struct attribute_group protkey_attr_group = { .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) +{ + int rc; + + if (off != 0 || count < sizeof(struct secaeskeytoken)) + return -EINVAL; + if (is_xts) + if (count < 2 * sizeof(struct secaeskeytoken)) + return -EINVAL; + + rc = pkey_genseckey(-1, -1, keytype, (struct pkey_seckey *)buf); + if (rc) + return rc; + + if (is_xts) { + buf += sizeof(struct pkey_seckey); + rc = pkey_genseckey(-1, -1, keytype, (struct pkey_seckey *)buf); + 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, +}; + static const struct attribute_group *pkey_attr_groups[] = { &protkey_attr_group, + &ccadata_attr_group, NULL, }; |