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>
This commit is contained in:
parent
aa55bf5f02
commit
a45a5c7d36
|
@ -109,4 +109,12 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
|
|||
u16 *pcardnr, u16 *pdomain,
|
||||
u16 *pkeysize, u32 *pattributes);
|
||||
|
||||
/*
|
||||
* In-kernel API: Generate (AES) random protected key.
|
||||
* @param keytype one of the PKEY_KEYTYPE values
|
||||
* @param protkey pointer to buffer receiving the protected key
|
||||
* @return 0 on success, negative errno value on failure
|
||||
*/
|
||||
int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey);
|
||||
|
||||
#endif /* _KAPI_PKEY_H */
|
||||
|
|
|
@ -129,4 +129,14 @@ struct pkey_verifykey {
|
|||
#define PKEY_VERIFY_ATTR_AES 0x00000001 /* key is an AES key */
|
||||
#define PKEY_VERIFY_ATTR_OLD_MKVP 0x00000100 /* key has old MKVP value */
|
||||
|
||||
/*
|
||||
* Generate (AES) random protected key.
|
||||
*/
|
||||
struct pkey_genprotk {
|
||||
__u32 keytype; /* in: key type to generate */
|
||||
struct pkey_protkey protkey; /* out: the protected key */
|
||||
};
|
||||
|
||||
#define PKEY_GENPROTK _IOWR(PKEY_IOCTL_MAGIC, 0x08, struct pkey_genprotk)
|
||||
|
||||
#endif /* _UAPI_PKEY_H */
|
||||
|
|
|
@ -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>
|
||||
|
@ -1051,6 +1052,46 @@ int pkey_verifykey(const struct pkey_seckey *seckey,
|
|||
}
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue