Skip to content

Commit 03b0d53

Browse files
committed
crypto: tegra - Reserve keyslots to allocate dynamically
jira LE-4159 Rebuild_History Non-Buildable kernel-5.14.0-570.41.1.el9_6 commit-author Akhil R <akhilrajeev@nvidia.com> commit b157e7a The HW supports only storing 15 keys at a time. This limits the number of tfms that can work without failutes. Reserve keyslots to solve this and use the reserved ones during the encryption/decryption operation. This allow users to have the capability of hardware protected keys and faster operations if there are limited number of tfms while not halting the operation if there are more tfms. 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 b157e7a) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent c7bbc2b commit 03b0d53

File tree

3 files changed

+164
-22
lines changed

3 files changed

+164
-22
lines changed

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

Lines changed: 118 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ struct tegra_aes_ctx {
2828
u32 ivsize;
2929
u32 key1_id;
3030
u32 key2_id;
31+
u32 keylen;
32+
u8 key1[AES_MAX_KEY_SIZE];
33+
u8 key2[AES_MAX_KEY_SIZE];
3134
};
3235

3336
struct tegra_aes_reqctx {
@@ -43,8 +46,9 @@ struct tegra_aead_ctx {
4346
struct tegra_se *se;
4447
unsigned int authsize;
4548
u32 alg;
46-
u32 keylen;
4749
u32 key_id;
50+
u32 keylen;
51+
u8 key[AES_MAX_KEY_SIZE];
4852
};
4953

5054
struct tegra_aead_reqctx {
@@ -56,8 +60,8 @@ struct tegra_aead_reqctx {
5660
unsigned int cryptlen;
5761
unsigned int authsize;
5862
bool encrypt;
59-
u32 config;
6063
u32 crypto_config;
64+
u32 config;
6165
u32 key_id;
6266
u32 iv[4];
6367
u8 authdata[16];
@@ -67,6 +71,8 @@ struct tegra_cmac_ctx {
6771
struct tegra_se *se;
6872
unsigned int alg;
6973
u32 key_id;
74+
u32 keylen;
75+
u8 key[AES_MAX_KEY_SIZE];
7076
struct crypto_shash *fallback_tfm;
7177
};
7278

@@ -260,11 +266,13 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
260266
struct tegra_aes_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
261267
struct tegra_aes_reqctx *rctx = skcipher_request_ctx(req);
262268
struct tegra_se *se = ctx->se;
263-
unsigned int cmdlen;
269+
unsigned int cmdlen, key1_id, key2_id;
264270
int ret;
265271

266272
rctx->iv = (u32 *)req->iv;
267273
rctx->len = req->cryptlen;
274+
key1_id = ctx->key1_id;
275+
key2_id = ctx->key2_id;
268276

269277
/* Pad input to AES Block size */
270278
if (ctx->alg != SE_ALG_XTS) {
@@ -282,6 +290,29 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
282290

283291
scatterwalk_map_and_copy(rctx->datbuf.buf, req->src, 0, req->cryptlen, 0);
284292

293+
rctx->config = tegra234_aes_cfg(ctx->alg, rctx->encrypt);
294+
rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, rctx->encrypt);
295+
296+
if (!key1_id) {
297+
ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key1,
298+
ctx->keylen, ctx->alg, &key1_id);
299+
if (ret)
300+
goto out;
301+
}
302+
303+
rctx->crypto_config |= SE_AES_KEY_INDEX(key1_id);
304+
305+
if (ctx->alg == SE_ALG_XTS) {
306+
if (!key2_id) {
307+
ret = tegra_key_submit_reserved_xts(ctx->se, ctx->key2,
308+
ctx->keylen, ctx->alg, &key2_id);
309+
if (ret)
310+
goto out;
311+
}
312+
313+
rctx->crypto_config |= SE_AES_KEY2_INDEX(key2_id);
314+
}
315+
285316
/* Prepare the command and submit for execution */
286317
cmdlen = tegra_aes_prep_cmd(ctx, rctx);
287318
ret = tegra_se_host1x_submit(se, se->cmdbuf, cmdlen);
@@ -290,10 +321,17 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq)
290321
tegra_aes_update_iv(req, ctx);
291322
scatterwalk_map_and_copy(rctx->datbuf.buf, req->dst, 0, req->cryptlen, 1);
292323

324+
out:
293325
/* Free the buffer */
294326
dma_free_coherent(ctx->se->dev, rctx->datbuf.size,
295327
rctx->datbuf.buf, rctx->datbuf.addr);
296328

329+
if (tegra_key_is_reserved(key1_id))
330+
tegra_key_invalidate_reserved(ctx->se, key1_id, ctx->alg);
331+
332+
if (tegra_key_is_reserved(key2_id))
333+
tegra_key_invalidate_reserved(ctx->se, key2_id, ctx->alg);
334+
297335
out_finalize:
298336
crypto_finalize_skcipher_request(se->engine, req, ret);
299337

@@ -316,6 +354,7 @@ static int tegra_aes_cra_init(struct crypto_skcipher *tfm)
316354
ctx->se = se_alg->se_dev;
317355
ctx->key1_id = 0;
318356
ctx->key2_id = 0;
357+
ctx->keylen = 0;
319358

320359
algname = crypto_tfm_alg_name(&tfm->base);
321360
ret = se_algname_to_algid(algname);
@@ -344,13 +383,20 @@ static int tegra_aes_setkey(struct crypto_skcipher *tfm,
344383
const u8 *key, u32 keylen)
345384
{
346385
struct tegra_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
386+
int ret;
347387

348388
if (aes_check_keylen(keylen)) {
349389
dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
350390
return -EINVAL;
351391
}
352392

353-
return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key1_id);
393+
ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key1_id);
394+
if (ret) {
395+
ctx->keylen = keylen;
396+
memcpy(ctx->key1, key, keylen);
397+
}
398+
399+
return 0;
354400
}
355401

