Commit 836d8f43 authored by Iuliana Prodan's avatar Iuliana Prodan Committed by Herbert Xu

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: default avatarIuliana Prodan <iuliana.prodan@nxp.com>
Reviewed-by: default avatarHoria Geanta <horia.geanta@nxp.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 1ccb39eb
...@@ -111,6 +111,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI ...@@ -111,6 +111,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
select CRYPTO_AUTHENC select CRYPTO_AUTHENC
select CRYPTO_BLKCIPHER select CRYPTO_BLKCIPHER
select CRYPTO_DES
help help
Selecting this will use CAAM Queue Interface (QI) for sending Selecting this will use CAAM Queue Interface (QI) for sending
& receiving crypto jobs to/from CAAM. This gives better performance & receiving crypto jobs to/from CAAM. This gives better performance
...@@ -161,6 +162,7 @@ config CRYPTO_DEV_FSL_DPAA2_CAAM ...@@ -161,6 +162,7 @@ config CRYPTO_DEV_FSL_DPAA2_CAAM
select CRYPTO_AUTHENC select CRYPTO_AUTHENC
select CRYPTO_AEAD select CRYPTO_AEAD
select CRYPTO_HASH select CRYPTO_HASH
select CRYPTO_DES
help help
CAAM driver for QorIQ Data Path Acceleration Architecture 2. CAAM driver for QorIQ Data Path Acceleration Architecture 2.
It handles DPSECI DPAA2 objects that sit on the Management Complex It handles DPSECI DPAA2 objects that sit on the Management Complex
......
...@@ -667,6 +667,13 @@ static int gcm_setkey(struct crypto_aead *aead, ...@@ -667,6 +667,13 @@ static int gcm_setkey(struct crypto_aead *aead,
{ {
struct caam_ctx *ctx = crypto_aead_ctx(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
int err;
err = aes_check_keylen(keylen);
if (err) {
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
return err;
}
print_hex_dump_debug("key in @"__stringify(__LINE__)": ", print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -683,9 +690,13 @@ static int rfc4106_setkey(struct crypto_aead *aead, ...@@ -683,9 +690,13 @@ static int rfc4106_setkey(struct crypto_aead *aead,
{ {
struct caam_ctx *ctx = crypto_aead_ctx(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
int err;
if (keylen < 4) err = aes_check_keylen(keylen - 4);
return -EINVAL; if (err) {
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
return err;
}
print_hex_dump_debug("key in @"__stringify(__LINE__)": ", print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -707,9 +718,13 @@ static int rfc4543_setkey(struct crypto_aead *aead, ...@@ -707,9 +718,13 @@ static int rfc4543_setkey(struct crypto_aead *aead,
{ {
struct caam_ctx *ctx = crypto_aead_ctx(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
int err;
if (keylen < 4) err = aes_check_keylen(keylen - 4);
return -EINVAL; if (err) {
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
return err;
}
print_hex_dump_debug("key in @"__stringify(__LINE__)": ", print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -727,7 +742,7 @@ static int rfc4543_setkey(struct crypto_aead *aead, ...@@ -727,7 +742,7 @@ static int rfc4543_setkey(struct crypto_aead *aead,
} }
static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, 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_ctx *ctx = crypto_skcipher_ctx(skcipher);
struct caam_skcipher_alg *alg = struct caam_skcipher_alg *alg =
...@@ -736,30 +751,10 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ...@@ -736,30 +751,10 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
unsigned int ivsize = crypto_skcipher_ivsize(skcipher); unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
u32 *desc; u32 *desc;
u32 ctx1_iv_off = 0;
const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
OP_ALG_AAI_CTR_MOD128);
const bool is_rfc3686 = alg->caam.rfc3686; const bool is_rfc3686 = alg->caam.rfc3686;
print_hex_dump_debug("key in @"__stringify(__LINE__)": ", print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 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.keylen = keylen;
ctx->cdata.key_virt = key; ctx->cdata.key_virt = key;
...@@ -782,6 +777,74 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ...@@ -782,6 +777,74 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
return 0; return 0;
} }
static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int 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 arc4_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int keylen)
{
return skcipher_setkey(skcipher, key, keylen, 0);
}
static int des_skcipher_setkey(struct crypto_skcipher *skcipher, static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int keylen) const u8 *key, unsigned int keylen)
{ {
...@@ -800,7 +863,7 @@ static int des_skcipher_setkey(struct crypto_skcipher *skcipher, ...@@ -800,7 +863,7 @@ static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
return -EINVAL; return -EINVAL;
} }
return skcipher_setkey(skcipher, key, keylen); return skcipher_setkey(skcipher, key, keylen, 0);
} }
static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
...@@ -1880,7 +1943,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1880,7 +1943,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "cbc-aes-caam", .cra_driver_name = "cbc-aes-caam",
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
}, },
.setkey = skcipher_setkey, .setkey = aes_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE, .min_keysize = AES_MIN_KEY_SIZE,
...@@ -1928,7 +1991,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1928,7 +1991,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "ctr-aes-caam", .cra_driver_name = "ctr-aes-caam",
.cra_blocksize = 1, .cra_blocksize = 1,
}, },
.setkey = skcipher_setkey, .setkey = ctr_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE, .min_keysize = AES_MIN_KEY_SIZE,
...@@ -1946,7 +2009,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1946,7 +2009,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "rfc3686-ctr-aes-caam", .cra_driver_name = "rfc3686-ctr-aes-caam",
.cra_blocksize = 1, .cra_blocksize = 1,
}, },
.setkey = skcipher_setkey, .setkey = rfc3686_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE + .min_keysize = AES_MIN_KEY_SIZE +
...@@ -2000,7 +2063,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -2000,7 +2063,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "ecb-aes-caam", .cra_driver_name = "ecb-aes-caam",
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
}, },
.setkey = skcipher_setkey, .setkey = aes_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE, .min_keysize = AES_MIN_KEY_SIZE,
...@@ -2030,7 +2093,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -2030,7 +2093,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "ecb-arc4-caam", .cra_driver_name = "ecb-arc4-caam",
.cra_blocksize = ARC4_BLOCK_SIZE, .cra_blocksize = ARC4_BLOCK_SIZE,
}, },
.setkey = skcipher_setkey, .setkey = arc4_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = ARC4_MIN_KEY_SIZE, .min_keysize = ARC4_MIN_KEY_SIZE,
......
...@@ -385,6 +385,12 @@ static int gcm_setkey(struct crypto_aead *aead, ...@@ -385,6 +385,12 @@ static int gcm_setkey(struct crypto_aead *aead,
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
int ret; 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__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -480,8 +486,11 @@ static int rfc4106_setkey(struct crypto_aead *aead, ...@@ -480,8 +486,11 @@ static int rfc4106_setkey(struct crypto_aead *aead,
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
int ret; int ret;
if (keylen < 4) ret = aes_check_keylen(keylen - 4);
return -EINVAL; if (ret) {
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
return ret;
}
print_hex_dump_debug("key in @" __stringify(__LINE__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -582,8 +591,11 @@ static int rfc4543_setkey(struct crypto_aead *aead, ...@@ -582,8 +591,11 @@ static int rfc4543_setkey(struct crypto_aead *aead,
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
int ret; int ret;
if (keylen < 4) ret = aes_check_keylen(keylen - 4);
return -EINVAL; if (ret) {
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
return ret;
}
print_hex_dump_debug("key in @" __stringify(__LINE__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -624,7 +636,7 @@ static int rfc4543_setkey(struct crypto_aead *aead, ...@@ -624,7 +636,7 @@ static int rfc4543_setkey(struct crypto_aead *aead,
} }
static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, 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_ctx *ctx = crypto_skcipher_ctx(skcipher);
struct caam_skcipher_alg *alg = struct caam_skcipher_alg *alg =
...@@ -632,33 +644,12 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ...@@ -632,33 +644,12 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
skcipher); skcipher);
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
unsigned int ivsize = crypto_skcipher_ivsize(skcipher); unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
u32 ctx1_iv_off = 0;
const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
OP_ALG_AAI_CTR_MOD128);
const bool is_rfc3686 = alg->caam.rfc3686; const bool is_rfc3686 = alg->caam.rfc3686;
int ret = 0; int ret = 0;
print_hex_dump_debug("key in @" __stringify(__LINE__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 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.keylen = keylen;
ctx->cdata.key_virt = key; ctx->cdata.key_virt = key;
ctx->cdata.key_inline = true; ctx->cdata.key_inline = true;
...@@ -694,11 +685,88 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ...@@ -694,11 +685,88 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
return -EINVAL; return -EINVAL;
} }
static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int 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 des3_skcipher_setkey(struct crypto_skcipher *skcipher, static int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int keylen) const u8 *key, unsigned int keylen)
{ {
return unlikely(des3_verify_key(skcipher, key)) ?: return unlikely(des3_verify_key(skcipher, key)) ?:
skcipher_setkey(skcipher, key, keylen); skcipher_setkey(skcipher, key, keylen, 0);
}
static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int keylen)
{
u32 tmp[DES_EXPKEY_WORDS];
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, static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
...@@ -1405,7 +1473,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1405,7 +1473,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "cbc-aes-caam-qi", .cra_driver_name = "cbc-aes-caam-qi",
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
}, },
.setkey = skcipher_setkey, .setkey = aes_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE, .min_keysize = AES_MIN_KEY_SIZE,
...@@ -1437,7 +1505,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1437,7 +1505,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "cbc-des-caam-qi", .cra_driver_name = "cbc-des-caam-qi",
.cra_blocksize = DES_BLOCK_SIZE, .cra_blocksize = DES_BLOCK_SIZE,
}, },
.setkey = skcipher_setkey, .setkey = des_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = DES_KEY_SIZE, .min_keysize = DES_KEY_SIZE,
...@@ -1453,7 +1521,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1453,7 +1521,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "ctr-aes-caam-qi", .cra_driver_name = "ctr-aes-caam-qi",
.cra_blocksize = 1, .cra_blocksize = 1,
}, },
.setkey = skcipher_setkey, .setkey = ctr_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE, .min_keysize = AES_MIN_KEY_SIZE,
...@@ -1471,7 +1539,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1471,7 +1539,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "rfc3686-ctr-aes-caam-qi", .cra_driver_name = "rfc3686-ctr-aes-caam-qi",
.cra_blocksize = 1, .cra_blocksize = 1,
}, },
.setkey = skcipher_setkey, .setkey = rfc3686_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE + .min_keysize = AES_MIN_KEY_SIZE +
......
...@@ -732,7 +732,13 @@ static int gcm_setkey(struct crypto_aead *aead, ...@@ -732,7 +732,13 @@ static int gcm_setkey(struct crypto_aead *aead,
{ {
struct caam_ctx *ctx = crypto_aead_ctx(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *dev = ctx->dev; 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__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -818,9 +824,13 @@ static int rfc4106_setkey(struct crypto_aead *aead, ...@@ -818,9 +824,13 @@ static int rfc4106_setkey(struct crypto_aead *aead,
{ {
struct caam_ctx *ctx = crypto_aead_ctx(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *dev = ctx->dev; struct device *dev = ctx->dev;
int ret;
if (keylen < 4) ret = aes_check_keylen(keylen - 4);
return -EINVAL; if (ret) {
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
return ret;
}
print_hex_dump_debug("key in @" __stringify(__LINE__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -912,9 +922,13 @@ static int rfc4543_setkey(struct crypto_aead *aead, ...@@ -912,9 +922,13 @@ static int rfc4543_setkey(struct crypto_aead *aead,
{ {
struct caam_ctx *ctx = crypto_aead_ctx(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *dev = ctx->dev; struct device *dev = ctx->dev;
int ret;
if (keylen < 4) ret = aes_check_keylen(keylen - 4);
return -EINVAL; if (ret) {
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
return ret;
}
print_hex_dump_debug("key in @" __stringify(__LINE__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
...@@ -932,7 +946,7 @@ static int rfc4543_setkey(struct crypto_aead *aead, ...@@ -932,7 +946,7 @@ static int rfc4543_setkey(struct crypto_aead *aead,
} }
static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, 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_ctx *ctx = crypto_skcipher_ctx(skcipher);
struct caam_skcipher_alg *alg = struct caam_skcipher_alg *alg =
...@@ -942,34 +956,11 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ...@@ -942,34 +956,11 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
struct caam_flc *flc; struct caam_flc *flc;
unsigned int ivsize = crypto_skcipher_ivsize(skcipher); unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
u32 *desc; 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; const bool is_rfc3686 = alg->caam.rfc3686;
print_hex_dump_debug("key in @" __stringify(__LINE__)": ", print_hex_dump_debug("key in @" __stringify(__LINE__)": ",
DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 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.keylen = keylen;
ctx->cdata.key_virt = key; ctx->cdata.key_virt = key;
ctx->cdata.key_inline = true; ctx->cdata.key_inline = true;
...@@ -997,11 +988,99 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ...@@ -997,11 +988,99 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
return 0; return 0;
} }
static int des3_skcipher_setkey(struct crypto_skcipher *skcipher, static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
const u8 *key, unsigned int keylen) const u8 *key, unsigned int keylen)
{ {
return unlikely(des3_verify_key(skcipher, key)) ?: int err;
skcipher_setkey(skcipher, key, keylen);
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, static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
...@@ -1535,7 +1614,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1535,7 +1614,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "cbc-aes-caam-qi2", .cra_driver_name = "cbc-aes-caam-qi2",
.cra_blocksize = AES_BLOCK_SIZE, .cra_blocksize = AES_BLOCK_SIZE,
}, },
.setkey = skcipher_setkey, .setkey = aes_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE, .min_keysize = AES_MIN_KEY_SIZE,
...@@ -1551,7 +1630,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1551,7 +1630,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "cbc-3des-caam-qi2", .cra_driver_name = "cbc-3des-caam-qi2",
.cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_blocksize = DES3_EDE_BLOCK_SIZE,
}, },
.setkey = des3_skcipher_setkey, .setkey = des_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = DES3_EDE_KEY_SIZE, .min_keysize = DES3_EDE_KEY_SIZE,
...@@ -1567,7 +1646,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1567,7 +1646,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "cbc-des-caam-qi2", .cra_driver_name = "cbc-des-caam-qi2",
.cra_blocksize = DES_BLOCK_SIZE, .cra_blocksize = DES_BLOCK_SIZE,
}, },
.setkey = skcipher_setkey, .setkey = des_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = DES_KEY_SIZE, .min_keysize = DES_KEY_SIZE,
...@@ -1583,7 +1662,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1583,7 +1662,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "ctr-aes-caam-qi2", .cra_driver_name = "ctr-aes-caam-qi2",
.cra_blocksize = 1, .cra_blocksize = 1,
}, },
.setkey = skcipher_setkey, .setkey = ctr_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE, .min_keysize = AES_MIN_KEY_SIZE,
...@@ -1601,7 +1680,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1601,7 +1680,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "rfc3686-ctr-aes-caam-qi2", .cra_driver_name = "rfc3686-ctr-aes-caam-qi2",
.cra_blocksize = 1, .cra_blocksize = 1,
}, },
.setkey = skcipher_setkey, .setkey = rfc3686_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = AES_MIN_KEY_SIZE + .min_keysize = AES_MIN_KEY_SIZE +
...@@ -1640,7 +1719,7 @@ static struct caam_skcipher_alg driver_algs[] = { ...@@ -1640,7 +1719,7 @@ static struct caam_skcipher_alg driver_algs[] = {
.cra_driver_name = "chacha20-caam-qi2", .cra_driver_name = "chacha20-caam-qi2",
.cra_blocksize = 1, .cra_blocksize = 1,
}, },
.setkey = skcipher_setkey, .setkey = chacha20_skcipher_setkey,
.encrypt = skcipher_encrypt, .encrypt = skcipher_encrypt,
.decrypt = skcipher_decrypt, .decrypt = skcipher_decrypt,
.min_keysize = CHACHA_KEY_SIZE, .min_keysize = CHACHA_KEY_SIZE,
......
...@@ -501,6 +501,11 @@ static int axcbc_setkey(struct crypto_ahash *ahash, const u8 *key, ...@@ -501,6 +501,11 @@ static int axcbc_setkey(struct crypto_ahash *ahash, const u8 *key,
struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
struct device *jrdev = ctx->jrdev; struct device *jrdev = ctx->jrdev;
if (keylen != AES_KEYSIZE_128) {
crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
memcpy(ctx->key, key, keylen); memcpy(ctx->key, key, keylen);
dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE); dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE);
ctx->adata.keylen = keylen; ctx->adata.keylen = keylen;
...@@ -515,6 +520,13 @@ static int acmac_setkey(struct crypto_ahash *ahash, const u8 *key, ...@@ -515,6 +520,13 @@ static int acmac_setkey(struct crypto_ahash *ahash, const u8 *key,
unsigned int keylen) unsigned int keylen)
{ {
struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
int err;
err = aes_check_keylen(keylen);
if (err) {
crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN);
return err;
}
/* key is immediate data for all cmac shared descriptors */ /* key is immediate data for all cmac shared descriptors */
ctx->adata.key_virt = key; ctx->adata.key_virt = key;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment