From: Harald Freudenberger Date: Fri, 25 Oct 2024 10:34:28 +0000 (+0200) Subject: s390/pkey: Simplify protected key length calculation code X-Git-Tag: v6.13-rc1~206^2~80 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bbecb519004c928629f2fd150b929b54f9740bf6;p=thirdparty%2Fkernel%2Flinux.git 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 Reviewed-by: Holger Dengler Signed-off-by: Heiko Carstens --- diff --git a/drivers/s390/crypto/pkey_base.h b/drivers/s390/crypto/pkey_base.h index 7a1a5ce192d82..7347647dfaa76 100644 --- a/drivers/s390/crypto/pkey_base.h +++ b/drivers/s390/crypto/pkey_base.h @@ -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: */ diff --git a/drivers/s390/crypto/pkey_pckmo.c b/drivers/s390/crypto/pkey_pckmo.c index 70b9996e5f9f8..20fabfff6ef8d 100644 --- a/drivers/s390/crypto/pkey_pckmo.c +++ b/drivers/s390/crypto/pkey_pckmo.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; - } + 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) + default: + if (t->len != keysize + AES_WK_VP_SIZE || + keylen != sizeof(*t) + keysize + AES_WK_VP_SIZE) goto out; break; - default: - PKEY_DBF_ERR("%s protected key token: unknown keytype %u\n", - __func__, t->keytype); - goto out; } 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,32 +323,32 @@ static int pckmo_gen_protkey(u32 keytype, u32 subtype, int keysize; int rc; + keysize = pkey_keytype_to_size(keytype); + if (!keysize) { + PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", + __func__, keytype); + return -EINVAL; + } + if (subtype != PKEY_TYPE_PROTKEY) { + PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", + __func__, subtype); + return -EINVAL; + } + 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: - PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", + PKEY_DBF_ERR("%s unsupported keytype %d\n", __func__, keytype); return -EINVAL; } - if (subtype != PKEY_TYPE_PROTKEY) { - PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", - __func__, subtype); - return -EINVAL; - } /* generate a dummy random clear key */ get_random_bytes(clrkey, keysize);