356402
static int tegra_xts_setkey(struct crypto_skcipher *tfm,
@@ -368,11 +414,17 @@ static int tegra_xts_setkey(struct crypto_skcipher *tfm,
368414

369415
ret = tegra_key_submit(ctx->se, key, len,
370416
ctx->alg, &ctx->key1_id);
371-
if (ret)
372-
return ret;
417+
if (ret) {
418+
ctx->keylen = len;
419+
memcpy(ctx->key1, key, len);
420+
}
373421

374-
return tegra_key_submit(ctx->se, key + len, len,
422+
ret = tegra_key_submit(ctx->se, key + len, len,
375423
ctx->alg, &ctx->key2_id);
424+
if (ret) {
425+
ctx->keylen = len;
426+
memcpy(ctx->key2, key + len, len);
427+
}
376428

377429
return 0;
378430
}
@@ -450,12 +502,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)
450502
req->iv = NULL;
451503

452504
rctx->encrypt = encrypt;
453-
rctx->config = tegra234_aes_cfg(ctx->alg, encrypt);
454-
rctx->crypto_config = tegra234_aes_crypto_cfg(ctx->alg, encrypt);
455-
rctx->crypto_config |= SE_AES_KEY_INDEX(ctx->key1_id);
456-
457-
if (ctx->key2_id)
458-
rctx->crypto_config |= SE_AES_KEY2_INDEX(ctx->key2_id);
459505

460506
return crypto_transfer_skcipher_request_to_engine(ctx->se->engine, req);
461507
}
@@ -721,7 +767,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct
721767

722768
rctx->config = tegra234_aes_cfg(SE_ALG_GMAC, rctx->encrypt);
723769
rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_GMAC, rctx->encrypt) |
724-
SE_AES_KEY_INDEX(ctx->key_id);
770+
SE_AES_KEY_INDEX(rctx->key_id);
725771

726772
cmdlen = tegra_gmac_prep_cmd(ctx, rctx);
727773

@@ -738,7 +784,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
738784

739785
rctx->config = tegra234_aes_cfg(SE_ALG_GCM, rctx->encrypt);
740786
rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_GCM, rctx->encrypt) |
741-
SE_AES_KEY_INDEX(ctx->key_id);
787+
SE_AES_KEY_INDEX(rctx->key_id);
742788

743789
/* Prepare command and submit */
744790
cmdlen = tegra_gcm_crypt_prep_cmd(ctx, rctx);
@@ -761,7 +807,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
761807

