diff options
author | Eric Biggers <ebiggers@google.com> | 2019-12-31 06:19:36 +0300 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2020-01-09 06:30:53 +0300 |
commit | 674f368a952c48ede71784935a799a5205b92b6c (patch) | |
tree | e8610dafbeb92ae5f91d53579e071e8ff58303e4 /crypto | |
parent | 5c925e8b10a5f43f220755aceb9d5f14b2f4e2c5 (diff) | |
download | linux-674f368a952c48ede71784935a799a5205b92b6c.tar.xz |
crypto: remove CRYPTO_TFM_RES_BAD_KEY_LEN
The CRYPTO_TFM_RES_BAD_KEY_LEN flag was apparently meant as a way to
make the ->setkey() functions provide more information about errors.
However, no one actually checks for this flag, which makes it pointless.
Also, many algorithms fail to set this flag when given a bad length key.
Reviewing just the generic implementations, this is the case for
aes-fixed-time, cbcmac, echainiv, nhpoly1305, pcrypt, rfc3686, rfc4309,
rfc7539, rfc7539esp, salsa20, seqiv, and xcbc. But there are probably
many more in arch/*/crypto/ and drivers/crypto/.
Some algorithms can even set this flag when the key is the correct
length. For example, authenc and authencesn set it when the key payload
is malformed in any way (not just a bad length), the atmel-sha and ccree
drivers can set it if a memory allocation fails, and the chelsio driver
sets it for bad auth tag lengths, not just bad key lengths.
So even if someone actually wanted to start checking this flag (which
seems unlikely, since it's been unused for a long time), there would be
a lot of work needed to get it working correctly. But it would probably
be much better to go back to the drawing board and just define different
return values, like -EINVAL if the key is invalid for the algorithm vs.
-EKEYREJECTED if the key was rejected by a policy like "no weak keys".
That would be much simpler, less error-prone, and easier to test.
So just remove this flag.
Signed-off-by: Eric Biggers <ebiggers@google.com>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/aegis128-core.c | 4 | ||||
-rw-r--r-- | crypto/aes_generic.c | 18 | ||||
-rw-r--r-- | crypto/anubis.c | 2 | ||||
-rw-r--r-- | crypto/authenc.c | 6 | ||||
-rw-r--r-- | crypto/authencesn.c | 6 | ||||
-rw-r--r-- | crypto/blake2b_generic.c | 4 | ||||
-rw-r--r-- | crypto/blake2s_generic.c | 4 | ||||
-rw-r--r-- | crypto/camellia_generic.c | 5 | ||||
-rw-r--r-- | crypto/cast6_generic.c | 10 | ||||
-rw-r--r-- | crypto/cipher.c | 4 | ||||
-rw-r--r-- | crypto/crc32_generic.c | 4 | ||||
-rw-r--r-- | crypto/crc32c_generic.c | 4 | ||||
-rw-r--r-- | crypto/essiv.c | 4 | ||||
-rw-r--r-- | crypto/ghash-generic.c | 4 | ||||
-rw-r--r-- | crypto/michael_mic.c | 4 | ||||
-rw-r--r-- | crypto/skcipher.c | 4 | ||||
-rw-r--r-- | crypto/sm4_generic.c | 16 | ||||
-rw-r--r-- | crypto/twofish_common.c | 8 | ||||
-rw-r--r-- | crypto/vmac.c | 4 | ||||
-rw-r--r-- | crypto/xxhash_generic.c | 4 |
20 files changed, 31 insertions, 88 deletions
diff --git a/crypto/aegis128-core.c b/crypto/aegis128-core.c index 71c11cb5bad1..44fb4956f0dd 100644 --- a/crypto/aegis128-core.c +++ b/crypto/aegis128-core.c @@ -372,10 +372,8 @@ static int crypto_aegis128_setkey(struct crypto_aead *aead, const u8 *key, { struct aegis_ctx *ctx = crypto_aead_ctx(aead); - if (keylen != AEGIS128_KEY_SIZE) { - crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen != AEGIS128_KEY_SIZE) return -EINVAL; - } memcpy(ctx->key.bytes, key, AEGIS128_KEY_SIZE); return 0; diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c index 22e5867177f1..27ab27931813 100644 --- a/crypto/aes_generic.c +++ b/crypto/aes_generic.c @@ -1127,24 +1127,18 @@ EXPORT_SYMBOL_GPL(crypto_it_tab); * @in_key: The input key. * @key_len: The size of the key. * - * Returns 0 on success, on failure the %CRYPTO_TFM_RES_BAD_KEY_LEN flag in tfm - * is set. The function uses aes_expand_key() to expand the key. - * &crypto_aes_ctx _must_ be the private data embedded in @tfm which is - * retrieved with crypto_tfm_ctx(). + * This function uses aes_expand_key() to expand the key. &crypto_aes_ctx + * _must_ be the private data embedded in @tfm which is retrieved with + * crypto_tfm_ctx(). + * + * Return: 0 on success; -EINVAL on failure (only happens for bad key lengths) */ int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len) { struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm); - u32 *flags = &tfm->crt_flags; - int ret; - - ret = aes_expandkey(ctx, in_key, key_len); - if (!ret) - return 0; - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; - return -EINVAL; + return aes_expandkey(ctx, in_key, key_len); } EXPORT_SYMBOL_GPL(crypto_aes_set_key); diff --git a/crypto/anubis.c b/crypto/anubis.c index f9ce78fde6ee..5da0241ef453 100644 --- a/crypto/anubis.c +++ b/crypto/anubis.c @@ -464,7 +464,6 @@ static int anubis_setkey(struct crypto_tfm *tfm, const u8 *in_key, { struct anubis_ctx *ctx = crypto_tfm_ctx(tfm); const __be32 *key = (const __be32 *)in_key; - u32 *flags = &tfm->crt_flags; int N, R, i, r; u32 kappa[ANUBIS_MAX_N]; u32 inter[ANUBIS_MAX_N]; @@ -474,7 +473,6 @@ static int anubis_setkey(struct crypto_tfm *tfm, const u8 *in_key, case 32: case 36: case 40: break; default: - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; return -EINVAL; } diff --git a/crypto/authenc.c b/crypto/authenc.c index 3f0ed9402582..0da80632e872 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -91,7 +91,7 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, int err = -EINVAL; if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) - goto badkey; + goto out; crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) & @@ -113,10 +113,6 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, out: memzero_explicit(&keys, sizeof(keys)); return err; - -badkey: - crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN); - goto out; } static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err) diff --git a/crypto/authencesn.c b/crypto/authencesn.c index adb7554fca29..749527e1b617 100644 --- a/crypto/authencesn.c +++ b/crypto/authencesn.c @@ -65,7 +65,7 @@ static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 * int err = -EINVAL; if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) - goto badkey; + goto out; crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc_esn) & @@ -87,10 +87,6 @@ static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 * out: memzero_explicit(&keys, sizeof(keys)); return err; - -badkey: - crypto_aead_set_flags(authenc_esn, CRYPTO_TFM_RES_BAD_KEY_LEN); - goto out; } static int crypto_authenc_esn_genicv_tail(struct aead_request *req, diff --git a/crypto/blake2b_generic.c b/crypto/blake2b_generic.c index d04b1788dc42..1d262374fa4e 100644 --- a/crypto/blake2b_generic.c +++ b/crypto/blake2b_generic.c @@ -147,10 +147,8 @@ static int blake2b_setkey(struct crypto_shash *tfm, const u8 *key, { struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(tfm); - if (keylen == 0 || keylen > BLAKE2B_KEYBYTES) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen == 0 || keylen > BLAKE2B_KEYBYTES) return -EINVAL; - } memcpy(tctx->key, key, keylen); tctx->keylen = keylen; diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c index ed0c74640470..005783ff45ad 100644 --- a/crypto/blake2s_generic.c +++ b/crypto/blake2s_generic.c @@ -17,10 +17,8 @@ static int crypto_blake2s_setkey(struct crypto_shash *tfm, const u8 *key, { struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm); - if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE) return -EINVAL; - } memcpy(tctx->key, key, keylen); tctx->keylen = keylen; diff --git a/crypto/camellia_generic.c b/crypto/camellia_generic.c index b6a1121e2478..9a5783e5196a 100644 --- a/crypto/camellia_generic.c +++ b/crypto/camellia_generic.c @@ -970,12 +970,9 @@ camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key, { struct camellia_ctx *cctx = crypto_tfm_ctx(tfm); const unsigned char *key = (const unsigned char *)in_key; - u32 *flags = &tfm->crt_flags; - if (key_len != 16 && key_len != 24 && key_len != 32) { - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + if (key_len != 16 && key_len != 24 && key_len != 32) return -EINVAL; - } cctx->key_length = key_len; diff --git a/crypto/cast6_generic.c b/crypto/cast6_generic.c index 85328522c5ca..c77ff6c8a2b2 100644 --- a/crypto/cast6_generic.c +++ b/crypto/cast6_generic.c @@ -103,17 +103,14 @@ static inline void W(u32 *key, unsigned int i) key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]); } -int __cast6_setkey(struct cast6_ctx *c, const u8 *in_key, - unsigned key_len, u32 *flags) +int __cast6_setkey(struct cast6_ctx *c, const u8 *in_key, unsigned int key_len) { int i; u32 key[8]; __be32 p_key[8]; /* padded key */ - if (key_len % 4 != 0) { - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + if (key_len % 4 != 0) return -EINVAL; - } memset(p_key, 0, 32); memcpy(p_key, in_key, key_len); @@ -148,8 +145,7 @@ EXPORT_SYMBOL_GPL(__cast6_setkey); int cast6_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) { - return __cast6_setkey(crypto_tfm_ctx(tfm), key, keylen, - &tfm->crt_flags); + return __cast6_setkey(crypto_tfm_ctx(tfm), key, keylen); } EXPORT_SYMBOL_GPL(cast6_setkey); diff --git a/crypto/cipher.c b/crypto/cipher.c index aadd51cb7250..0fb7042a709d 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -46,10 +46,8 @@ int crypto_cipher_setkey(struct crypto_cipher *tfm, unsigned long alignmask = crypto_cipher_alignmask(tfm); crypto_cipher_clear_flags(tfm, CRYPTO_TFM_RES_MASK); - if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { - crypto_cipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) return -EINVAL; - } if ((unsigned long)key & alignmask) return setkey_unaligned(tfm, key, keylen); diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c index 9e97912280bd..0e103fb5dd77 100644 --- a/crypto/crc32_generic.c +++ b/crypto/crc32_generic.c @@ -60,10 +60,8 @@ static int crc32_setkey(struct crypto_shash *hash, const u8 *key, { u32 *mctx = crypto_shash_ctx(hash); - if (keylen != sizeof(u32)) { - crypto_shash_set_flags(hash, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen != sizeof(u32)) return -EINVAL; - } *mctx = get_unaligned_le32(key); return 0; } diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c index 7b25fe82072c..7fa9b0788685 100644 --- a/crypto/crc32c_generic.c +++ b/crypto/crc32c_generic.c @@ -74,10 +74,8 @@ static int chksum_setkey(struct crypto_shash *tfm, const u8 *key, { struct chksum_ctx *mctx = crypto_shash_ctx(tfm); - if (keylen != sizeof(mctx->key)) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen != sizeof(mctx->key)) return -EINVAL; - } mctx->key = get_unaligned_le32(key); return 0; } diff --git a/crypto/essiv.c b/crypto/essiv.c index e4b32c2ea7ec..f49bd6fc6972 100644 --- a/crypto/essiv.c +++ b/crypto/essiv.c @@ -117,10 +117,8 @@ static int essiv_aead_setkey(struct crypto_aead *tfm, const u8 *key, if (err) return err; - if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) { - crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) return -EINVAL; - } desc->tfm = tctx->hash; err = crypto_shash_init(desc) ?: diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c index 5027b3461c92..c70d163c1ac9 100644 --- a/crypto/ghash-generic.c +++ b/crypto/ghash-generic.c @@ -58,10 +58,8 @@ static int ghash_setkey(struct crypto_shash *tfm, struct ghash_ctx *ctx = crypto_shash_ctx(tfm); be128 k; - if (keylen != GHASH_BLOCK_SIZE) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen != GHASH_BLOCK_SIZE) return -EINVAL; - } if (ctx->gf128) gf128mul_free_4k(ctx->gf128); diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c index 20e6220f46f6..63350c4ad461 100644 --- a/crypto/michael_mic.c +++ b/crypto/michael_mic.c @@ -137,10 +137,8 @@ static int michael_setkey(struct crypto_shash *tfm, const u8 *key, const __le32 *data = (const __le32 *)key; - if (keylen != 8) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen != 8) return -EINVAL; - } mctx->l = le32_to_cpu(data[0]); mctx->r = le32_to_cpu(data[1]); diff --git a/crypto/skcipher.c b/crypto/skcipher.c index 457e4ddc1482..8c8735f75478 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c @@ -603,10 +603,8 @@ int crypto_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned long alignmask = crypto_skcipher_alignmask(tfm); int err; - if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { - crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) return -EINVAL; - } if ((unsigned long)key & alignmask) err = skcipher_setkey_unaligned(tfm, key, keylen); diff --git a/crypto/sm4_generic.c b/crypto/sm4_generic.c index 71ffb343709a..016dbc595705 100644 --- a/crypto/sm4_generic.c +++ b/crypto/sm4_generic.c @@ -143,29 +143,23 @@ int crypto_sm4_expand_key(struct crypto_sm4_ctx *ctx, const u8 *in_key, EXPORT_SYMBOL_GPL(crypto_sm4_expand_key); /** - * crypto_sm4_set_key - Set the AES key. + * crypto_sm4_set_key - Set the SM4 key. * @tfm: The %crypto_tfm that is used in the context. * @in_key: The input key. * @key_len: The size of the key. * - * Returns 0 on success, on failure the %CRYPTO_TFM_RES_BAD_KEY_LEN flag in tfm - * is set. The function uses crypto_sm4_expand_key() to expand the key. + * This function uses crypto_sm4_expand_key() to expand the key. * &crypto_sm4_ctx _must_ be the private data embedded in @tfm which is * retrieved with crypto_tfm_ctx(). + * + * Return: 0 on success; -EINVAL on failure (only happens for bad key lengths) */ int crypto_sm4_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len) { struct crypto_sm4_ctx *ctx = crypto_tfm_ctx(tfm); - u32 *flags = &tfm->crt_flags; - int ret; - - ret = crypto_sm4_expand_key(ctx, in_key, key_len); - if (!ret) - return 0; - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; - return -EINVAL; + return crypto_sm4_expand_key(ctx, in_key, key_len); } EXPORT_SYMBOL_GPL(crypto_sm4_set_key); diff --git a/crypto/twofish_common.c b/crypto/twofish_common.c index 222fc765c57a..d23fa531b91f 100644 --- a/crypto/twofish_common.c +++ b/crypto/twofish_common.c @@ -567,7 +567,7 @@ static const u8 calc_sb_tbl[512] = { /* Perform the key setup. */ int __twofish_setkey(struct twofish_ctx *ctx, const u8 *key, - unsigned int key_len, u32 *flags) + unsigned int key_len) { int i, j, k; @@ -584,10 +584,7 @@ int __twofish_setkey(struct twofish_ctx *ctx, const u8 *key, /* Check key length. */ if (key_len % 8) - { - *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; return -EINVAL; /* unsupported key length */ - } /* Compute the first two words of the S vector. The magic numbers are * the entries of the RS matrix, preprocessed through poly_to_exp. The @@ -688,8 +685,7 @@ EXPORT_SYMBOL_GPL(__twofish_setkey); int twofish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len) { - return __twofish_setkey(crypto_tfm_ctx(tfm), key, key_len, - &tfm->crt_flags); + return __twofish_setkey(crypto_tfm_ctx(tfm), key, key_len); } EXPORT_SYMBOL_GPL(twofish_setkey); diff --git a/crypto/vmac.c b/crypto/vmac.c index f50a85060b39..0bbb34dc87c4 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -435,10 +435,8 @@ static int vmac_setkey(struct crypto_shash *tfm, unsigned int i; int err; - if (keylen != VMAC_KEY_LEN) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen != VMAC_KEY_LEN) return -EINVAL; - } err = crypto_cipher_setkey(tctx->cipher, key, keylen); if (err) diff --git a/crypto/xxhash_generic.c b/crypto/xxhash_generic.c index 4aad2c0f40a9..55d1c8a76127 100644 --- a/crypto/xxhash_generic.c +++ b/crypto/xxhash_generic.c @@ -22,10 +22,8 @@ static int xxhash64_setkey(struct crypto_shash *tfm, const u8 *key, { struct xxhash64_tfm_ctx *tctx = crypto_shash_ctx(tfm); - if (keylen != sizeof(tctx->seed)) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + if (keylen != sizeof(tctx->seed)) return -EINVAL; - } tctx->seed = get_unaligned_le64(key); return 0; } |