Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: rsassa-pkcs1 - Harden digest length verification

The RSASSA-PKCS1-v1_5 sign operation currently only checks that the
digest length is less than "key_size - hash_prefix->size - 11".
The verify operation merely checks that it's more than zero.

Actually the precise digest length is known because the hash algorithm
is specified upon instance creation and the digest length is encoded
into the final byte of the hash algorithm's Full Hash Prefix.

So check for the exact digest length rather than solely relying on
imprecise maximum/minimum checks.

Keep the maximum length check for the sign operation as a safety net,
but drop the now unnecessary minimum check for the verify operation.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Lukas Wunner and committed by
Herbert Xu
5e00481b 1e562dea

+19 -1
+19 -1
crypto/rsassa-pkcs1.c
··· 11 11 #include <linux/scatterlist.h> 12 12 #include <crypto/akcipher.h> 13 13 #include <crypto/algapi.h> 14 + #include <crypto/hash.h> 14 15 #include <crypto/sig.h> 15 16 #include <crypto/internal/akcipher.h> 16 17 #include <crypto/internal/rsa.h> ··· 119 118 return NULL; 120 119 } 121 120 121 + static unsigned int rsassa_pkcs1_hash_len(const struct hash_prefix *p) 122 + { 123 + /* 124 + * The final byte of the Full Hash Prefix encodes the hash length. 125 + * 126 + * This needs to be revisited should hash algorithms with more than 127 + * 1016 bits (127 bytes * 8) ever be added. The length would then 128 + * be encoded into more than one byte by ASN.1. 129 + */ 130 + static_assert(HASH_MAX_DIGESTSIZE <= 127); 131 + 132 + return p->data[p->size - 1]; 133 + } 134 + 122 135 struct rsassa_pkcs1_ctx { 123 136 struct crypto_akcipher *child; 124 137 unsigned int key_size; ··· 166 151 167 152 if (dlen < ctx->key_size) 168 153 return -EOVERFLOW; 154 + 155 + if (slen != rsassa_pkcs1_hash_len(hash_prefix)) 156 + return -EINVAL; 169 157 170 158 if (slen + hash_prefix->size > ctx->key_size - 11) 171 159 return -EOVERFLOW; ··· 235 217 /* RFC 8017 sec 8.2.2 step 1 - length checking */ 236 218 if (!ctx->key_size || 237 219 slen != ctx->key_size || 238 - !dlen) 220 + dlen != rsassa_pkcs1_hash_len(hash_prefix)) 239 221 return -EINVAL; 240 222 241 223 /* RFC 8017 sec 8.2.2 step 2 - RSA verification */