762808
rctx->config = tegra234_aes_cfg(SE_ALG_GCM_FINAL, rctx->encrypt);
763809
rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_GCM_FINAL, rctx->encrypt) |
764-
SE_AES_KEY_INDEX(ctx->key_id);
810+
SE_AES_KEY_INDEX(rctx->key_id);
765811

766812
/* Prepare command and submit */
767813
cmdlen = tegra_gcm_prep_final_cmd(se, cpuvaddr, rctx);
@@ -892,7 +938,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req
892938
rctx->config = tegra234_aes_cfg(SE_ALG_CBC_MAC, rctx->encrypt);
893939
rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_CBC_MAC,
894940
rctx->encrypt) |
895-
SE_AES_KEY_INDEX(ctx->key_id);
941+
SE_AES_KEY_INDEX(rctx->key_id);
896942

897943
/* Prepare command and submit */
898944
cmdlen = tegra_cbcmac_prep_cmd(ctx, rctx);
@@ -1079,7 +1125,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx
10791125

10801126
rctx->config = tegra234_aes_cfg(SE_ALG_CTR, rctx->encrypt);
10811127
rctx->crypto_config = tegra234_aes_crypto_cfg(SE_ALG_CTR, rctx->encrypt) |
1082-
SE_AES_KEY_INDEX(ctx->key_id);
1128+
SE_AES_KEY_INDEX(rctx->key_id);
10831129

10841130
/* Copy authdata in the top of buffer for encryption/decryption */
10851131
if (rctx->encrypt)
@@ -1160,6 +1206,8 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
11601206
if (ret)
11611207
goto out_finalize;
11621208

1209+
rctx->key_id = ctx->key_id;
1210+
11631211
/* Allocate buffers required */
11641212
rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen + 100;
11651213
rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
@@ -1175,6 +1223,13 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
11751223
goto out_free_inbuf;
11761224
}
11771225

1226+
if (!ctx->key_id) {
1227+
ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key,
1228+
ctx->keylen, ctx->alg, &rctx->key_id);
1229+
if (ret)
1230+
goto out;
1231+
}
1232+
11781233
if (rctx->encrypt) {
11791234
/* CBC MAC Operation */
11801235
ret = tegra_ccm_compute_auth(ctx, rctx);
@@ -1205,6 +1260,9 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
12051260
dma_free_coherent(ctx->se->dev, rctx->outbuf.size,
12061261
rctx->inbuf.buf, rctx->inbuf.addr);
12071262

1263+
if (tegra_key_is_reserved(rctx->key_id))
1264+
tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg);
1265+
12081266
out_finalize:
12091267
crypto_finalize_aead_request(ctx->se->engine, req, ret);
12101268

@@ -1232,6 +1290,8 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12321290
memcpy(rctx->iv, req->iv, GCM_AES_IV_SIZE);
12331291
rctx->iv[3] = (1 << 24);
12341292

1293+
rctx->key_id = ctx->key_id;
1294+
12351295
/* Allocate buffers required */
12361296
rctx->inbuf.size = rctx->assoclen + rctx->authsize + rctx->cryptlen;
12371297
rctx->inbuf.buf = dma_alloc_coherent(ctx->se->dev, rctx->inbuf.size,
@@ -1249,6 +1309,13 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12491309
goto out_free_inbuf;
12501310
}
12511311

1312+
if (!ctx->key_id) {
1313+
ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key,
1314+
ctx->keylen, ctx->alg, &rctx->key_id);
1315+
if (ret)
1316+
goto out;
1317+
}
1318+
12521319
/* If there is associated data perform GMAC operation */
12531320
if (rctx->assoclen) {
12541321
ret = tegra_gcm_do_gmac(ctx, rctx);
@@ -1279,6 +1346,9 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12791346
dma_free_coherent(ctx->se->dev, rctx->inbuf.size,
12801347
rctx->inbuf.buf, rctx->inbuf.addr);
12811348

1349+
if (tegra_key_is_reserved(rctx->key_id))
1350+
tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg);
1351+
12821352
out_finalize:
12831353
crypto_finalize_aead_request(ctx->se->engine, req, ret);
12841354

@@ -1301,6 +1371,7 @@ static int tegra_aead_cra_init(struct crypto_aead *tfm)
13011371

