Skip to content

Commit

Permalink
crypto: remove CRYPTO_TFM_RES_BAD_KEY_LEN
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Horia Geantă <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
ebiggers authored and herbertx committed Jan 9, 2020
1 parent 5c925e8 commit 674f368
Show file tree
Hide file tree
Showing 93 changed files with 167 additions and 561 deletions.
14 changes: 2 additions & 12 deletions arch/arm/crypto/aes-ce-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,8 @@ static int ce_aes_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
unsigned int key_len)
{
struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
int ret;

ret = ce_aes_expandkey(ctx, in_key, key_len);
if (!ret)
return 0;

crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
return ce_aes_expandkey(ctx, in_key, key_len);
}

struct crypto_aes_xts_ctx {
Expand All @@ -167,11 +161,7 @@ static int xts_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
if (!ret)
ret = ce_aes_expandkey(&ctx->key2, &in_key[key_len / 2],
key_len / 2);
if (!ret)
return 0;

crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
return ret;
}

static int ecb_encrypt(struct skcipher_request *req)
Expand Down
4 changes: 1 addition & 3 deletions arch/arm/crypto/crc32-ce-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,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 = le32_to_cpup((__le32 *)key);
return 0;
}
Expand Down
4 changes: 1 addition & 3 deletions arch/arm/crypto/ghash-ce-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,8 @@ static int ghash_setkey(struct crypto_shash *tfm,
struct ghash_key *key = crypto_shash_ctx(tfm);
be128 h;

if (keylen != GHASH_BLOCK_SIZE) {
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
if (keylen != GHASH_BLOCK_SIZE)
return -EINVAL;
}

/* needed for the fallback */
memcpy(&key->k, inkey, GHASH_BLOCK_SIZE);
Expand Down
8 changes: 1 addition & 7 deletions arch/arm64/crypto/aes-ce-ccm-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,8 @@ static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key,
unsigned int key_len)
{
struct crypto_aes_ctx *ctx = crypto_aead_ctx(tfm);
int ret;

ret = ce_aes_expandkey(ctx, in_key, key_len);
if (!ret)
return 0;

tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
return ce_aes_expandkey(ctx, in_key, key_len);
}

static int ccm_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
Expand Down
8 changes: 1 addition & 7 deletions arch/arm64/crypto/aes-ce-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,8 @@ int ce_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len)
{
struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
int ret;

ret = ce_aes_expandkey(ctx, in_key, key_len);
if (!ret)
return 0;

tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
return ce_aes_expandkey(ctx, in_key, key_len);
}
EXPORT_SYMBOL(ce_aes_setkey);

Expand Down
31 changes: 5 additions & 26 deletions arch/arm64/crypto/aes-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,8 @@ static int skcipher_aes_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
unsigned int key_len)
{
struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
int ret;

ret = aes_expandkey(ctx, in_key, key_len);
if (ret)
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);

return ret;
return aes_expandkey(ctx, in_key, key_len);
}

