Skip to content

Commit 584201f

Browse files
chunkeeyherbertx
authored andcommitted
crypto: crypto4xx - extend aead fallback checks
1020 bytes is the limit for associated data. Any more and it will no longer fit into hash_crypto_offset anymore. The hardware will not process aead requests with plaintext that have less than AES_BLOCK_SIZE bytes. When decrypting aead requests the authsize has to be taken in account as well, as it is part of the cryptlen. Otherwise the hardware will think it has been misconfigured and will return: aead return err status = 0x98 For rtc4543(gcm(aes)), the hardware has a dedicated GMAC mode as part of the hash function set. Signed-off-by: Christian Lamparter <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent fc34011 commit 584201f

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

drivers/crypto/amcc/crypto4xx_alg.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ int crypto4xx_decrypt_ctr(struct skcipher_request *req)
321321
}
322322

323323
static inline bool crypto4xx_aead_need_fallback(struct aead_request *req,
324+
unsigned int len,
324325
bool is_ccm, bool decrypt)
325326
{
326327
struct crypto_aead *aead = crypto_aead_reqtfm(req);
@@ -330,14 +331,14 @@ static inline bool crypto4xx_aead_need_fallback(struct aead_request *req,
330331
return true;
331332

332333
/*
333-
* hardware does not handle cases where cryptlen
334-
* is less than a block
334+
* hardware does not handle cases where plaintext
335+
* is less than a block.
335336
*/
336-
if (req->cryptlen < AES_BLOCK_SIZE)
337+
if (len < AES_BLOCK_SIZE)
337338
return true;
338339

339-
/* assoc len needs to be a multiple of 4 */
340-
if (req->assoclen & 0x3)
340+
/* assoc len needs to be a multiple of 4 and <= 1020 */
341+
if (req->assoclen & 0x3 || req->assoclen > 1020)
341342
return true;
342343

343344
/* CCM supports only counter field length of 2 and 4 bytes */
@@ -449,17 +450,17 @@ static int crypto4xx_crypt_aes_ccm(struct aead_request *req, bool decrypt)
449450
{
450451
struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
451452
struct crypto_aead *aead = crypto_aead_reqtfm(req);
452-
unsigned int len = req->cryptlen;
453453
__le32 iv[16];
454454
u32 tmp_sa[SA_AES128_CCM_LEN + 4];
455455
struct dynamic_sa_ctl *sa = (struct dynamic_sa_ctl *)tmp_sa;
456-
457-
if (crypto4xx_aead_need_fallback(req, true, decrypt))
458-
return crypto4xx_aead_fallback(req, ctx, decrypt);
456+
unsigned int len = req->cryptlen;
459457

460458
if (decrypt)
461459
len -= crypto_aead_authsize(aead);
462460

461+
if (crypto4xx_aead_need_fallback(req, len, true, decrypt))
462+
return crypto4xx_aead_fallback(req, ctx, decrypt);
463+
463464
memcpy(tmp_sa, decrypt ? ctx->sa_in : ctx->sa_out, ctx->sa_len * 4);
464465
sa->sa_command_0.bf.digest_len = crypto_aead_authsize(aead) >> 2;
465466

@@ -605,18 +606,19 @@ static inline int crypto4xx_crypt_aes_gcm(struct aead_request *req,
605606
bool decrypt)
606607
{
607608
struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
608-
unsigned int len = req->cryptlen;
609+
struct crypto4xx_aead_reqctx *rctx = aead_request_ctx(req);
609610
__le32 iv[4];
611+
unsigned int len = req->cryptlen;
612+
613+
if (decrypt)
614+
len -= crypto_aead_authsize(crypto_aead_reqtfm(req));
610615

611-
if (crypto4xx_aead_need_fallback(req, false, decrypt))
616+
if (crypto4xx_aead_need_fallback(req, len, false, decrypt))
612617
return crypto4xx_aead_fallback(req, ctx, decrypt);
613618

614619
crypto4xx_memcpy_to_le32(iv, req->iv, GCM_AES_IV_SIZE);
615620
iv[3] = cpu_to_le32(1);
616621

617-
if (decrypt)
618-
len -= crypto_aead_authsize(crypto_aead_reqtfm(req));
619-
620622
return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
621623
len, iv, sizeof(iv),
622624
decrypt ? ctx->sa_in : ctx->sa_out,

0 commit comments

Comments
 (0)