Skip to content

Commit e4e992a

Browse files
committed
crypto: tegra - Do not use fixed size buffers
jira LE-4159 Rebuild_History Non-Buildable kernel-5.14.0-570.41.1.el9_6 commit-author Akhil R <akhilrajeev@nvidia.com> commit 1cb328d Allocate the buffer based on the request instead of a fixed buffer length. In operations which may require larger buffer size, a fixed buffer may fail. Fixes: 0880bb3 ("crypto: tegra - Add Tegra Security Engine driver") Signed-off-by: Akhil R <akhilrajeev@nvidia.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> (cherry picked from commit 1cb328d) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 38ed63d commit e4e992a

File tree

3 files changed

+89
-75
lines changed

3 files changed

+89
-75
lines changed

drivers/crypto/tegra/tegra-se-aes.c

Lines changed: 64 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,6 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
263263
unsigned int cmdlen;
264264
int ret;
265265

266-
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_AES_BUFLEN,
267-
&rctx->datbuf.addr, GFP_KERNEL);
268-
if (!rctx->datbuf.buf)
269-
return -ENOMEM;
270-
271-
rctx->datbuf.size = SE_AES_BUFLEN;
272266
rctx->iv = (u32 *)req->iv;
273267
rctx->len = req->cryptlen;
274268

@@ -278,6 +272,12 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
278272
rctx->len += AES_BLOCK_SIZE - (rctx->len % AES_BLOCK_SIZE);
279273
}
280274

275+
rctx->datbuf.size = rctx->len;
276+
rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
277+
&rctx->datbuf.addr, GFP_KERNEL);
278+
if (!rctx->datbuf.buf)
279+
return -ENOMEM;
280+
281281
scatterwalk_map_and_copy(rctx->datbuf.buf, req->src, 0, req->cryptlen, 0);
282282

283283
/* Prepare the command and submit for execution */
@@ -289,7 +289,7 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
289289
scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1);
290290

291291
/* Free the buffer */
292-
dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
292+
dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
293293
rctx->datbuf.buf, rctx->datbuf.addr);
294294

295295
crypto_finalize_skcipher_request(se->engine, req, ret);
@@ -1117,6 +1117,11 @@ static int tegra_ccm_crypt_init(struct aead_request *req, struct tegra_se *se,
11171117
rctx->assoclen = req->assoclen;
11181118
rctx->authsize = crypto_aead_authsize(tfm);
11191119

1120+
if (rctx->encrypt)
1121+
rctx->cryptlen = req->cryptlen;
1122+
else
1123+
rctx->cryptlen = req->cryptlen - rctx->authsize;
1124+
11201125
memcpy(iv, req->iv, 16);
11211126

11221127
ret = tegra_ccm_check_iv(iv);
@@ -1145,30 +1150,26 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
11451150
struct tegra_se *se = ctx->se;
11461151
int ret;
11471152

1153+
ret = tegra_ccm_crypt_init(req, se, rctx);
1154+
if (ret)
1155+
return ret;
1156+
11481157
/* Allocate buffers required */
1149-
rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
1158+
rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
1159+
rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
11501160
&rctx->inbuf.addr, GFP_KERNEL);
11511161
if (!rctx->inbuf.buf)
11521162
return -ENOMEM;
11531163

1154-
rctx->inbuf.size = SE_AES_BUFLEN;
1155-
1156-
rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
1164+
rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
1165+
rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->outbuf.size,
11571166
&rctx->outbuf.addr, GFP_KERNEL);
11581167
if (!rctx->outbuf.buf) {
11591168
ret = -ENOMEM;
11601169
goto outbuf_err;
11611170
}
11621171

1163-
rctx->outbuf.size = SE_AES_BUFLEN;
1164-
1165-
ret = tegra_ccm_crypt_init(req, se, rctx);
1166-
if (ret)
1167-
goto out;
1168-
11691172
if (rctx->encrypt) {
1170-
rctx->cryptlen = req->cryptlen;
1171-
11721173
/* CBC MAC Operation */
11731174
ret = tegra_ccm_compute_auth(ctx, rctx);
11741175
if (ret)
@@ -1179,8 +1180,6 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
11791180
if (ret)
11801181
goto out;
11811182
} else {
1182-
rctx->cryptlen = req->cryptlen - ctx->authsize;
1183-
11841183
/* CTR operation */
11851184
ret = tegra_ccm_do_ctr(ctx, rctx);
11861185
if (ret)
@@ -1193,11 +1192,11 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
11931192
}
11941193

11951194
out:
1196-
dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
1195+
dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
11971196
rctx->outbuf.buf, rctx->outbuf.addr);
11981197

11991198
outbuf_err:
1200-
dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
1199+
dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
12011200
rctx->inbuf.buf, rctx->inbuf.addr);
12021201

12031202
crypto_finalize_aead_request(ctx->se->engine, req, ret);
@@ -1213,23 +1212,6 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12131212
struct tegra_aead_reqctx *rctx = aead_request_ctx(req);
12141213
int ret;
12151214

1216-
/* Allocate buffers required */
1217-
rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
1218-
&rctx->inbuf.addr, GFP_KERNEL);
1219-
if (!rctx->inbuf.buf)
1220-
return -ENOMEM;
1221-
1222-
rctx->inbuf.size = SE_AES_BUFLEN;
1223-
1224-
rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, SE_AES_BUFLEN,
1225-
&rctx->outbuf.addr, GFP_KERNEL);
1226-
if (!rctx->outbuf.buf) {
1227-
ret = -ENOMEM;
1228-
goto outbuf_err;
1229-
}
1230-
1231-
rctx->outbuf.size = SE_AES_BUFLEN;
1232-
12331215
rctx->src_sg = req->src;
12341216
rctx->dst_sg = req->dst;
12351217
rctx->assoclen = req->assoclen;
@@ -1243,6 +1225,21 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12431225
memcpy(rctx->iv, req->iv, GCM_AES_IV_SIZE);
12441226
rctx->iv[3] = (1 << 24);
12451227

1228+
/* Allocate buffers required */
1229+
rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
1230+
rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
1231+
&rctx->inbuf.addr, GFP_KERNEL);
1232+
if (!rctx->inbuf.buf)
1233+
return -ENOMEM;
1234+
1235+
rctx->outbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
1236+
rctx->outbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->outbuf.size,
1237+
&rctx->outbuf.addr, GFP_KERNEL);
1238+
if (!rctx->outbuf.buf) {
1239+
ret = -ENOMEM;
1240+
goto outbuf_err;
1241+
}
1242+
12461243
/* If there is associated data perform GMAC operation */
12471244
if (rctx->assoclen) {
12481245
ret = tegra_gcm_do_gmac(ctx, rctx);
@@ -1266,11 +1263,11 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12661263
ret = tegra_gcm_do_verify(ctx->se, rctx);
12671264

12681265
out:
1269-
dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
1266+
dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
12701267
rctx->outbuf.buf, rctx->outbuf.addr);
12711268

12721269
outbuf_err:
1273-
dma_free_coherent(ctx->se->dev, SE_AES_BUFLEN,
1270+
dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
12741271
rctx->inbuf.buf, rctx->inbuf.addr);
12751272

12761273
/* Finalize the request if there are no errors */
@@ -1497,6 +1494,11 @@ static int tegra_cmac_do_update(struct ahash_request *req)
14971494
return 0;
14981495
}
14991496

1497+
rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->datbuf.size,
1498+
&rctx->datbuf.addr, GFP_KERNEL);
1499+
if (!rctx->datbuf.buf)
1500+
return -ENOMEM;
1501+
15001502
/* Copy the previous residue first */
15011503
if (rctx->residue.size)
15021504
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
@@ -1529,6 +1531,9 @@ static int tegra_cmac_do_update(struct ahash_request *req)
15291531
if (!(rctx->task & SHA_FINAL))
15301532
tegra_cmac_copy_result(ctx->se, rctx);
15311533

1534+
dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
1535+
rctx->datbuf.buf, rctx->datbuf.addr);
1536+
15321537
return ret;
15331538
}
15341539

@@ -1543,10 +1548,20 @@ static int tegra_cmac_do_final(struct ahash_request *req)
15431548

15441549
if (!req->nbytes && !rctx->total_len && ctx->fallback_tfm) {
15451550
return crypto_shash_tfm_digest(ctx->fallback_tfm,
1546-
rctx->datbuf.buf, 0, req->result);
1551+
NULL, 0, req->result);
1552+
}
1553+
1554+
if (rctx->residue.size) {
1555+
rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->residue.size,
1556+
&rctx->datbuf.addr, GFP_KERNEL);
1557+
if (!rctx->datbuf.buf) {
1558+
ret = -ENOMEM;
1559+
goto out_free;
1560+
}
1561+
1562+
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
15471563
}
15481564

1549-
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
15501565
rctx->datbuf.size = rctx->residue.size;
15511566
rctx->total_len += rctx->residue.size;
15521567
rctx->config = tegra234_aes_cfg(SE_ALG_CMAC, 0);
@@ -1565,8 +1580,10 @@ static int tegra_cmac_do_final(struct ahash_request *req)
15651580
writel(0, se->base + se->hw->regs->result + (i * 4));
15661581