13021372
ctx->se = se_alg->se_dev;
13031373
ctx->key_id = 0;
1374+
ctx->keylen = 0;
13041375

13051376
ret = se_algname_to_algid(algname);
13061377
if (ret < 0) {
@@ -1382,13 +1453,20 @@ static int tegra_aead_setkey(struct crypto_aead *tfm,
13821453
const u8 *key, u32 keylen)
13831454
{
13841455
struct tegra_aead_ctx *ctx = crypto_aead_ctx(tfm);
1456+
int ret;
13851457

13861458
if (aes_check_keylen(keylen)) {
13871459
dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
13881460
return -EINVAL;
13891461
}
13901462

1391-
return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
1463+
ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
1464+
if (ret) {
1465+
ctx->keylen = keylen;
1466+
memcpy(ctx->key, key, keylen);
1467+
}
1468+
1469+
return 0;
13921470
}
13931471

13941472
static unsigned int tegra_cmac_prep_cmd(struct tegra_cmac_ctx *ctx,
@@ -1473,6 +1551,7 @@ static int tegra_cmac_do_init(struct ahash_request *req)
14731551
rctx->total_len = 0;
14741552
rctx->datbuf.size = 0;
14751553
rctx->residue.size = 0;
1554+
rctx->key_id = ctx->key_id;
14761555
rctx->task |= SHA_FIRST;
14771556
rctx->blk_size = crypto_ahash_blocksize(tfm);
14781557

@@ -1517,7 +1596,7 @@ static int tegra_cmac_do_update(struct ahash_request *req)
15171596
rctx->datbuf.size = (req->nbytes + rctx->residue.size) - nresidue;
15181597
rctx->total_len += rctx->datbuf.size;
15191598
rctx->config = tegra234_aes_cfg(SE_ALG_CMAC, 0);
1520-
rctx->crypto_config = SE_AES_KEY_INDEX(ctx->key_id);
1599+
rctx->crypto_config = SE_AES_KEY_INDEX(rctx->key_id);
15211600

15221601
/*
15231602
* Keep one block and residue bytes in residue and
@@ -1643,6 +1722,13 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
16431722
rctx->task &= ~SHA_INIT;
16441723
}
16451724

1725+
if (!ctx->key_id) {
1726+
ret = tegra_key_submit_reserved_aes(ctx->se, ctx->key,
1727+
ctx->keylen, ctx->alg, &rctx->key_id);
1728+
if (ret)
1729+
goto out;
1730+
}
1731+
16461732
if (rctx->task & SHA_UPDATE) {
16471733
ret = tegra_cmac_do_update(req);
16481734
if (ret)
@@ -1659,6 +1745,9 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
16591745
rctx->task &= ~SHA_FINAL;
16601746
}
16611747
out:
1748+
if (tegra_key_is_reserved(rctx->key_id))
1749+
tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg);
1750+
16621751
crypto_finalize_hash_request(se->engine, req, ret);
16631752

16641753
return 0;
@@ -1699,6 +1788,7 @@ static int tegra_cmac_cra_init(struct crypto_tfm *tfm)
16991788

17001789
ctx->se = se_alg->se_dev;
17011790
ctx->key_id = 0;
1791+
ctx->keylen = 0;
17021792

17031793
ret = se_algname_to_algid(algname);
17041794
if (ret < 0) {
@@ -1727,6 +1817,7 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
17271817
unsigned int keylen)
17281818
{
17291819
struct tegra_cmac_ctx *ctx = crypto_ahash_ctx(tfm);
1820+
int ret;
17301821

17311822
if (aes_check_keylen(keylen)) {
17321823
dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
@@ -1736,7 +1827,13 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
17361827
if (ctx->fallback_tfm)
17371828
crypto_shash_setkey(ctx->fallback_tfm, key, keylen);
17381829

1739-
return tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
1830+
ret = tegra_key_submit(ctx->se, key, keylen, ctx->alg, &ctx->key_id);
1831+
if (ret) {
1832+
ctx->keylen = keylen;
1833+
memcpy(ctx->key, key, keylen);
1834+
}
1835+
1836+
return 0;
17401837
}
17411838

17421839
static int tegra_cmac_init(struct ahash_request *req)

0 commit comments

Comments
 (0)