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:
Harald Freudenberger 2024-10-25 12:34:28 +02:00 committed by Heiko Carstens
parent 55e055ba7f
commit bbecb51900
2 changed files with 77 additions and 123 deletions

View File

@ -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:
*/

View File

@ -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;
}
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);
goto out;
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);