Calculate the SHA256 hash for blacklisting purposes independently of the signature hash (which may be something other than SHA256).
This is necessary because when ML-DSA is used, no digest is calculated. Note that this represents a change of behaviour in that the hash used for the blacklist check would previously have been whatever digest was used for, say, RSA-based signatures. It may be that this is inadvisable. Signed-off-by: David Howells <[email protected]> cc: Lukas Wunner <[email protected]> cc: Ignat Korchagin <[email protected]> cc: Stephan Mueller <[email protected]> cc: Eric Biggers <[email protected]> cc: Herbert Xu <[email protected]> cc: [email protected] cc: [email protected] --- crypto/asymmetric_keys/x509_parser.h | 2 ++ crypto/asymmetric_keys/x509_public_key.c | 23 +++++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h index 0688c222806b..b7aeebdddb36 100644 --- a/crypto/asymmetric_keys/x509_parser.h +++ b/crypto/asymmetric_keys/x509_parser.h @@ -9,12 +9,14 @@ #include <linux/time.h> #include <crypto/public_key.h> #include <keys/asymmetric-type.h> +#include <crypto/sha2.h> struct x509_certificate { struct x509_certificate *next; struct x509_certificate *signer; /* Certificate that signed this one */ struct public_key *pub; /* Public key details */ struct public_key_signature *sig; /* Signature parameters */ + u8 sha256[SHA256_DIGEST_SIZE]; /* Hash for blacklist purposes */ char *issuer; /* Name of certificate issuer */ char *subject; /* Name of certificate subject */ struct asymmetric_key_id *id; /* Issuer + Serial number */ diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 12e3341e806b..6d002e3b20c5 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -31,6 +31,19 @@ int x509_get_sig_params(struct x509_certificate *cert) pr_devel("==>%s()\n", __func__); + /* Calculate a SHA256 hash of the TBS and check it against the + * blacklist. + */ + sha256(cert->tbs, cert->tbs_size, cert->sha256); + ret = is_hash_blacklisted(cert->sha256, sizeof(cert->sha256), + BLACKLIST_HASH_X509_TBS); + if (ret == -EKEYREJECTED) { + pr_err("Cert %*phN is blacklisted\n", + (int)sizeof(cert->sha256), cert->sha256); + cert->blacklisted = true; + ret = 0; + } + sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL); if (!sig->s) return -ENOMEM; @@ -65,19 +78,9 @@ int x509_get_sig_params(struct x509_certificate *cert) ret = crypto_shash_digest(desc, cert->tbs, cert->tbs_size, sig->digest); - if (ret < 0) goto error_2; - ret = is_hash_blacklisted(sig->digest, sig->digest_size, - BLACKLIST_HASH_X509_TBS); - if (ret == -EKEYREJECTED) { - pr_err("Cert %*phN is blacklisted\n", - sig->digest_size, sig->digest); - cert->blacklisted = true; - ret = 0; - } - error_2: kfree(desc); error:
