From a91a5c25a2c3f652178b591facc2395a7dbb59af Mon Sep 17 00:00:00 2001 From: Holger Dengler Date: Thu, 20 Aug 2026 17:50:03 +0200 Subject: s390/zcrypt: Validate length in reply before using it The length information in the reply is used to copy the key token to the target buffer. An invalid information in t->len of the reply may cause an over-read of the target buffer and also a over-write of the target buffer. To prevent that, check t->len before using it. As the available space in destination and source buffer is always larger than the valid length value in the parameter block in the reply, compare t->len with this (already validated) length information. As a side effect, this check also prevents buffer over-read and over-write. Reviewed-by: Harald Freudenberger Signed-off-by: Holger Dengler Signed-off-by: Vasily Gorbik Signed-off-by: Heiko Carstens --- drivers/s390/crypto/zcrypt_ccamisc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers/s390/crypto') diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c index d4ce6352b5b2..19909bf43dc9 100644 --- a/drivers/s390/crypto/zcrypt_ccamisc.c +++ b/drivers/s390/crypto/zcrypt_ccamisc.c @@ -1158,8 +1158,21 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain, /* do not check the key here, it may be incomplete */ - /* copy the vlsc key token back */ + /* + * Copy the vlsc key token back. + * The available space in the destination (key_token) and the source + * (t) buffer is always larger as the valid range of prepparm->kb.len. + * Validate t->len by comparing it with the length information in the + * param block of the request (prepparm->kb.len) + * The value range of prepparm->kb.len has been checked above. + */ t = (struct cipherkeytoken *)prepparm->kb.tlv1.key_token; + if (t->len != prepparm->kb.len - 3 * sizeof(uint16_t)) { + ZCRYPT_DBF_ERR("%s reply with invalid key_token length %u\n", + __func__, t->len); + rc = -EIO; + goto out; + } memcpy(key_token, t, t->len); *key_token_size = t->len; -- cgit v1.2.3 From 98d23edcd41432286cf03672252507a841323c8c Mon Sep 17 00:00:00 2001 From: Harald Freudenberger Date: Tue, 25 Aug 2026 18:01:54 +0200 Subject: s390/zcrypt: Fix uninitialized padding in CRT key structure The zcrypt_type6_crt_key() function leaves padding bytes uninitialized between key components and the modulus in the CCA CRT key token. These padding bytes are sent to the crypto card, potentially leaking kernel memory contents. The initial memset() only zeros fixed structure fields, not the flexible array member key_parts[] where the padding resides. While key components are properly copied from userspace, the calculated pad_len bytes between them remain uninitialized. Fix by explicitly zeroing the padding bytes after copying the CRT key components. Signed-off-by: Harald Freudenberger Reviewed-by: Finn Callies Signed-off-by: Vasily Gorbik Signed-off-by: Heiko Carstens --- drivers/s390/crypto/zcrypt_cca_key.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/s390/crypto') diff --git a/drivers/s390/crypto/zcrypt_cca_key.h b/drivers/s390/crypto/zcrypt_cca_key.h index f5907b67db29..8a69eed75040 100644 --- a/drivers/s390/crypto/zcrypt_cca_key.h +++ b/drivers/s390/crypto/zcrypt_cca_key.h @@ -219,6 +219,7 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p) copy_from_user(key->key_parts + 2 * long_len + 2 * short_len, crt->u_mult_inv, long_len)) return -EFAULT; + memset(key->key_parts + 3 * long_len + 2 * short_len, 0, pad_len); memset(key->key_parts + 3 * long_len + 2 * short_len + pad_len, 0xff, crt->inputdatalength); pub = (struct cca_public_sec *)(key->key_parts + key_len); -- cgit v1.2.3