15
15
#include <linux/platform_device.h>
16
16
#include <linux/stmp_device.h>
17
17
#include <linux/clk.h>
18
+ #include <soc/fsl/dcp.h>
18
19
19
20
#include <crypto/aes.h>
20
21
#include <crypto/sha1.h>
@@ -101,6 +102,7 @@ struct dcp_async_ctx {
101
102
struct crypto_skcipher * fallback ;
102
103
unsigned int key_len ;
103
104
uint8_t key [AES_KEYSIZE_128 ];
105
+ bool key_referenced ;
104
106
};
105
107
106
108
struct dcp_aes_req_ctx {
@@ -155,6 +157,7 @@ static struct dcp *global_sdcp;
155
157
#define MXS_DCP_CONTROL0_HASH_TERM (1 << 13)
156
158
#define MXS_DCP_CONTROL0_HASH_INIT (1 << 12)
157
159
#define MXS_DCP_CONTROL0_PAYLOAD_KEY (1 << 11)
160
+ #define MXS_DCP_CONTROL0_OTP_KEY (1 << 10)
158
161
#define MXS_DCP_CONTROL0_CIPHER_ENCRYPT (1 << 8)
159
162
#define MXS_DCP_CONTROL0_CIPHER_INIT (1 << 9)
160
163
#define MXS_DCP_CONTROL0_ENABLE_HASH (1 << 6)
@@ -168,6 +171,8 @@ static struct dcp *global_sdcp;
168
171
#define MXS_DCP_CONTROL1_CIPHER_MODE_ECB (0 << 4)
169
172
#define MXS_DCP_CONTROL1_CIPHER_SELECT_AES128 (0 << 0)
170
173
174
+ #define MXS_DCP_CONTROL1_KEY_SELECT_SHIFT 8
175
+
171
176
static int mxs_dcp_start_dma (struct dcp_async_ctx * actx )
172
177
{
173
178
int dma_err ;
@@ -224,13 +229,16 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
224
229
struct dcp * sdcp = global_sdcp ;
225
230
struct dcp_dma_desc * desc = & sdcp -> coh -> desc [actx -> chan ];
226
231
struct dcp_aes_req_ctx * rctx = skcipher_request_ctx (req );
232
+ bool key_referenced = actx -> key_referenced ;
227
233
int ret ;
228
234
229
- key_phys = dma_map_single (sdcp -> dev , sdcp -> coh -> aes_key ,
230
- 2 * AES_KEYSIZE_128 , DMA_TO_DEVICE );
231
- ret = dma_mapping_error (sdcp -> dev , key_phys );
232
- if (ret )
233
- return ret ;
235
+ if (!key_referenced ) {
236
+ key_phys = dma_map_single (sdcp -> dev , sdcp -> coh -> aes_key ,
237
+ 2 * AES_KEYSIZE_128 , DMA_TO_DEVICE );
238
+ ret = dma_mapping_error (sdcp -> dev , key_phys );
239
+ if (ret )
240
+ return ret ;
241
+ }
234
242
235
243
src_phys = dma_map_single (sdcp -> dev , sdcp -> coh -> aes_in_buf ,
236
244
DCP_BUF_SZ , DMA_TO_DEVICE );
@@ -255,8 +263,12 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
255
263
MXS_DCP_CONTROL0_INTERRUPT |
256
264
MXS_DCP_CONTROL0_ENABLE_CIPHER ;
257
265
258
- /* Payload contains the key. */
259
- desc -> control0 |= MXS_DCP_CONTROL0_PAYLOAD_KEY ;
266
+ if (key_referenced )
267
+ /* Set OTP key bit to select the key via KEY_SELECT. */
268
+ desc -> control0 |= MXS_DCP_CONTROL0_OTP_KEY ;
269
+ else
270
+ /* Payload contains the key. */
271
+ desc -> control0 |= MXS_DCP_CONTROL0_PAYLOAD_KEY ;
260
272
261
273
if (rctx -> enc )
262
274
desc -> control0 |= MXS_DCP_CONTROL0_CIPHER_ENCRYPT ;
@@ -270,6 +282,9 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
270
282
else
271
283
desc -> control1 |= MXS_DCP_CONTROL1_CIPHER_MODE_CBC ;
272
284
285
+ if (key_referenced )
286
+ desc -> control1 |= sdcp -> coh -> aes_key [0 ] << MXS_DCP_CONTROL1_KEY_SELECT_SHIFT ;
287
+
273
288
desc -> next_cmd_addr = 0 ;
274
289
desc -> source = src_phys ;
275
290
desc -> destination = dst_phys ;
@@ -284,9 +299,9 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
284
299
err_dst :
285
300
dma_unmap_single (sdcp -> dev , src_phys , DCP_BUF_SZ , DMA_TO_DEVICE );
286
301
err_src :
287
- dma_unmap_single ( sdcp -> dev , key_phys , 2 * AES_KEYSIZE_128 ,
288
- DMA_TO_DEVICE );
289
-
302
+ if (! key_referenced )
303
+ dma_unmap_single ( sdcp -> dev , key_phys , 2 * AES_KEYSIZE_128 ,
304
+ DMA_TO_DEVICE );
290
305
return ret ;
291
306
}
292
307
@@ -453,7 +468,7 @@ static int mxs_dcp_aes_enqueue(struct skcipher_request *req, int enc, int ecb)
453
468
struct dcp_aes_req_ctx * rctx = skcipher_request_ctx (req );
454
469
int ret ;
455
470
456
- if (unlikely (actx -> key_len != AES_KEYSIZE_128 ))
471
+ if (unlikely (actx -> key_len != AES_KEYSIZE_128 && ! actx -> key_referenced ))
457
472
return mxs_dcp_block_fallback (req , enc );
458
473
459
474
rctx -> enc = enc ;
@@ -500,6 +515,7 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
500
515
* there can still be an operation in progress.
501
516
*/
502
517
actx -> key_len = len ;
518
+ actx -> key_referenced = false;
503
519
if (len == AES_KEYSIZE_128 ) {
504
520
memcpy (actx -> key , key , len );
505
521
return 0 ;
@@ -516,6 +532,32 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
516
532
return crypto_skcipher_setkey (actx -> fallback , key , len );
517
533
}
518
534
535
+ static int mxs_dcp_aes_setrefkey (struct crypto_skcipher * tfm , const u8 * key ,
536
+ unsigned int len )
537
+ {
538
+ struct dcp_async_ctx * actx = crypto_skcipher_ctx (tfm );
539
+
540
+ if (len != DCP_PAES_KEYSIZE )
541
+ return - EINVAL ;
542
+
543
+ switch (key [0 ]) {
544
+ case DCP_PAES_KEY_SLOT0 :
545
+ case DCP_PAES_KEY_SLOT1 :
546
+ case DCP_PAES_KEY_SLOT2 :
547
+ case DCP_PAES_KEY_SLOT3 :
548
+ case DCP_PAES_KEY_UNIQUE :
549
+ case DCP_PAES_KEY_OTP :
550
+ memcpy (actx -> key , key , len );
551
+ actx -> key_len = len ;
552
+ actx -> key_referenced = true;
553
+ break ;
554
+ default :
555
+ return - EINVAL ;
556
+ }
557
+
558
+ return 0 ;
559
+ }
560
+
519
561
static int mxs_dcp_aes_fallback_init_tfm (struct crypto_skcipher * tfm )
520
562
{
521
563
const char * name = crypto_tfm_alg_name (crypto_skcipher_tfm (tfm ));
@@ -539,6 +581,13 @@ static void mxs_dcp_aes_fallback_exit_tfm(struct crypto_skcipher *tfm)
539
581
crypto_free_skcipher (actx -> fallback );
540
582
}
541
583
584
+ static int mxs_dcp_paes_init_tfm (struct crypto_skcipher * tfm )
585
+ {
586
+ crypto_skcipher_set_reqsize (tfm , sizeof (struct dcp_aes_req_ctx ));
587
+
588
+ return 0 ;
589
+ }
590
+
542
591
/*
543
592
* Hashing (SHA1/SHA256)
544
593
*/
@@ -889,6 +938,39 @@ static struct skcipher_alg dcp_aes_algs[] = {
889
938
.ivsize = AES_BLOCK_SIZE ,
890
939
.init = mxs_dcp_aes_fallback_init_tfm ,
891
940
.exit = mxs_dcp_aes_fallback_exit_tfm ,
941
+ }, {
942
+ .base .cra_name = "ecb(paes)" ,
943
+ .base .cra_driver_name = "ecb-paes-dcp" ,
944
+ .base .cra_priority = 401 ,
945
+ .base .cra_alignmask = 15 ,
946
+ .base .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_INTERNAL ,
947
+ .base .cra_blocksize = AES_BLOCK_SIZE ,
948
+ .base .cra_ctxsize = sizeof (struct dcp_async_ctx ),
949
+ .base .cra_module = THIS_MODULE ,
950
+
951
+ .min_keysize = DCP_PAES_KEYSIZE ,
952
+ .max_keysize = DCP_PAES_KEYSIZE ,
953
+ .setkey = mxs_dcp_aes_setrefkey ,
954
+ .encrypt = mxs_dcp_aes_ecb_encrypt ,
955
+ .decrypt = mxs_dcp_aes_ecb_decrypt ,
956
+ .init = mxs_dcp_paes_init_tfm ,
957
+ }, {
958
+ .base .cra_name = "cbc(paes)" ,
959
+ .base .cra_driver_name = "cbc-paes-dcp" ,
960
+ .base .cra_priority = 401 ,
961
+ .base .cra_alignmask = 15 ,
962
+ .base .cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_INTERNAL ,
963
+ .base .cra_blocksize = AES_BLOCK_SIZE ,
964
+ .base .cra_ctxsize = sizeof (struct dcp_async_ctx ),
965
+ .base .cra_module = THIS_MODULE ,
966
+
967
+ .min_keysize = DCP_PAES_KEYSIZE ,
968
+ .max_keysize = DCP_PAES_KEYSIZE ,
969
+ .setkey = mxs_dcp_aes_setrefkey ,
970
+ .encrypt = mxs_dcp_aes_cbc_encrypt ,
971
+ .decrypt = mxs_dcp_aes_cbc_decrypt ,
972
+ .ivsize = AES_BLOCK_SIZE ,
973
+ .init = mxs_dcp_paes_init_tfm ,
892
974
},
893
975
};
894
976
0 commit comments