@@ -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 = (ctx -> alg == SE_ALG_ECB ) ? NULL : (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}
@@ -447,12 +499,6 @@ static int tegra_aes_crypt(struct skcipher_request *req, bool encrypt)
447499 return 0 ;
448500
449501 rctx -> encrypt = encrypt ;
450- rctx -> config = tegra234_aes_cfg (ctx -> alg , encrypt );
451- rctx -> crypto_config = tegra234_aes_crypto_cfg (ctx -> alg , encrypt );
452- rctx -> crypto_config |= SE_AES_KEY_INDEX (ctx -> key1_id );
453-
454- if (ctx -> key2_id )
455- rctx -> crypto_config |= SE_AES_KEY2_INDEX (ctx -> key2_id );
456502
457503 return crypto_transfer_skcipher_request_to_engine (ctx -> se -> engine , req );
458504}
@@ -719,7 +765,7 @@ static int tegra_gcm_do_gmac(struct tegra_aead_ctx *ctx, struct tegra_aead_reqct
719765
720766 rctx -> config = tegra234_aes_cfg (SE_ALG_GMAC , rctx -> encrypt );
721767 rctx -> crypto_config = tegra234_aes_crypto_cfg (SE_ALG_GMAC , rctx -> encrypt ) |
722- SE_AES_KEY_INDEX (ctx -> key_id );
768+ SE_AES_KEY_INDEX (rctx -> key_id );
723769
724770 cmdlen = tegra_gmac_prep_cmd (ctx , rctx );
725771
@@ -736,7 +782,7 @@ static int tegra_gcm_do_crypt(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
736782
737783 rctx -> config = tegra234_aes_cfg (SE_ALG_GCM , rctx -> encrypt );
738784 rctx -> crypto_config = tegra234_aes_crypto_cfg (SE_ALG_GCM , rctx -> encrypt ) |
739- SE_AES_KEY_INDEX (ctx -> key_id );
785+ SE_AES_KEY_INDEX (rctx -> key_id );
740786
741787 /* Prepare command and submit */
742788 cmdlen = tegra_gcm_crypt_prep_cmd (ctx , rctx );
@@ -759,7 +805,7 @@ static int tegra_gcm_do_final(struct tegra_aead_ctx *ctx, struct tegra_aead_reqc
759805
760806 rctx -> config = tegra234_aes_cfg (SE_ALG_GCM_FINAL , rctx -> encrypt );
761807 rctx -> crypto_config = tegra234_aes_crypto_cfg (SE_ALG_GCM_FINAL , rctx -> encrypt ) |
762- SE_AES_KEY_INDEX (ctx -> key_id );
808+ SE_AES_KEY_INDEX (rctx -> key_id );
763809
764810 /* Prepare command and submit */
765811 cmdlen = tegra_gcm_prep_final_cmd (se , cpuvaddr , rctx );
@@ -890,7 +936,7 @@ static int tegra_ccm_do_cbcmac(struct tegra_aead_ctx *ctx, struct tegra_aead_req
890936 rctx -> config = tegra234_aes_cfg (SE_ALG_CBC_MAC , rctx -> encrypt );
891937 rctx -> crypto_config = tegra234_aes_crypto_cfg (SE_ALG_CBC_MAC ,
892938 rctx -> encrypt ) |
893- SE_AES_KEY_INDEX (ctx -> key_id );
939+ SE_AES_KEY_INDEX (rctx -> key_id );
894940
895941 /* Prepare command and submit */
896942 cmdlen = tegra_cbcmac_prep_cmd (ctx , rctx );
@@ -1077,7 +1123,7 @@ static int tegra_ccm_do_ctr(struct tegra_aead_ctx *ctx, struct tegra_aead_reqctx
10771123
10781124 rctx -> config = tegra234_aes_cfg (SE_ALG_CTR , rctx -> encrypt );
10791125 rctx -> crypto_config = tegra234_aes_crypto_cfg (SE_ALG_CTR , rctx -> encrypt ) |
1080- SE_AES_KEY_INDEX (ctx -> key_id );
1126+ SE_AES_KEY_INDEX (rctx -> key_id );
10811127
10821128 /* Copy authdata in the top of buffer for encryption/decryption */
10831129 if (rctx -> encrypt )
@@ -1158,6 +1204,8 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
11581204 if (ret )
11591205 goto out_finalize ;
11601206
1207+ rctx -> key_id = ctx -> key_id ;
1208+
11611209 /* Allocate buffers required */
11621210 rctx -> inbuf .size = rctx -> assoclen + rctx -> authsize + rctx -> cryptlen + 100 ;
11631211 rctx -> inbuf .buf = dma_alloc_coherent (ctx -> se -> dev , rctx -> inbuf .size ,
@@ -1173,6 +1221,13 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
11731221 goto out_free_inbuf ;
11741222 }
11751223
1224+ if (!ctx -> key_id ) {
1225+ ret = tegra_key_submit_reserved_aes (ctx -> se , ctx -> key ,
1226+ ctx -> keylen , ctx -> alg , & rctx -> key_id );
1227+ if (ret )
1228+ goto out ;
1229+ }
1230+
11761231 if (rctx -> encrypt ) {
11771232 /* CBC MAC Operation */
11781233 ret = tegra_ccm_compute_auth (ctx , rctx );
@@ -1203,6 +1258,9 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq)
12031258 dma_free_coherent (ctx -> se -> dev , rctx -> outbuf .size ,
12041259 rctx -> inbuf .buf , rctx -> inbuf .addr );
12051260
1261+ if (tegra_key_is_reserved (rctx -> key_id ))
1262+ tegra_key_invalidate_reserved (ctx -> se , rctx -> key_id , ctx -> alg );
1263+
12061264out_finalize :
12071265 crypto_finalize_aead_request (ctx -> se -> engine , req , ret );
12081266
@@ -1230,6 +1288,8 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12301288 memcpy (rctx -> iv , req -> iv , GCM_AES_IV_SIZE );
12311289 rctx -> iv [3 ] = (1 << 24 );
12321290
1291+ rctx -> key_id = ctx -> key_id ;
1292+
12331293 /* Allocate buffers required */
12341294 rctx -> inbuf .size = rctx -> assoclen + rctx -> authsize + rctx -> cryptlen ;
12351295 rctx -> inbuf .buf = dma_alloc_coherent (ctx -> se -> dev , rctx -> inbuf .size ,
@@ -1247,6 +1307,13 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12471307 goto out_free_inbuf ;
12481308 }
12491309
1310+ if (!ctx -> key_id ) {
1311+ ret = tegra_key_submit_reserved_aes (ctx -> se , ctx -> key ,
1312+ ctx -> keylen , ctx -> alg , & rctx -> key_id );
1313+ if (ret )
1314+ goto out ;
1315+ }
1316+
12501317 /* If there is associated data perform GMAC operation */
12511318 if (rctx -> assoclen ) {
12521319 ret = tegra_gcm_do_gmac (ctx , rctx );
@@ -1277,6 +1344,9 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq)
12771344 dma_free_coherent (ctx -> se -> dev , rctx -> inbuf .size ,
12781345 rctx -> inbuf .buf , rctx -> inbuf .addr );
12791346
1347+ if (tegra_key_is_reserved (rctx -> key_id ))
1348+ tegra_key_invalidate_reserved (ctx -> se , rctx -> key_id , ctx -> alg );
1349+
12801350out_finalize :
12811351 crypto_finalize_aead_request (ctx -> se -> engine , req , ret );
12821352
@@ -1299,6 +1369,7 @@ static int tegra_aead_cra_init(struct crypto_aead *tfm)
12991369
13001370 ctx -> se = se_alg -> se_dev ;
13011371 ctx -> key_id = 0 ;
1372+ ctx -> keylen = 0 ;
13021373
13031374 ret = se_algname_to_algid (algname );
13041375 if (ret < 0 ) {
@@ -1380,13 +1451,20 @@ static int tegra_aead_setkey(struct crypto_aead *tfm,
13801451 const u8 * key , u32 keylen )
13811452{
13821453 struct tegra_aead_ctx * ctx = crypto_aead_ctx (tfm );
1454+ int ret ;
13831455
13841456 if (aes_check_keylen (keylen )) {
13851457 dev_dbg (ctx -> se -> dev , "invalid key length (%d)\n" , keylen );
13861458 return - EINVAL ;
13871459 }
13881460
1389- return tegra_key_submit (ctx -> se , key , keylen , ctx -> alg , & ctx -> key_id );
1461+ ret = tegra_key_submit (ctx -> se , key , keylen , ctx -> alg , & ctx -> key_id );
1462+ if (ret ) {
1463+ ctx -> keylen = keylen ;
1464+ memcpy (ctx -> key , key , keylen );
1465+ }
1466+
1467+ return 0 ;
13901468}
13911469
13921470static unsigned int tegra_cmac_prep_cmd (struct tegra_cmac_ctx * ctx ,
@@ -1471,6 +1549,7 @@ static int tegra_cmac_do_init(struct ahash_request *req)
14711549 rctx -> total_len = 0 ;
14721550 rctx -> datbuf .size = 0 ;
14731551 rctx -> residue .size = 0 ;
1552+ rctx -> key_id = ctx -> key_id ;
14741553 rctx -> task |= SHA_FIRST ;
14751554 rctx -> blk_size = crypto_ahash_blocksize (tfm );
14761555
@@ -1515,7 +1594,7 @@ static int tegra_cmac_do_update(struct ahash_request *req)
15151594 rctx -> datbuf .size = (req -> nbytes + rctx -> residue .size ) - nresidue ;
15161595 rctx -> total_len += rctx -> datbuf .size ;
15171596 rctx -> config = tegra234_aes_cfg (SE_ALG_CMAC , 0 );
1518- rctx -> crypto_config = SE_AES_KEY_INDEX (ctx -> key_id );
1597+ rctx -> crypto_config = SE_AES_KEY_INDEX (rctx -> key_id );
15191598
15201599 /*
15211600 * Keep one block and residue bytes in residue and
@@ -1641,6 +1720,13 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
16411720 rctx -> task &= ~SHA_INIT ;
16421721 }
16431722
1723+ if (!ctx -> key_id ) {
1724+ ret = tegra_key_submit_reserved_aes (ctx -> se , ctx -> key ,
1725+ ctx -> keylen , ctx -> alg , & rctx -> key_id );
1726+ if (ret )
1727+ goto out ;
1728+ }
1729+
16441730 if (rctx -> task & SHA_UPDATE ) {
16451731 ret = tegra_cmac_do_update (req );
16461732 if (ret )
@@ -1657,6 +1743,9 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq)
16571743 rctx -> task &= ~SHA_FINAL ;
16581744 }
16591745out :
1746+ if (tegra_key_is_reserved (rctx -> key_id ))
1747+ tegra_key_invalidate_reserved (ctx -> se , rctx -> key_id , ctx -> alg );
1748+
16601749 crypto_finalize_hash_request (se -> engine , req , ret );
16611750
16621751 return 0 ;
@@ -1697,6 +1786,7 @@ static int tegra_cmac_cra_init(struct crypto_tfm *tfm)
16971786
16981787 ctx -> se = se_alg -> se_dev ;
16991788 ctx -> key_id = 0 ;
1789+ ctx -> keylen = 0 ;
17001790
17011791 ret = se_algname_to_algid (algname );
17021792 if (ret < 0 ) {
@@ -1725,6 +1815,7 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
17251815 unsigned int keylen )
17261816{
17271817 struct tegra_cmac_ctx * ctx = crypto_ahash_ctx (tfm );
1818+ int ret ;
17281819
17291820 if (aes_check_keylen (keylen )) {
17301821 dev_dbg (ctx -> se -> dev , "invalid key length (%d)\n" , keylen );
@@ -1734,7 +1825,13 @@ static int tegra_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
17341825 if (ctx -> fallback_tfm )
17351826 crypto_shash_setkey (ctx -> fallback_tfm , key , keylen );
17361827
1737- return tegra_key_submit (ctx -> se , key , keylen , ctx -> alg , & ctx -> key_id );
1828+ ret = tegra_key_submit (ctx -> se , key , keylen , ctx -> alg , & ctx -> key_id );
1829+ if (ret ) {
1830+ ctx -> keylen = keylen ;
1831+ memcpy (ctx -> key , key , keylen );
1832+ }
1833+
1834+ return 0 ;
17381835}
17391836
17401837static int tegra_cmac_init (struct ahash_request * req )
0 commit comments