mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 14:53:58 -04:00
crypto: caam - check key length
Check key length to solve the extra tests that expect -EINVAL to be returned when the key size is not valid. Validated AES keylen for skcipher, ahash and aead. Signed-off-by: Iuliana Prodan <iuliana.prodan@nxp.com> Reviewed-by: Horia Geanta <horia.geanta@nxp.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
committed by
Herbert Xu
parent
1ccb39eb5a
commit
836d8f43c5
@@ -732,7 +732,13 @@ static int gcm_setkey(struct crypto_aead *aead,
|
||||
{
|
||||
struct caam_ctx *ctx = crypto_aead_ctx(aead);
|
||||
struct device *dev = ctx->dev;
|
||||
int ret;
|
||||
|
||||
ret = aes_check_keylen(keylen);
|
||||
if (ret) {
|
||||
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return ret;
|
||||
}
|
||||
print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
|
||||
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
|
||||
|
||||
@@ -818,9 +824,13 @@ static int rfc4106_setkey(struct crypto_aead *aead,
|
||||
{
|
||||
struct caam_ctx *ctx = crypto_aead_ctx(aead);
|
||||
struct device *dev = ctx->dev;
|
||||
int ret;
|
||||
|
||||
if (keylen < 4)
|
||||
return -EINVAL;
|
||||
ret = aes_check_keylen(keylen - 4);
|
||||
if (ret) {
|
||||
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
|
||||
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
|
||||
@@ -912,9 +922,13 @@ static int rfc4543_setkey(struct crypto_aead *aead,
|
||||
{
|
||||
struct caam_ctx *ctx = crypto_aead_ctx(aead);
|
||||
struct device *dev = ctx->dev;
|
||||
int ret;
|
||||
|
||||
if (keylen < 4)
|
||||
return -EINVAL;
|
||||
ret = aes_check_keylen(keylen - 4);
|
||||
if (ret) {
|
||||
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return ret;
|
||||
}
|
||||
|
||||
print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
|
||||
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
|
||||
@@ -932,7 +946,7 @@ static int rfc4543_setkey(struct crypto_aead *aead,
|
||||
}
|
||||
|
||||
static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
|
||||
unsigned int keylen)
|
||||
unsigned int keylen, const u32 ctx1_iv_off)
|
||||
{
|
||||
struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
|
||||
struct caam_skcipher_alg *alg =
|
||||
@@ -942,34 +956,11 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
|
||||
struct caam_flc *flc;
|
||||
unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
|
||||
u32 *desc;
|
||||
u32 ctx1_iv_off = 0;
|
||||
const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
|
||||
OP_ALG_AAI_CTR_MOD128) &&
|
||||
((ctx->cdata.algtype & OP_ALG_ALGSEL_MASK) !=
|
||||
OP_ALG_ALGSEL_CHACHA20);
|
||||
const bool is_rfc3686 = alg->caam.rfc3686;
|
||||
|
||||
print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
|
||||
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
|
||||
|
||||
/*
|
||||
* AES-CTR needs to load IV in CONTEXT1 reg
|
||||
* at an offset of 128bits (16bytes)
|
||||
* CONTEXT1[255:128] = IV
|
||||
*/
|
||||
if (ctr_mode)
|
||||
ctx1_iv_off = 16;
|
||||
|
||||
/*
|
||||
* RFC3686 specific:
|
||||
* | CONTEXT1[255:128] = {NONCE, IV, COUNTER}
|
||||
* | *key = {KEY, NONCE}
|
||||
*/
|
||||
if (is_rfc3686) {
|
||||
ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
|
||||
keylen -= CTR_RFC3686_NONCE_SIZE;
|
||||
}
|
||||
|
||||
ctx->cdata.keylen = keylen;
|
||||
ctx->cdata.key_virt = key;
|
||||
ctx->cdata.key_inline = true;
|
||||
@@ -997,11 +988,99 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
|
||||
const u8 *key, unsigned int keylen)
|
||||
static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return unlikely(des3_verify_key(skcipher, key)) ?:
|
||||
skcipher_setkey(skcipher, key, keylen);
|
||||
int err;
|
||||
|
||||
err = aes_check_keylen(keylen);
|
||||
if (err) {
|
||||
crypto_skcipher_set_flags(skcipher,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return err;
|
||||
}
|
||||
|
||||
return skcipher_setkey(skcipher, key, keylen, 0);
|
||||
}
|
||||
|
||||
static int rfc3686_skcipher_setkey(struct crypto_skcipher *skcipher,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
u32 ctx1_iv_off;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* RFC3686 specific:
|
||||
* | CONTEXT1[255:128] = {NONCE, IV, COUNTER}
|
||||
* | *key = {KEY, NONCE}
|
||||
*/
|
||||
ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
|
||||
keylen -= CTR_RFC3686_NONCE_SIZE;
|
||||
|
||||
err = aes_check_keylen(keylen);
|
||||
if (err) {
|
||||
crypto_skcipher_set_flags(skcipher,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return err;
|
||||
}
|
||||
|
||||
return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
|
||||
}
|
||||
|
||||
static int ctr_skcipher_setkey(struct crypto_skcipher *skcipher,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
u32 ctx1_iv_off;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* AES-CTR needs to load IV in CONTEXT1 reg
|
||||
* at an offset of 128bits (16bytes)
|
||||
* CONTEXT1[255:128] = IV
|
||||
*/
|
||||
ctx1_iv_off = 16;
|
||||
|
||||
err = aes_check_keylen(keylen);
|
||||
if (err) {
|
||||
crypto_skcipher_set_flags(skcipher,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return err;
|
||||
}
|
||||
|
||||
return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
|
||||
}
|
||||
|
||||
static int chacha20_skcipher_setkey(struct crypto_skcipher *skcipher,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
if (keylen != CHACHA_KEY_SIZE) {
|
||||
crypto_skcipher_set_flags(skcipher,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return skcipher_setkey(skcipher, key, keylen, 0);
|
||||
}
|
||||
|
||||
static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
u32 tmp[DES3_EDE_EXPKEY_WORDS];
|
||||
struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
|
||||
|
||||
if (keylen == DES3_EDE_KEY_SIZE &&
|
||||
__des3_ede_setkey(tmp, &tfm->crt_flags, key, DES3_EDE_KEY_SIZE)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!des_ekey(tmp, key) && (crypto_skcipher_get_flags(skcipher) &
|
||||
CRYPTO_TFM_REQ_FORBID_WEAK_KEYS)) {
|
||||
crypto_skcipher_set_flags(skcipher,
|
||||
CRYPTO_TFM_RES_WEAK_KEY);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return skcipher_setkey(skcipher, key, keylen, 0);
|
||||
}
|
||||
|
||||
static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
|
||||
@@ -1535,7 +1614,7 @@ static struct caam_skcipher_alg driver_algs[] = {
|
||||
.cra_driver_name = "cbc-aes-caam-qi2",
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
},
|
||||
.setkey = skcipher_setkey,
|
||||
.setkey = aes_skcipher_setkey,
|
||||
.encrypt = skcipher_encrypt,
|
||||
.decrypt = skcipher_decrypt,
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
@@ -1551,7 +1630,7 @@ static struct caam_skcipher_alg driver_algs[] = {
|
||||
.cra_driver_name = "cbc-3des-caam-qi2",
|
||||
.cra_blocksize = DES3_EDE_BLOCK_SIZE,
|
||||
},
|
||||
.setkey = des3_skcipher_setkey,
|
||||
.setkey = des_skcipher_setkey,
|
||||
.encrypt = skcipher_encrypt,
|
||||
.decrypt = skcipher_decrypt,
|
||||
.min_keysize = DES3_EDE_KEY_SIZE,
|
||||
@@ -1567,7 +1646,7 @@ static struct caam_skcipher_alg driver_algs[] = {
|
||||
.cra_driver_name = "cbc-des-caam-qi2",
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
},
|
||||
.setkey = skcipher_setkey,
|
||||
.setkey = des_skcipher_setkey,
|
||||
.encrypt = skcipher_encrypt,
|
||||
.decrypt = skcipher_decrypt,
|
||||
.min_keysize = DES_KEY_SIZE,
|
||||
@@ -1583,7 +1662,7 @@ static struct caam_skcipher_alg driver_algs[] = {
|
||||
.cra_driver_name = "ctr-aes-caam-qi2",
|
||||
.cra_blocksize = 1,
|
||||
},
|
||||
.setkey = skcipher_setkey,
|
||||
.setkey = ctr_skcipher_setkey,
|
||||
.encrypt = skcipher_encrypt,
|
||||
.decrypt = skcipher_decrypt,
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
@@ -1601,7 +1680,7 @@ static struct caam_skcipher_alg driver_algs[] = {
|
||||
.cra_driver_name = "rfc3686-ctr-aes-caam-qi2",
|
||||
.cra_blocksize = 1,
|
||||
},
|
||||
.setkey = skcipher_setkey,
|
||||
.setkey = rfc3686_skcipher_setkey,
|
||||
.encrypt = skcipher_encrypt,
|
||||
.decrypt = skcipher_decrypt,
|
||||
.min_keysize = AES_MIN_KEY_SIZE +
|
||||
@@ -1640,7 +1719,7 @@ static struct caam_skcipher_alg driver_algs[] = {
|
||||
.cra_driver_name = "chacha20-caam-qi2",
|
||||
.cra_blocksize = 1,
|
||||
},
|
||||
.setkey = skcipher_setkey,
|
||||
.setkey = chacha20_skcipher_setkey,
|
||||
.encrypt = skcipher_encrypt,
|
||||
.decrypt = skcipher_decrypt,
|
||||
.min_keysize = CHACHA_KEY_SIZE,
|
||||
|
||||
Reference in New Issue
Block a user