summaryrefslogtreecommitdiff
path: root/drivers/s390/crypto/pkey_api.c
diff options
context:
space:
mode:
authorIngo Franzki <ifranzki@linux.ibm.com>2018-08-23 11:06:26 +0300
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-10-09 12:21:38 +0300
commita45a5c7d36a53646094c2ba4970777a20ec0ec42 (patch)
treee31f212b548141d0fd3b1240674b0417eb28d9cc /drivers/s390/crypto/pkey_api.c
parentaa55bf5f022271903fe8a71e08be3e217e1b6363 (diff)
downloadlinux-a45a5c7d36a53646094c2ba4970777a20ec0ec42.tar.xz
s390/pkey: Introduce new API for random protected key generation
This patch introduces a new ioctl API and in-kernel API to generate a random protected key. The protected key is generated in a way that the effective clear key is never exposed in clear. Both APIs are described in detail in the header files arch/s390/include/asm/pkey.h and arch/s390/include/uapi/asm/pkey.h. 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/s390/crypto/pkey_api.c')
-rw-r--r--drivers/s390/crypto/pkey_api.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 1b4001e0285f..29028ccdce5b 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/kallsyms.h>
#include <linux/debugfs.h>
+#include <linux/random.h>
#include <asm/zcrypt.h>
#include <asm/cpacf.h>
#include <asm/pkey.h>
@@ -1052,6 +1053,46 @@ out:
EXPORT_SYMBOL(pkey_verifykey);
/*
+ * Generate a random protected key
+ */
+int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey)
+{
+ struct pkey_clrkey clrkey;
+ int keysize;
+ int rc;
+
+ switch (keytype) {
+ case PKEY_KEYTYPE_AES_128:
+ keysize = 16;
+ break;
+ case PKEY_KEYTYPE_AES_192:
+ keysize = 24;
+ break;
+ case PKEY_KEYTYPE_AES_256:
+ keysize = 32;
+ break;
+ default:
+ DEBUG_ERR("%s unknown/unsupported keytype %d\n", __func__,
+ keytype);
+ return -EINVAL;
+ }
+
+ /* generate a dummy random clear key */
+ get_random_bytes(clrkey.clrkey, keysize);
+
+ /* convert it to a dummy protected key */
+ rc = pkey_clr2protkey(keytype, &clrkey, protkey);
+ if (rc)
+ return rc;
+
+ /* replace the key part of the protected key with random bytes */
+ get_random_bytes(protkey->protkey, keysize);
+
+ return 0;
+}
+EXPORT_SYMBOL(pkey_genprotkey);
+
+/*
* File io functions
*/
@@ -1167,6 +1208,20 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
break;
}
+ case PKEY_GENPROTK: {
+ struct pkey_genprotk __user *ugp = (void __user *) arg;
+ struct pkey_genprotk kgp;
+
+ if (copy_from_user(&kgp, ugp, sizeof(kgp)))
+ return -EFAULT;
+ rc = pkey_genprotkey(kgp.keytype, &kgp.protkey);
+ DEBUG_DBG("%s pkey_genprotkey()=%d\n", __func__, rc);
+ if (rc)
+ break;
+ if (copy_to_user(ugp, &kgp, sizeof(kgp)))
+ return -EFAULT;
+ break;
+ }
default:
/* unknown/unsupported ioctl cmd */
return -ENOTTY;