@@ -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
3336struct 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
5054struct 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+
297335out_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
356402static 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+
12081266out_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+
12821352out_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
13941472static 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 }
16611747out :
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
17421839static int tegra_cmac_init (struct ahash_request * req )
0 commit comments