mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
s390/pkey: Simplify protected key length calculation code
The calculation of the length of a protected key based on the protected key type is scattered over certain places within the pkey code. By introducing a new inline function pkey_keytype_to_size() this can be centralized and the calling code can be reduced and simplified. With this also comes a slight rework of the generation of protected keys. Now the pkey_pckmo module is able to generate all but ECC keys. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Holger Dengler <dengler@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
parent
55e055ba7f
commit
bbecb51900
@ -96,6 +96,42 @@ static inline u32 pkey_aes_bitsize_to_keytype(u32 keybitsize)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* helper function which translates the PKEY_KEYTYPE_*
|
||||
* to the protected key size minus the WK VP length
|
||||
*/
|
||||
static inline u32 pkey_keytype_to_size(u32 keytype)
|
||||
{
|
||||
switch (keytype) {
|
||||
case PKEY_KEYTYPE_AES_128:
|
||||
return 16;
|
||||
case PKEY_KEYTYPE_AES_192:
|
||||
return 24;
|
||||
case PKEY_KEYTYPE_AES_256:
|
||||
return 32;
|
||||
case PKEY_KEYTYPE_ECC_P256:
|
||||
return 32;
|
||||
case PKEY_KEYTYPE_ECC_P384:
|
||||
return 48;
|
||||
case PKEY_KEYTYPE_ECC_P521:
|
||||
return 80;
|
||||
case PKEY_KEYTYPE_ECC_ED25519:
|
||||
return 32;
|
||||
case PKEY_KEYTYPE_ECC_ED448:
|
||||
return 54;
|
||||
case PKEY_KEYTYPE_AES_XTS_128:
|
||||
return 32;
|
||||
case PKEY_KEYTYPE_AES_XTS_256:
|
||||
return 64;
|
||||
case PKEY_KEYTYPE_HMAC_512:
|
||||
return 64;
|
||||
case PKEY_KEYTYPE_HMAC_1024:
|
||||
return 128;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pkey_api.c:
|
||||
*/
|
||||
|
@ -37,23 +37,9 @@ static bool is_pckmo_key(const u8 *key, u32 keylen)
|
||||
case TOKTYPE_NON_CCA:
|
||||
switch (hdr->version) {
|
||||
case TOKVER_CLEAR_KEY:
|
||||
switch (t->keytype) {
|
||||
case PKEY_KEYTYPE_AES_128:
|
||||
case PKEY_KEYTYPE_AES_192:
|
||||
case PKEY_KEYTYPE_AES_256:
|
||||
case PKEY_KEYTYPE_ECC_P256:
|
||||
case PKEY_KEYTYPE_ECC_P384:
|
||||
case PKEY_KEYTYPE_ECC_P521:
|
||||
case PKEY_KEYTYPE_ECC_ED25519:
|
||||
case PKEY_KEYTYPE_ECC_ED448:
|
||||
case PKEY_KEYTYPE_AES_XTS_128:
|
||||
case PKEY_KEYTYPE_AES_XTS_256:
|
||||
case PKEY_KEYTYPE_HMAC_512:
|
||||
case PKEY_KEYTYPE_HMAC_1024:
|
||||
if (pkey_keytype_to_size(t->keytype))
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case TOKVER_PROTECTED_KEY:
|
||||
return true;
|
||||
default:
|
||||
@ -85,80 +71,49 @@ static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
|
||||
|
||||
int keysize, rc = -EINVAL;
|
||||
u8 paramblock[160];
|
||||
u32 pkeytype;
|
||||
long fc;
|
||||
u32 pkeytype = 0;
|
||||
unsigned int fc;
|
||||
|
||||
switch (keytype) {
|
||||
case PKEY_KEYTYPE_AES_128:
|
||||
/* 16 byte key, 32 byte aes wkvp, total 48 bytes */
|
||||
keysize = 16;
|
||||
pkeytype = keytype;
|
||||
fc = CPACF_PCKMO_ENC_AES_128_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_192:
|
||||
/* 24 byte key, 32 byte aes wkvp, total 56 bytes */
|
||||
keysize = 24;
|
||||
pkeytype = keytype;
|
||||
fc = CPACF_PCKMO_ENC_AES_192_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_256:
|
||||
/* 32 byte key, 32 byte aes wkvp, total 64 bytes */
|
||||
keysize = 32;
|
||||
pkeytype = keytype;
|
||||
fc = CPACF_PCKMO_ENC_AES_256_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_P256:
|
||||
/* 32 byte key, 32 byte aes wkvp, total 64 bytes */
|
||||
keysize = 32;
|
||||
pkeytype = PKEY_KEYTYPE_ECC;
|
||||
fc = CPACF_PCKMO_ENC_ECC_P256_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_P384:
|
||||
/* 48 byte key, 32 byte aes wkvp, total 80 bytes */
|
||||
keysize = 48;
|
||||
pkeytype = PKEY_KEYTYPE_ECC;
|
||||
fc = CPACF_PCKMO_ENC_ECC_P384_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_P521:
|
||||
/* 80 byte key, 32 byte aes wkvp, total 112 bytes */
|
||||
keysize = 80;
|
||||
pkeytype = PKEY_KEYTYPE_ECC;
|
||||
fc = CPACF_PCKMO_ENC_ECC_P521_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_ED25519:
|
||||
/* 32 byte key, 32 byte aes wkvp, total 64 bytes */
|
||||
keysize = 32;
|
||||
pkeytype = PKEY_KEYTYPE_ECC;
|
||||
fc = CPACF_PCKMO_ENC_ECC_ED25519_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_ED448:
|
||||
/* 64 byte key, 32 byte aes wkvp, total 96 bytes */
|
||||
keysize = 64;
|
||||
pkeytype = PKEY_KEYTYPE_ECC;
|
||||
fc = CPACF_PCKMO_ENC_ECC_ED448_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_128:
|
||||
/* 2x16 byte keys, 32 byte aes wkvp, total 64 bytes */
|
||||
keysize = 32;
|
||||
pkeytype = PKEY_KEYTYPE_AES_XTS_128;
|
||||
fc = CPACF_PCKMO_ENC_AES_XTS_128_DOUBLE_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_256:
|
||||
/* 2x32 byte keys, 32 byte aes wkvp, total 96 bytes */
|
||||
keysize = 64;
|
||||
pkeytype = PKEY_KEYTYPE_AES_XTS_256;
|
||||
fc = CPACF_PCKMO_ENC_AES_XTS_256_DOUBLE_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_HMAC_512:
|
||||
/* 64 byte key, 32 byte aes wkvp, total 96 bytes */
|
||||
keysize = 64;
|
||||
pkeytype = PKEY_KEYTYPE_HMAC_512;
|
||||
fc = CPACF_PCKMO_ENC_HMAC_512_KEY;
|
||||
break;
|
||||
case PKEY_KEYTYPE_HMAC_1024:
|
||||
/* 128 byte key, 32 byte aes wkvp, total 160 bytes */
|
||||
keysize = 128;
|
||||
pkeytype = PKEY_KEYTYPE_HMAC_1024;
|
||||
fc = CPACF_PCKMO_ENC_HMAC_1024_KEY;
|
||||
break;
|
||||
default:
|
||||
@ -167,6 +122,9 @@ static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
|
||||
goto out;
|
||||
}
|
||||
|
||||
keysize = pkey_keytype_to_size(keytype);
|
||||
pkeytype = pkeytype ?: keytype;
|
||||
|
||||
if (clrkeylen && clrkeylen < keysize) {
|
||||
PKEY_DBF_ERR("%s clear key size too small: %u < %d\n",
|
||||
__func__, clrkeylen, keysize);
|
||||
@ -189,7 +147,8 @@ static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
|
||||
}
|
||||
/* check for the pckmo subfunction we need now */
|
||||
if (!cpacf_test_func(&pckmo_functions, fc)) {
|
||||
PKEY_DBF_ERR("%s pckmo functions not available\n", __func__);
|
||||
PKEY_DBF_ERR("%s pckmo fc 0x%02x not available\n",
|
||||
__func__, fc);
|
||||
rc = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
@ -288,37 +247,33 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen,
|
||||
switch (hdr->version) {
|
||||
case TOKVER_PROTECTED_KEY: {
|
||||
struct protkeytoken *t = (struct protkeytoken *)key;
|
||||
u32 keysize;
|
||||
|
||||
if (keylen < sizeof(*t))
|
||||
goto out;
|
||||
keysize = pkey_keytype_to_size(t->keytype);
|
||||
if (!keysize) {
|
||||
PKEY_DBF_ERR("%s protected key token: unknown keytype %u\n",
|
||||
__func__, t->keytype);
|
||||
goto out;
|
||||
}
|
||||
switch (t->keytype) {
|
||||
case PKEY_KEYTYPE_AES_128:
|
||||
case PKEY_KEYTYPE_AES_192:
|
||||
case PKEY_KEYTYPE_AES_256:
|
||||
if (keylen != sizeof(struct protaeskeytoken))
|
||||
if (t->len != keysize + AES_WK_VP_SIZE ||
|
||||
keylen != sizeof(struct protaeskeytoken))
|
||||
goto out;
|
||||
rc = pckmo_verify_protkey(t->protkey, t->len,
|
||||
t->keytype);
|
||||
if (rc)
|
||||
goto out;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_128:
|
||||
if (t->len != 64 || keylen != sizeof(*t) + t->len)
|
||||
goto out;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_256:
|
||||
case PKEY_KEYTYPE_HMAC_512:
|
||||
if (t->len != 96 || keylen != sizeof(*t) + t->len)
|
||||
goto out;
|
||||
break;
|
||||
case PKEY_KEYTYPE_HMAC_1024:
|
||||
if (t->len != 160 || keylen != sizeof(*t) + t->len)
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
PKEY_DBF_ERR("%s protected key token: unknown keytype %u\n",
|
||||
__func__, t->keytype);
|
||||
if (t->len != keysize + AES_WK_VP_SIZE ||
|
||||
keylen != sizeof(*t) + keysize + AES_WK_VP_SIZE)
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
memcpy(protkey, t->protkey, t->len);
|
||||
*protkeylen = t->len;
|
||||
@ -327,47 +282,12 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen,
|
||||
}
|
||||
case TOKVER_CLEAR_KEY: {
|
||||
struct clearkeytoken *t = (struct clearkeytoken *)key;
|
||||
u32 keysize = 0;
|
||||
u32 keysize;
|
||||
|
||||
if (keylen < sizeof(struct clearkeytoken) ||
|
||||
keylen != sizeof(*t) + t->len)
|
||||
goto out;
|
||||
switch (t->keytype) {
|
||||
case PKEY_KEYTYPE_AES_128:
|
||||
case PKEY_KEYTYPE_AES_192:
|
||||
case PKEY_KEYTYPE_AES_256:
|
||||
keysize = pkey_keytype_aes_to_size(t->keytype);
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_P256:
|
||||
keysize = 32;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_P384:
|
||||
keysize = 48;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_P521:
|
||||
keysize = 80;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_ED25519:
|
||||
keysize = 32;
|
||||
break;
|
||||
case PKEY_KEYTYPE_ECC_ED448:
|
||||
keysize = 64;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_128:
|
||||
keysize = 32;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_256:
|
||||
keysize = 64;
|
||||
break;
|
||||
case PKEY_KEYTYPE_HMAC_512:
|
||||
keysize = 64;
|
||||
break;
|
||||
case PKEY_KEYTYPE_HMAC_1024:
|
||||
keysize = 128;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
keysize = pkey_keytype_to_size(t->keytype);
|
||||
if (!keysize) {
|
||||
PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n",
|
||||
__func__, t->keytype);
|
||||
@ -395,8 +315,6 @@ out:
|
||||
|
||||
/*
|
||||
* Generate a random protected key.
|
||||
* Currently only the generation of AES protected keys
|
||||
* is supported.
|
||||
*/
|
||||
static int pckmo_gen_protkey(u32 keytype, u32 subtype,
|
||||
u8 *protkey, u32 *protkeylen, u32 *protkeytype)
|
||||
@ -405,23 +323,8 @@ static int pckmo_gen_protkey(u32 keytype, u32 subtype,
|
||||
int keysize;
|
||||
int rc;
|
||||
|
||||
switch (keytype) {
|
||||
case PKEY_KEYTYPE_AES_128:
|
||||
case PKEY_KEYTYPE_AES_192:
|
||||
case PKEY_KEYTYPE_AES_256:
|
||||
keysize = pkey_keytype_aes_to_size(keytype);
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_128:
|
||||
keysize = 32;
|
||||
break;
|
||||
case PKEY_KEYTYPE_AES_XTS_256:
|
||||
case PKEY_KEYTYPE_HMAC_512:
|
||||
keysize = 64;
|
||||
break;
|
||||
case PKEY_KEYTYPE_HMAC_1024:
|
||||
keysize = 128;
|
||||
break;
|
||||
default:
|
||||
keysize = pkey_keytype_to_size(keytype);
|
||||
if (!keysize) {
|
||||
PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
|
||||
__func__, keytype);
|
||||
return -EINVAL;
|
||||
@ -432,6 +335,21 @@ static int pckmo_gen_protkey(u32 keytype, u32 subtype,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (keytype) {
|
||||
case PKEY_KEYTYPE_AES_128:
|
||||
case PKEY_KEYTYPE_AES_192:
|
||||
case PKEY_KEYTYPE_AES_256:
|
||||
case PKEY_KEYTYPE_AES_XTS_128:
|
||||
case PKEY_KEYTYPE_AES_XTS_256:
|
||||
case PKEY_KEYTYPE_HMAC_512:
|
||||
case PKEY_KEYTYPE_HMAC_1024:
|
||||
break;
|
||||
default:
|
||||
PKEY_DBF_ERR("%s unsupported keytype %d\n",
|
||||
__func__, keytype);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* generate a dummy random clear key */
|
||||
get_random_bytes(clrkey, keysize);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user