New s390 specific protected key hmac
Subsystems (4)
Harald Freudenberger
maintainerv9 cover New s390 specific protected key hmac
Add support for protected key hmac ("phmac") for s390 arch.
With the latest machine generation there is now support for protected key (that is a key wrapped by a master key stored in firmware) hmac for sha2 (sha224, sha256, sha384 and sha512) for the s390 specific CPACF instruction kmac.
This patch adds support via 4 new hashes registered as phmac(sha224), phmac(sha256), phmac(sha384) and phmac(sha512).
Changelog:
v1: Initial version
v2: Increase HASH_MAX_DESCSIZE generic (not just for arch s390).
Fix one finding to use kmemdup instead of kmalloc/memcpy from test robot. Remove unneeded cpacf subfunctions checks. Simplify clone_tfm() function. Rebased to s390/features.
v3: Feedback from Herbert: Use GFP_ATOMIC in setkey function.
Feedback from Holger: rework tfm clone function, move convert key invocation from setkey to init function. Rebased to updated s390/features from 11/7/2024. Ready for integration if there are no complains on v3.
v4: Rewind back more or less to v2. Add code to check for non-sleeping
context. Non-sleeping context during attempt to derive the protected key from raw key material is not accepted and -EOPNOTSUPP is returned (also currently all derivation pathes would in fact never sleep). In general the phmac implementation is not to be used within non-sleeping context and the code header mentions this. Tested with (patched) dm-integrity - works fine.
v5: As suggested by Herbert now the shashes have been marked as
'internal' and wrapped by ahashes which use the cryptd if an atomic context is detected. So the visible phmac algorithms are now ahashes. Unfortunately the dm-integrity implementation currently requests and deals only with shashes and this phmac implementation is not fitting to the original goal any more...
v6: As suggested by Herbert now a pure async phmac implementation.
Tested via AF_ALG interface. Untested via dm-integrity as this layer only supports shashes. Maybe I'll develop a patch to switch the dm-integrity to ahash as it is anyway the more flexible interface.
v7: Total rework of the implementation. Now uses workqueues and triggers
asynch requests for key convert, init, update, final and digest. Tested with instrumented code and with a reworked version of dm-integrity which uses asynchronous hashes. A patch for dm-integrity is on the way but yet needs some last hone work.
v8: Added selftest. With the selftest comes some code which wraps the
clear key into a "clear key token" digestible by PKEY. The selftest also uses import() and export(), so these are now also implemented. Furthermore a finup() implementation is now also available. Tested with AF_ALG testcases and dm-integrity, also tested with some instrumented code to check that the asynch workqueue functions do their job correctly. Coding is complete!
v9: As suggested by Herbert use ahash_request_complete() and surround it
with local_bh_disable().
Harald Freudenberger (2):
s390/crypto: New s390 specific protected key hash phmac s390/crypto: Enable phmac selftest invocation
Holger Dengler (1):
s390/crypto: Add protected key hmac subfunctions for KMAC
arch/s390/configs/debug_defconfig | 1 + arch/s390/configs/defconfig | 1 + arch/s390/crypto/Makefile | 1 + arch/s390/crypto/phmac_s390.c | 986 ++++++++++++++++++++++++++++++ arch/s390/include/asm/cpacf.h | 4 + crypto/testmgr.c | 30 + drivers/crypto/Kconfig | 12 + include/linux/crypto.h | 5 + 8 files changed, 1040 insertions(+) create mode 100644 arch/s390/crypto/phmac_s390.c
base-commit: fac04efc5c793dccbd07e2d59af9f90b7fc0dca4
Signature · 1 line
2.43.0
Harald Freudenberger
maintainerPATCH v9 1/3 s390/crypto: Add protected key hmac subfunctions for KMAC
From: Holger Dengler <[email protected]>
The CPACF KMAC instruction supports new subfunctions for protected key hmac. Add defines for these 4 new subfuctions.
--- arch/s390/include/asm/cpacf.h | 4 ++++ 1 file changed, 4 insertions(+)
arch/s390/include/asm/cpacf.h +4 -0
@@ -129,6 +129,10 @@#define CPACF_KMAC_HMAC_SHA_256 0x71#define CPACF_KMAC_HMAC_SHA_384 0x72#define CPACF_KMAC_HMAC_SHA_512 0x73 +#define CPACF_KMAC_PHMAC_SHA_224 0x78 +#define CPACF_KMAC_PHMAC_SHA_256 0x79 +#define CPACF_KMAC_PHMAC_SHA_384 0x7a +#define CPACF_KMAC_PHMAC_SHA_512 0x7b/* * Function codes for the PCKMO (PERFORM CRYPTOGRAPHIC KEY MANAGEMENT)
Signature · 1 line
2.43.0
Harald Freudenberger
maintainerPATCH v9 2/3 s390/crypto: New s390 specific protected key hash phmac
In reply to Harald FreudenbergerAdd support for protected key hmac ("phmac") for s390 arch.
With the latest machine generation there is now support for protected key (that is a key wrapped by a master key stored in firmware) hmac for sha2 (sha224, sha256, sha384 and sha512) for the s390 specific CPACF instruction kmac.
This patch adds support via 4 new ahashes registered as phmac(sha224), phmac(sha256), phmac(sha384) and phmac(sha512).
--- arch/s390/configs/debug_defconfig | 1 + arch/s390/configs/defconfig | 1 + arch/s390/crypto/Makefile | 1 + arch/s390/crypto/phmac_s390.c | 852 ++++++++++++++++++++++++++++++ drivers/crypto/Kconfig | 12 + 5 files changed, 867 insertions(+) create mode 100644 arch/s390/crypto/phmac_s390.c
arch/s390/configs/debug_defconfig +1 -0
@@ -813,6 +813,7 @@ CONFIG_PKEY_EP11=m CONFIG_PKEY_PCKMO=m CONFIG_PKEY_UV=m CONFIG_CRYPTO_PAES_S390=m +CONFIG_CRYPTO_PHMAC_S390=m CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_SYSTEM_BLACKLIST_KEYRING=y CONFIG_CORDIC=m
arch/s390/configs/defconfig +1 -0
@@ -800,6 +800,7 @@ CONFIG_PKEY_EP11=m CONFIG_PKEY_PCKMO=m CONFIG_PKEY_UV=m CONFIG_CRYPTO_PAES_S390=m +CONFIG_CRYPTO_PHMAC_S390=m CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_SYSTEM_BLACKLIST_KEYRING=y CONFIG_CORDIC=m
arch/s390/crypto/Makefile +1 -0
@@ -16,6 +16,7 @@ obj-$(CONFIG_S390_PRNG) += prng.o obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o obj-$(CONFIG_CRYPTO_CRC32_S390) += crc32-vx_s390.o obj-$(CONFIG_CRYPTO_HMAC_S390) += hmac_s390.o +obj-$(CONFIG_CRYPTO_PHMAC_S390) += phmac_s390.o obj-y += arch_random.o crc32-vx_s390-y := crc32-vx.o crc32le-vx.o crc32be-vx.o
arch/s390/crypto/phmac_s390.c new file +852 -0
852 lines not on this page · raw message
drivers/crypto/Kconfig +12 -0
@@ -187,6 +187,18 @@ config CRYPTO_PAES_S390 Select this option if you want to use the paes cipher for example to use protected key encrypted devices. +config CRYPTO_PHMAC_S390 + tristate "PHMAC cipher algorithms" + depends on S390 + depends on PKEY + select CRYPTO_HASH + help + This is the s390 hardware accelerated implementation of the + protected key HMAC support for SHA224, SHA256, SHA384 and SHA512. + + Select this option if you want to use the phmac digests + for example to use dm-integrity with secure/protected keys. + config S390_PRNG tristate "Pseudo random number generator device driver" depends on S390
Signature · 1 line
2.43.0
Holger Dengler
maintainerRe: [PATCH v9 2/3] s390/crypto: New s390 specific protected key hash phmac
Quoted 11 lines · Harald Freudenberger
Add support for protected key hmac ("phmac") for s390 arch.
With the latest machine generation there is now support for protected key (that is a key wrapped by a master key stored in firmware) hmac for sha2 (sha224, sha256, sha384 and sha512) for the s390 specific CPACF instruction kmac.
This patch adds support via 4 new ahashes registered as phmac(sha224), phmac(sha256), phmac(sha384) and phmac(sha512).
Co-developed-by Holger Dengler <[email protected]>
Please also add my S-o-b.
Quoted 1 line
Signed-off-by Harald Freudenberger <[email protected]>
[...]
Signature · 5 lines
Mit freundlichen Grüßen / Kind regards Holger Dengler -- IBM Systems, Linux on IBM Z Development [email protected]
Harald Freudenberger
maintainerPATCH v9 3/3 s390/crypto: Enable phmac selftest invocation
In reply to Harald Freudenberger- Add a little helper inline function crypto_tfm_alg_get_flags()
to crypto.h to retrieve the alg flags.
- Add key preparation code in case of selftest running to the phmac setkey function.
- Add phmac selftest invocation to the crypto testmanager.
--- arch/s390/crypto/phmac_s390.c | 144 ++++++++++++++++++++++++++++++++-- crypto/testmgr.c | 30 +++++++ include/linux/crypto.h | 5 ++ 3 files changed, 174 insertions(+), 5 deletions(-)
arch/s390/crypto/phmac_s390.c +139 -5
@@ -112,6 +112,19 @@ struct s390_phmac_req_ctx {struct s390_kmac_sha2_ctx sha2_ctx; }; +/* +* Pkey 'token' struct used to derive a protected key value from a clear key. +*/ +struct hmac_clrkey_token { +u8 type; +u8 res0[3 ]; +u8 version; +u8 res1[3 ]; +u32 keytype; +u32 len; +u8 key[]; +} __packed; +/* * kmac_sha2_set_imbl - sets the input message bit-length based on the blocksize */
@@ -132,6 +145,101 @@ static inline void kmac_sha2_set_imbl(u8 *param, unsigned int buflen, } } +static int hash_key (const u8 *in,unsigned int inlen, +u8 *digest,unsigned int digestsize) +{ +unsigned long func; +union { +struct sha256_paramblock { +u32 h[8 ]; +u64 mbl; + } sha256; +struct sha512_paramblock { +u64 h[8 ]; +u128 mbl; + } sha512; + } __packed param; + +#define PARAM_INIT (x, y, z) \ + param.sha##x.h[0] = SHA##y ## _H0; \ + param.sha##x.h[1] = SHA##y ## _H1; \ + param.sha##x.h[2] = SHA##y ## _H2; \ + param.sha##x.h[3] = SHA##y ## _H3; \ + param.sha##x.h[4] = SHA##y ## _H4; \ + param.sha##x.h[5] = SHA##y ## _H5; \ + param.sha##x.h[6] = SHA##y ## _H6; \ + param.sha##x.h[7] = SHA##y ## _H7; \ + param.sha##x.mbl = (z) + +switch (digestsize) { +case SHA224_DIGEST_SIZE : + func =CPACF_KLMD_SHA_256 ; +PARAM_INIT (256 ,224 , inlen *8 ); +break ; +case SHA256_DIGEST_SIZE : + func =CPACF_KLMD_SHA_256 ; +PARAM_INIT (256 ,256 , inlen *8 ); +break ; +case SHA384_DIGEST_SIZE : + func =CPACF_KLMD_SHA_512 ; +PARAM_INIT (512 ,384 , inlen *8 ); +break ; +case SHA512_DIGEST_SIZE : + func =CPACF_KLMD_SHA_512 ; +PARAM_INIT (512 ,512 , inlen *8 ); +break ; +default : +return -EINVAL ; + } + +#undef PARAM_INIT + +cpacf_klmd (func, ¶m, in, inlen); + +memcpy (digest, ¶m, digestsize); + +return 0 ; +} + +/* +* make_clrkey_token() - wrap the clear key into a pkey clearkey token. +*/ +static inline int make_clrkey_token (const u8 *clrkey,size_t clrkeylen, +unsigned int digestsize,u8 *dest) +{ +struct hmac_clrkey_token *token = (struct hmac_clrkey_token *)dest; +unsigned int blocksize; +int rc; + + token->type =0x00 ; + token->version =0x02 ; +switch (digestsize) { +case SHA224_DIGEST_SIZE : +case SHA256_DIGEST_SIZE : + token->keytype =PKEY_KEYTYPE_HMAC_512 ; + blocksize =64 ; +break ; +case SHA384_DIGEST_SIZE : +case SHA512_DIGEST_SIZE : + token->keytype =PKEY_KEYTYPE_HMAC_1024 ; + blocksize =128 ; +break ; +default : +return -EINVAL ; + } + token->len = blocksize; + +if (clrkeylen > blocksize) { + rc =hash_key (clrkey, clrkeylen, token->key, digestsize); +if (rc) +return rc; + }else { +memcpy (token->key, clrkey, clrkeylen); + } + +return 0 ; +} +/* * Convert the raw key material into a protected key via PKEY api. * This function may sleep - don't call in non-sleeping context.
@@ -680,6 +788,10 @@ static int s390_phmac_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen) {struct s390_phmac_ctx *tfm_ctx =crypto_ahash_ctx (tfm); +struct crypto_tfm *tfm_base =crypto_ahash_tfm (tfm); +unsigned int ds =crypto_ahash_digestsize (tfm); +unsigned int bs =crypto_ahash_blocksize (tfm); +int rc =0 ;if (tfm_ctx->keylen) {kfree_sensitive (tfm_ctx->key);
@@ -687,10 +799,26 @@ static int s390_phmac_setkey(struct crypto_ahash *tfm, tfm_ctx->keylen =0 ; } - tfm_ctx->key =kmemdup (key, keylen,GFP_ATOMIC ); -if (!tfm_ctx->key) -return -ENOMEM ; - tfm_ctx->keylen = keylen; +if (crypto_tfm_alg_get_flags (tfm_base) &CRYPTO_ALG_TESTED ) { +/* no selftest: key is always a key token digestable by PKEY */ + tfm_ctx->key =kmemdup (key, keylen,GFP_ATOMIC ); +if (!tfm_ctx->key) { + rc = -ENOMEM ; + goto out; + } + tfm_ctx->keylen = keylen; + }else { +/* selftest running: key is a raw hmac clear key */ + tfm_ctx->keylen =sizeof (struct hmac_clrkey_token ) + bs; + tfm_ctx->key =kzalloc (tfm_ctx->keylen,GFP_ATOMIC ); +if (!tfm_ctx->key) { + rc = -ENOMEM ; + goto out; + } + rc =make_clrkey_token (key, keylen, ds, tfm_ctx->key); +if (rc) + goto out; + }/* Always trigger an asynch key convert */ spin_lock_bh (&tfm_ctx->pk_lock);
@@ -698,8 +826,9 @@ static int s390_phmac_setkey(struct crypto_ahash *tfm,spin_unlock_bh (&tfm_ctx->pk_lock);schedule_delayed_work (&tfm_ctx->work,0 ); +out:pr_debug ("rc=0\n" ); -return 0 ; +return rc; }static int s390_phmac_import (struct ahash_request *req,const void *in)
@@ -816,6 +945,11 @@ static int __init phmac_s390_init(void)struct s390_hmac_alg *hmac;int i, rc = -ENODEV ; +if (!cpacf_query_func (CPACF_KLMD ,CPACF_KLMD_SHA_256 )) +return -ENODEV ; +if (!cpacf_query_func (CPACF_KLMD ,CPACF_KLMD_SHA_512 )) +return -ENODEV ; +for (i =0 ; i <ARRAY_SIZE (s390_hmac_algs); i++) { hmac = &s390_hmac_algs[i];if (!cpacf_query_func (CPACF_KMAC , hmac->fc))
crypto/testmgr.c +30 -0
@@ -5539,6 +5539,36 @@ static const struct alg_test_desc alg_test_descs[] = { .cipher = __VECS(fcrypt_pcbc_tv_template) } }, { +#if IS_ENABLED (CONFIG_CRYPTO_PHMAC_S390 ) + .alg = "phmac(sha224)", + .test = alg_test_hash, + .fips_allowed = 1, + .suite = { + .hash =__VECS (hmac_sha224_tv_template) + } + }, { + .alg = "phmac(sha256)", + .test = alg_test_hash, + .fips_allowed = 1, + .suite = { + .hash =__VECS (hmac_sha256_tv_template) + } + }, { + .alg = "phmac(sha384)", + .test = alg_test_hash, + .fips_allowed = 1, + .suite = { + .hash =__VECS (hmac_sha384_tv_template) + } + }, { + .alg = "phmac(sha512)", + .test = alg_test_hash, + .fips_allowed = 1, + .suite = { + .hash =__VECS (hmac_sha512_tv_template) + } + }, { +#endif .alg = "pkcs1(rsa,none)", .test = alg_test_sig, .suite = {
include/linux/crypto.h +5 -0
@@ -472,6 +472,11 @@ static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm)return tfm->__crt_alg->cra_alignmask; } +static inline u32 crypto_tfm_alg_get_flags (struct crypto_tfm *tfm) +{ +return tfm->__crt_alg->cra_flags; +} +static inline u32 crypto_tfm_get_flags (struct crypto_tfm *tfm) {return tfm->crt_flags;
Signature · 1 line
2.43.0
Holger Dengler
maintainerRe: [PATCH v9 3/3] s390/crypto: Enable phmac selftest invocation
Quoted 6 lines · Harald Freudenberger
- Add a little helper inline function
crypto_tfm_alg_get_flags()
tocrypto.hto retrieve the alg flags.
- Add key preparation code in case of selftest running to the phmac setkey function.
- Add phmac selftest invocation to the crypto testmanager.
Can you please split this self-test enablement for phmac into a separate patch series.
Quoted 11 lines
Signed-off-by Harald Freudenberger <[email protected]>--- arch/s390/crypto/phmac_s390.c | 144 ++++++++++++++++++++++++++++++++-- crypto/testmgr.c | 30 +++++++ include/linux/crypto.h | 5 ++ 3 files changed, 174 insertions(+), 5 deletions(-)arch/s390/crypto/phmac_s390.c +0
-0
[...]
Quoted 18 lines
arch/s390/crypto/phmac_s390.c +10
-4@@ -687,10 +799,26 @@ static int s390_phmac_setkey(struct crypto_ahash *tfm, tfm_ctx->keylen =0 ; } - tfm_ctx->key =kmemdup (key, keylen,GFP_ATOMIC ); -if (!tfm_ctx->key) -return -ENOMEM ; - tfm_ctx->keylen = keylen; +if (crypto_tfm_alg_get_flags (tfm_base) &CRYPTO_ALG_TESTED ) { +/* no selftest: key is always a key token digestable by PKEY */ + tfm_ctx->key =kmemdup (key, keylen,GFP_ATOMIC ); +if (!tfm_ctx->key) { + rc = -ENOMEM ; + goto out; + } + tfm_ctx->keylen = keylen; + }else { +/* selftest running: key is a raw hmac clear key */
arch/s390/crypto/phmac_s390.c static int s390_phmac_setkey(struct crypto_ahash *tfm, · line 821
Quoted 10 lines
arch/s390/crypto/phmac_s390.c +10
-0+ tfm_ctx->keylen =sizeof (struct hmac_clrkey_token ) + bs; + tfm_ctx->key =kzalloc (tfm_ctx->keylen,GFP_ATOMIC ); +if (!tfm_ctx->key) { + rc = -ENOMEM ; + goto out; + } + rc =make_clrkey_token (key, keylen, ds, tfm_ctx->key); +if (rc) + goto out; + }
I would prefer, if the conversion of the self-test clear-key is an additional code path and not a replacement. I know, that this might end up in an additional memory allocation, but I think it is worth to do so.
Signature · 5 lines
Mit freundlichen Grüßen / Kind regards Holger Dengler -- IBM Systems, Linux on IBM Z Development [email protected]