15671582
out:
1568-
dma_free_coherent(se->dev, SE_SHA_BUFLEN,
1569-
rctx->datbuf.buf, rctx->datbuf.addr);
1583+
if (rctx->residue.size)
1584+
dma_free_coherent(se->dev, rctx->datbuf.size,
1585+
rctx->datbuf.buf, rctx->datbuf.addr);
1586+
out_free:
15701587
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm) * 2,
15711588
rctx->residue.buf, rctx->residue.addr);
15721589
return ret;
@@ -1672,28 +1689,15 @@ static int tegra_cmac_init(struct ahash_request *req)
16721689
rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size * 2,
16731690
&rctx->residue.addr, GFP_KERNEL);
16741691
if (!rctx->residue.buf)
1675-
goto resbuf_fail;
1692+
return -ENOMEM;
16761693

16771694
rctx->residue.size = 0;
16781695

1679-
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
1680-
&rctx->datbuf.addr, GFP_KERNEL);
1681-
if (!rctx->datbuf.buf)
1682-
goto datbuf_fail;
1683-
1684-
rctx->datbuf.size = 0;
1685-
16861696
/* Clear any previous result */
16871697
for (i = 0; i < CMAC_RESULT_REG_COUNT; i++)
16881698
writel(0, se->base + se->hw->regs->result + (i * 4));
16891699

16901700
return 0;
1691-
1692-
datbuf_fail:
1693-
dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
1694-
rctx->residue.addr);
1695-
resbuf_fail:
1696-
return -ENOMEM;
16971701
}
16981702

16991703
static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,

drivers/crypto/tegra/tegra-se-hash.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ static int tegra_sha_do_update(struct ahash_request *req)
332332
return 0;
333333
}
334334

335+
rctx->datbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->datbuf.size,
336+
&rctx->datbuf.addr, GFP_KERNEL);
337+
if (!rctx->datbuf.buf)
338+
return -ENOMEM;
339+
335340
/* Copy the previous residue first */
336341
if (rctx->residue.size)
337342
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
@@ -368,6 +373,9 @@ static int tegra_sha_do_update(struct ahash_request *req)
368373
if (!(rctx->task & SHA_FINAL))
369374
tegra_sha_copy_hash_result(se, rctx);
370375

376+
dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
377+
rctx->datbuf.buf, rctx->datbuf.addr);
378+
371379
return ret;
372380
}
373381

@@ -380,7 +388,17 @@ static int tegra_sha_do_final(struct ahash_request *req)
380388
u32 *cpuvaddr = se->cmdbuf->addr;
381389
int size, ret = 0;
382390

383-
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
391+
if (rctx->residue.size) {
392+
rctx->datbuf.buf = dma_alloc_coherent(se->dev, rctx->residue.size,
393+
&rctx->datbuf.addr, GFP_KERNEL);
394+
if (!rctx->datbuf.buf) {
395+
ret = -ENOMEM;
396+
goto out_free;
397+
}
398+
399+
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
400+
}
401+
384402
rctx->datbuf.size = rctx->residue.size;
385403
rctx->total_len += rctx->residue.size;
386404

@@ -397,8 +415,10 @@ static int tegra_sha_do_final(struct ahash_request *req)
397415
memcpy(req->result, rctx->digest.buf, rctx->digest.size);
398416

399417
out:
400-
dma_free_coherent(se->dev, SE_SHA_BUFLEN,
401-
rctx->datbuf.buf, rctx->datbuf.addr);
418+
if (rctx->residue.size)
419+
dma_free_coherent(se->dev, rctx->datbuf.size,
420+
rctx->datbuf.buf, rctx->datbuf.addr);
421+
out_free:
402422
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm),
403423
rctx->residue.buf, rctx->residue.addr);
404424
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
@@ -527,19 +547,11 @@ static int tegra_sha_init(struct ahash_request *req)
527547
if (!rctx->residue.buf)
528548
goto resbuf_fail;
529549

530-
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
531-
&rctx->datbuf.addr, GFP_KERNEL);
532-
if (!rctx->datbuf.buf)
533-
goto datbuf_fail;
534-
535550
return 0;
536551

537-
datbuf_fail:
538-
dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
539-
rctx->residue.addr);
540552
resbuf_fail:
541-
dma_free_coherent(se->dev, SE_SHA_BUFLEN, rctx->datbuf.buf,
542-
rctx->datbuf.addr);
553+
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
554+
rctx->digest.addr);
543555
digbuf_fail:
544556
return -ENOMEM;
545557
}

drivers/crypto/tegra/tegra-se.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,6 @@
340340
#define SE_CRYPTO_CTR_REG_COUNT 4
341341
#define SE_MAX_KEYSLOT 15
342342
#define SE_MAX_MEM_ALLOC SZ_4M
343-
#define SE_AES_BUFLEN 0x8000
344-
#define SE_SHA_BUFLEN 0x2000
345343

346344
#define SHA_FIRST BIT(0)
347345
#define SHA_UPDATE BIT(1)

0 commit comments

Comments
 (0)