static int __maybe_unused xts_set_key(struct crypto_skcipher *tfm,
Expand All @@ -155,11 +150,7 @@ static int __maybe_unused xts_set_key(struct crypto_skcipher *tfm,
if (!ret)
ret = aes_expandkey(&ctx->key2, &in_key[key_len / 2],
key_len / 2);
if (!ret)
return 0;

crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
return ret;
}

static int __maybe_unused essiv_cbc_set_key(struct crypto_skcipher *tfm,
Expand All @@ -173,19 +164,12 @@ static int __maybe_unused essiv_cbc_set_key(struct crypto_skcipher *tfm,

ret = aes_expandkey(&ctx->key1, in_key, key_len);
if (ret)
goto out;
return ret;

desc->tfm = ctx->hash;
crypto_shash_digest(desc, in_key, key_len, digest);

ret = aes_expandkey(&ctx->key2, digest, sizeof(digest));
if (ret)
goto out;

return 0;
out:
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
return aes_expandkey(&ctx->key2, digest, sizeof(digest));
}

static int __maybe_unused ecb_encrypt(struct skcipher_request *req)
Expand Down Expand Up @@ -791,13 +775,8 @@ static int cbcmac_setkey(struct crypto_shash *tfm, const u8 *in_key,
unsigned int key_len)
{
struct mac_tfm_ctx *ctx = crypto_shash_ctx(tfm);
int err;

err = aes_expandkey(&ctx->key, in_key, key_len);
if (err)
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);

return err;
return aes_expandkey(&ctx->key, in_key, key_len);
}

static void cmac_gf128_mul_by_x(be128 *y, const be128 *x)
Expand Down
8 changes: 2 additions & 6 deletions arch/arm64/crypto/ghash-ce-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,8 @@ static int ghash_setkey(struct crypto_shash *tfm,
{
struct ghash_key *key = crypto_shash_ctx(tfm);

if (keylen != GHASH_BLOCK_SIZE) {
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
if (keylen != GHASH_BLOCK_SIZE)
return -EINVAL;
}

return __ghash_setkey(key, inkey, keylen);
}
Expand Down Expand Up @@ -306,10 +304,8 @@ static int gcm_setkey(struct crypto_aead *tfm, const u8 *inkey,
int ret;

ret = aes_expandkey(&ctx->aes_key, inkey, keylen);
if (ret) {
tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
if (ret)
return -EINVAL;
}

aes_encrypt(&ctx->aes_key, key, (u8[AES_BLOCK_SIZE]){});

Expand Down
4 changes: 1 addition & 3 deletions arch/mips/crypto/crc32-mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,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;
}
Expand Down
18 changes: 4 additions & 14 deletions arch/powerpc/crypto/aes-spe-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,6 @@ static int ppc_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
{
struct ppc_aes_ctx *ctx = crypto_tfm_ctx(tfm);

if (key_len != AES_KEYSIZE_128 &&
key_len != AES_KEYSIZE_192 &&
key_len != AES_KEYSIZE_256) {
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}

switch (key_len) {
case AES_KEYSIZE_128:
ctx->rounds = 4;
Expand All @@ -114,6 +107,8 @@ static int ppc_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
ctx->rounds = 6;
ppc_expand_key_256(ctx->key_enc, in_key);
break;
default:
return -EINVAL;
}

ppc_generate_decrypt_key(ctx->key_dec, ctx->key_enc, key_len);
Expand All @@ -139,13 +134,6 @@ static int ppc_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key,

key_len >>= 1;

if (key_len != AES_KEYSIZE_128 &&
key_len != AES_KEYSIZE_192 &&
key_len != AES_KEYSIZE_256) {
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}

switch (key_len) {
case AES_KEYSIZE_128:
ctx->rounds = 4;
Expand All @@ -162,6 +150,8 @@ static int ppc_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
ppc_expand_key_256(ctx->key_enc, in_key);
ppc_expand_key_256(ctx->key_twk, in_key + AES_KEYSIZE_256);
break;
default:
return -EINVAL;
}

ppc_generate_decrypt_key(ctx->key_dec, ctx->key_enc, key_len);
Expand Down
4 changes: 1 addition & 3 deletions arch/powerpc/crypto/crc32c-vpmsum_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,8 @@ static int crc32c_vpmsum_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 = le32_to_cpup((__le32 *)key);
return 0;
}
Expand Down
4 changes: 1 addition & 3 deletions arch/s390/crypto/aes_s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,8 @@ static int xts_aes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
return err;

/* In fips mode only 128 bit or 256 bit keys are valid */
if (fips_enabled && key_len != 32 && key_len != 64) {
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
if (fips_enabled && key_len != 32 && key_len != 64)
return -EINVAL;
}

/* Pick the correct function code based on the key length */
fc = (key_len == 32) ? CPACF_KM_XTS_128 :
Expand Down
8 changes: 2 additions & 6 deletions arch/s390/crypto/crc32-vx.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,8 @@ static int crc32_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
{
struct crc_ctx *mctx = crypto_shash_ctx(tfm);

if (newkeylen != sizeof(mctx->key)) {
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
if (newkeylen != sizeof(mctx->key))
return -EINVAL;
}
mctx->key = le32_to_cpu(*(__le32 *)newkey);
return 0;
}
Expand All @@ -124,10 +122,8 @@ static int crc32be_vx_setkey(struct crypto_shash *tfm, const u8 *newkey,
{
struct crc_ctx *mctx = crypto_shash_ctx(tfm);

if (newkeylen != sizeof(mctx->key)) {
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
if (newkeylen != sizeof(mctx->key))
return -EINVAL;
}
mctx->key = be32_to_cpu(*(__be32 *)newkey);
return 0;
}
Expand Down
4 changes: 1 addition & 3 deletions arch/s390/crypto/ghash_s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ static int ghash_setkey(struct crypto_shash *tfm,
{
struct ghash_ctx *ctx = crypto_shash_ctx(tfm);

if (keylen != GHASH_BLOCK_SIZE) {
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
if (keylen != GHASH_BLOCK_SIZE)
return -EINVAL;
}

memcpy(ctx->key, key, GHASH_BLOCK_SIZE);

Expand Down
25 changes: 6 additions & 19 deletions arch/s390/crypto/paes_s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,7 @@ static int ecb_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
if (rc)
return rc;

if (__paes_set_key(ctx)) {
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
return 0;
return __paes_set_key(ctx);
}

static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
Expand Down Expand Up @@ -254,11 +250,7 @@ static int cbc_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
if (rc)
return rc;

if (__cbc_paes_set_key(ctx)) {
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
return 0;
return __cbc_paes_set_key(ctx);
}

static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
Expand Down Expand Up @@ -386,10 +378,9 @@ static int xts_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
if (rc)
return rc;

if (__xts_paes_set_key(ctx)) {
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
rc = __xts_paes_set_key(ctx);
if (rc)
return rc;

/*
* xts_check_key verifies the key length is not odd and makes
Expand Down Expand Up @@ -526,11 +517,7 @@ static int ctr_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
if (rc)
return rc;

if (__ctr_paes_set_key(ctx)) {
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
return 0;
return __ctr_paes_set_key(ctx);
}

static unsigned int __ctrblk_init(u8 *ctrptr, u8 *iv, unsigned int nbytes)
Expand Down
2 changes: 0 additions & 2 deletions arch/sparc/crypto/aes_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len)
{
struct crypto_sparc64_aes_ctx *ctx = crypto_tfm_ctx(tfm);
u32 *flags = &tfm->crt_flags;

switch (key_len) {
case AES_KEYSIZE_128:
Expand All @@ -188,7 +187,6 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
break;

default:
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}

Expand Down
5 changes: 1 addition & 4 deletions arch/sparc/crypto/camellia_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,9 @@ static int camellia_set_key(struct crypto_tfm *tfm, const u8 *_in_key,
{
struct camellia_sparc64_ctx *ctx = crypto_tfm_ctx(tfm);
const u32 *in_key = (const u32 *) _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;
}

ctx->key_len = key_len;

Expand Down
4 changes: 1 addition & 3 deletions arch/sparc/crypto/crc32c_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ static int crc32c_sparc64_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;
}
*(__le32 *)mctx = le32_to_cpup((__le32 *)key);
return 0;
}
Expand Down
4 changes: 1 addition & 3 deletions arch/x86/crypto/aegis128-aesni-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,8 @@ static int crypto_aegis128_aesni_setkey(struct crypto_aead *aead, const u8 *key,
{
struct aegis_ctx *ctx = crypto_aegis128_aesni_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);

Expand Down
Loading

0 comments on commit 674f368

Please sign in to comment.