crypto: crypto4xx - block ciphers should only accept complete blocks
The hardware automatically zero pads incomplete block ciphers blocks without raising any errors. This is a screw-up. This was noticed by CONFIG_CRYPTO_MANAGER_EXTRA_TESTS tests that sent a incomplete blocks and expect them to fail. This fixes: cbc-aes-ppc4xx encryption unexpectedly succeeded on test vector "random: len=2409 klen=32"; expected_error=-22, cfg="random: may_sleep use_digest src_divs=[96.90%@+2295, 2.34%@+4066, 0.32%@alignmask+12, 0.34%@+4087, 0.9%@alignmask+1787, 0.1%@+3767] iv_offset=6" ecb-aes-ppc4xx encryption unexpectedly succeeded on test vector "random: len=1011 klen=32"; expected_error=-22, cfg="random: may_sleep use_digest src_divs=[100.0%@alignmask+20] dst_divs=[3.12%@+3001, 96.88%@+4070]" Cc: Eric Biggers <ebiggers@kernel.org> Cc: stable@vger.kernel.org [4.19, 5.0 and 5.1] Signed-off-by: Christian Lamparter <chunkeey@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
70c4997f34
commit
0f7a813740
|
@ -76,12 +76,16 @@ static void set_dynamic_sa_command_1(struct dynamic_sa_ctl *sa, u32 cm,
|
|||
}
|
||||
|
||||
static inline int crypto4xx_crypt(struct skcipher_request *req,
|
||||
const unsigned int ivlen, bool decrypt)
|
||||
const unsigned int ivlen, bool decrypt,
|
||||
bool check_blocksize)
|
||||
{
|
||||
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
|
||||
struct crypto4xx_ctx *ctx = crypto_skcipher_ctx(cipher);
|
||||
__le32 iv[AES_IV_SIZE];
|
||||
|
||||
if (check_blocksize && !IS_ALIGNED(req->cryptlen, AES_BLOCK_SIZE))
|
||||
return -EINVAL;
|
||||
|
||||
if (ivlen)
|
||||
crypto4xx_memcpy_to_le32(iv, req->iv, ivlen);
|
||||
|
||||
|
@ -90,24 +94,34 @@ static inline int crypto4xx_crypt(struct skcipher_request *req,
|
|||
ctx->sa_len, 0, NULL);
|
||||
}
|
||||
|
||||
int crypto4xx_encrypt_noiv(struct skcipher_request *req)
|
||||
int crypto4xx_encrypt_noiv_block(struct skcipher_request *req)
|
||||
{
|
||||
return crypto4xx_crypt(req, 0, false);
|
||||
return crypto4xx_crypt(req, 0, false, true);
|
||||
}
|
||||
|
||||
int crypto4xx_encrypt_iv(struct skcipher_request *req)
|
||||
int crypto4xx_encrypt_iv_stream(struct skcipher_request *req)
|
||||
{
|
||||
return crypto4xx_crypt(req, AES_IV_SIZE, false);
|
||||
return crypto4xx_crypt(req, AES_IV_SIZE, false, false);
|
||||
}
|
||||
|
||||
int crypto4xx_decrypt_noiv(struct skcipher_request *req)
|
||||
int crypto4xx_decrypt_noiv_block(struct skcipher_request *req)
|
||||
{
|
||||
return crypto4xx_crypt(req, 0, true);
|
||||
return crypto4xx_crypt(req, 0, true, true);
|
||||
}
|
||||
|
||||
int crypto4xx_decrypt_iv(struct skcipher_request *req)
|
||||
int crypto4xx_decrypt_iv_stream(struct skcipher_request *req)
|
||||
{
|
||||
return crypto4xx_crypt(req, AES_IV_SIZE, true);
|
||||
return crypto4xx_crypt(req, AES_IV_SIZE, true, false);
|
||||
}
|
||||
|
||||
int crypto4xx_encrypt_iv_block(struct skcipher_request *req)
|
||||
{
|
||||
return crypto4xx_crypt(req, AES_IV_SIZE, false, true);
|
||||
}
|
||||
|
||||
int crypto4xx_decrypt_iv_block(struct skcipher_request *req)
|
||||
{
|
||||
return crypto4xx_crypt(req, AES_IV_SIZE, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,8 +292,8 @@ crypto4xx_ctr_crypt(struct skcipher_request *req, bool encrypt)
|
|||
return ret;
|
||||
}
|
||||
|
||||
return encrypt ? crypto4xx_encrypt_iv(req)
|
||||
: crypto4xx_decrypt_iv(req);
|
||||
return encrypt ? crypto4xx_encrypt_iv_stream(req)
|
||||
: crypto4xx_decrypt_iv_stream(req);
|
||||
}
|
||||
|
||||
static int crypto4xx_sk_setup_fallback(struct crypto4xx_ctx *ctx,
|
||||
|
|
|
@ -1219,8 +1219,8 @@ static struct crypto4xx_alg_common crypto4xx_alg[] = {
|
|||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.ivsize = AES_IV_SIZE,
|
||||
.setkey = crypto4xx_setkey_aes_cbc,
|
||||
.encrypt = crypto4xx_encrypt_iv,
|
||||
.decrypt = crypto4xx_decrypt_iv,
|
||||
.encrypt = crypto4xx_encrypt_iv_block,
|
||||
.decrypt = crypto4xx_decrypt_iv_block,
|
||||
.init = crypto4xx_sk_init,
|
||||
.exit = crypto4xx_sk_exit,
|
||||
} },
|
||||
|
@ -1239,8 +1239,8 @@ static struct crypto4xx_alg_common crypto4xx_alg[] = {
|
|||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.ivsize = AES_IV_SIZE,
|
||||
.setkey = crypto4xx_setkey_aes_cfb,
|
||||
.encrypt = crypto4xx_encrypt_iv,
|
||||
.decrypt = crypto4xx_decrypt_iv,
|
||||
.encrypt = crypto4xx_encrypt_iv_stream,
|
||||
.decrypt = crypto4xx_decrypt_iv_stream,
|
||||
.init = crypto4xx_sk_init,
|
||||
.exit = crypto4xx_sk_exit,
|
||||
} },
|
||||
|
@ -1299,8 +1299,8 @@ static struct crypto4xx_alg_common crypto4xx_alg[] = {
|
|||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.setkey = crypto4xx_setkey_aes_ecb,
|
||||
.encrypt = crypto4xx_encrypt_noiv,
|
||||
.decrypt = crypto4xx_decrypt_noiv,
|
||||
.encrypt = crypto4xx_encrypt_noiv_block,
|
||||
.decrypt = crypto4xx_decrypt_noiv_block,
|
||||
.init = crypto4xx_sk_init,
|
||||
.exit = crypto4xx_sk_exit,
|
||||
} },
|
||||
|
@ -1319,8 +1319,8 @@ static struct crypto4xx_alg_common crypto4xx_alg[] = {
|
|||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.ivsize = AES_IV_SIZE,
|
||||
.setkey = crypto4xx_setkey_aes_ofb,
|
||||
.encrypt = crypto4xx_encrypt_iv,
|
||||
.decrypt = crypto4xx_decrypt_iv,
|
||||
.encrypt = crypto4xx_encrypt_iv_stream,
|
||||
.decrypt = crypto4xx_decrypt_iv_stream,
|
||||
.init = crypto4xx_sk_init,
|
||||
.exit = crypto4xx_sk_exit,
|
||||
} },
|
||||
|
|
|
@ -182,10 +182,12 @@ int crypto4xx_setkey_rfc3686(struct crypto_skcipher *cipher,
|
|||
const u8 *key, unsigned int keylen);
|
||||
int crypto4xx_encrypt_ctr(struct skcipher_request *req);
|
||||
int crypto4xx_decrypt_ctr(struct skcipher_request *req);
|
||||
int crypto4xx_encrypt_iv(struct skcipher_request *req);
|
||||
int crypto4xx_decrypt_iv(struct skcipher_request *req);
|
||||
int crypto4xx_encrypt_noiv(struct skcipher_request *req);
|
||||
int crypto4xx_decrypt_noiv(struct skcipher_request *req);
|
||||
int crypto4xx_encrypt_iv_stream(struct skcipher_request *req);
|
||||
int crypto4xx_decrypt_iv_stream(struct skcipher_request *req);
|
||||
int crypto4xx_encrypt_iv_block(struct skcipher_request *req);
|
||||
int crypto4xx_decrypt_iv_block(struct skcipher_request *req);
|
||||
int crypto4xx_encrypt_noiv_block(struct skcipher_request *req);
|
||||
int crypto4xx_decrypt_noiv_block(struct skcipher_request *req);
|
||||
int crypto4xx_rfc3686_encrypt(struct skcipher_request *req);
|
||||
int crypto4xx_rfc3686_decrypt(struct skcipher_request *req);
|
||||
int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm);
|
||||
|
|
Loading…
Reference in New Issue