1515#include <linux/platform_device.h>
1616#include <linux/stmp_device.h>
1717#include <linux/clk.h>
18+ #include <soc/fsl/dcp.h>
1819
1920#include <crypto/aes.h>
2021#include <crypto/sha1.h>
@@ -101,6 +102,7 @@ struct dcp_async_ctx {
101102 struct crypto_skcipher * fallback ;
102103 unsigned int key_len ;
103104 uint8_t key [AES_KEYSIZE_128 ];
105+ bool key_referenced ;
104106};
105107
106108struct dcp_aes_req_ctx {
@@ -155,6 +157,7 @@ static struct dcp *global_sdcp;
155157#define MXS_DCP_CONTROL0_HASH_TERM (1 << 13)
156158#define MXS_DCP_CONTROL0_HASH_INIT (1 << 12)
157159#define MXS_DCP_CONTROL0_PAYLOAD_KEY (1 << 11)
160+ #define MXS_DCP_CONTROL0_OTP_KEY (1 << 10)
158161#define MXS_DCP_CONTROL0_CIPHER_ENCRYPT (1 << 8)
159162#define MXS_DCP_CONTROL0_CIPHER_INIT (1 << 9)
160163#define MXS_DCP_CONTROL0_ENABLE_HASH (1 << 6)
@@ -168,6 +171,8 @@ static struct dcp *global_sdcp;
168171#define MXS_DCP_CONTROL1_CIPHER_MODE_ECB (0 << 4)
169172#define MXS_DCP_CONTROL1_CIPHER_SELECT_AES128 (0 << 0)
170173
174+ #define MXS_DCP_CONTROL1_KEY_SELECT_SHIFT 8
175+
171176static int mxs_dcp_start_dma (struct dcp_async_ctx * actx )
172177{
173178 int dma_err ;
@@ -224,13 +229,16 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
224229 struct dcp * sdcp = global_sdcp ;
225230 struct dcp_dma_desc * desc = & sdcp -> coh -> desc [actx -> chan ];
226231 struct dcp_aes_req_ctx * rctx = skcipher_request_ctx (req );
232+ bool key_referenced = actx -> key_referenced ;
227233 int ret ;
228234
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+ }
234242
235243 src_phys = dma_map_single (sdcp -> dev , sdcp -> coh -> aes_in_buf ,
236244 DCP_BUF_SZ , DMA_TO_DEVICE );
@@ -255,8 +263,12 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
255263 MXS_DCP_CONTROL0_INTERRUPT |
256264 MXS_DCP_CONTROL0_ENABLE_CIPHER ;
257265
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 ;
260272
261273 if (rctx -> enc )
262274 desc -> control0 |= MXS_DCP_CONTROL0_CIPHER_ENCRYPT ;
@@ -270,6 +282,9 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
270282 else
271283 desc -> control1 |= MXS_DCP_CONTROL1_CIPHER_MODE_CBC ;
272284
285+ if (key_referenced )
286+ desc -> control1 |= sdcp -> coh -> aes_key [0 ] << MXS_DCP_CONTROL1_KEY_SELECT_SHIFT ;
287+
273288 desc -> next_cmd_addr = 0 ;
274289 desc -> source = src_phys ;
275290 desc -> destination = dst_phys ;
@@ -284,9 +299,9 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
284299err_dst :
285300 dma_unmap_single (sdcp -> dev , src_phys , DCP_BUF_SZ , DMA_TO_DEVICE );
286301err_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 );
290305 return ret ;
291306}
292307
@@ -453,7 +468,7 @@ static int mxs_dcp_aes_enqueue(struct skcipher_request *req, int enc, int ecb)
453468 struct dcp_aes_req_ctx * rctx = skcipher_request_ctx (req );
454469 int ret ;
455470
456- if (unlikely (actx -> key_len != AES_KEYSIZE_128 ))
471+ if (unlikely (actx -> key_len != AES_KEYSIZE_128 && ! actx -> key_referenced ))
457472 return mxs_dcp_block_fallback (req , enc );
458473
459474 rctx -> enc = enc ;
@@ -500,6 +515,7 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
500515 * there can still be an operation in progress.
501516 */
502517 actx -> key_len = len ;
518+ actx -> key_referenced = false;
503519 if (len == AES_KEYSIZE_128 ) {
504520 memcpy (actx -> key , key , len );
505521 return 0 ;
@@ -516,6 +532,32 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
516532 return crypto_skcipher_setkey (actx -> fallback , key , len );
517533}
518534
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+
519561static int mxs_dcp_aes_fallback_init_tfm (struct crypto_skcipher * tfm )
520562{
521563 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)
539581 crypto_free_skcipher (actx -> fallback );
540582}
541583
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+
542591/*
543592 * Hashing (SHA1/SHA256)
544593 */
@@ -889,6 +938,39 @@ static struct skcipher_alg dcp_aes_algs[] = {
889938 .ivsize = AES_BLOCK_SIZE ,
890939 .init = mxs_dcp_aes_fallback_init_tfm ,
891940 .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 ,
892974 },
893975};
894976
0 commit comments