forked from openwrt/openwrt
-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
804-crypto-0020-MLKU-25-3-crypto-caam-add-Secure-Memory-support.patch
2503 lines (2476 loc) · 78.7 KB
/
804-crypto-0020-MLKU-25-3-crypto-caam-add-Secure-Memory-support.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
From 32221046a302245a63d5e00d16cf3008b5b31255 Mon Sep 17 00:00:00 2001
From: Steve Cornelius <steve.cornelius@freescale.com>
Date: Tue, 23 Jul 2013 20:47:32 -0700
Subject: [PATCH] MLKU-25-3 crypto: caam - add Secure Memory support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a squash of the following i.MX BSP commits
(rel_imx_4.19.35_1.1.0_rc2)
1. ae8175a3f1be ("MLK-9710-10 Add CCM defs for FIFO_STORE instruction")
2. 9512280d066b ("MLK-9769-11 Add SM register defs, and expanded driver-private storage.")
3. a9dc44de8150 ("MLK-9769-10 Add Blob command bitdefs.")
4. 8f6a17b41917 ("ENGR00289885 [iMX6Q] Add Secure Memory and SECVIO support.")
5. c7d4f9db1077 ("MLK-9710-11 Add internal key cover and external blob export/import to prototype SM-API")
6. 568e449edfca ("MLK-9710-12 Adapt sm_test as a black-key handling example")
7. f42f12d9cb19 ("MLK-9710-13 Correct size in BLOB_OVERHEAD definition")
8. 022fc2b33f57 ("MLK-9710-14 Un-pad cache sizes for blob export/import")
9. 8d3e8c3c4dc1 ("MLK-9710-15 Correct size of padded key buffers")
10. 997fb2ff88ec ("MLK-9710-5 Unregister Secure Memory platform device upon shutdown")
11. 5316249198ee ("MLK-10897-1 ARM: imx7d: Add CAAM support for i.mx7d")
12. 07566f42a4ec ("MLK-11103 Missing register in Secure memory configuration v1")
13. 3004636304e1 ("MLK-12302 caam: Secure Memory platform device creation crashes")
14. 0e6ed5a819f7 ("MLK-13779 crypto: caam - initialize kslock spinlock")
15. b1254b6b5f52 ("Add missing NULL checks in CAAM sm")
16. 61f57509bc9a ("MLK-17992: caam: sm: Fix compilation warnings")
17. 41cf3d4c580c ("MLK-15473-1: crypto: caam: Add CAAM driver support for iMX8 soc family")
18. bb8742481209 ("MLK-17253-1: crypto: caam: Fix computation of SM pages addresses")
19. 308796dfae3b ("MLK-17253-2: crypto: caam: Use correct memory function for Secure Memory")
20. ba2cb6b5fb10 ("MLK-17732-2: SM store: Support iMX8QX and iMX8QM")
21. de710d376af6 ("MLK-17674-1: sm_store remove CONFIG_OF")
22. cfcae647434e ("MLK-17674-2: CAAM SM : get base address from device tree")
23. f49ebbd5eefa ("MLK-17992: caam: sm: Fix compilation warnings")
24. 345ead4338b9 ("MLK-17841: crypto: caam: Correct bugs in Secure Memory")
25. c17811f3fffc ("MLK-18082: crypto: caam: sm: Fix encap/decap function to handle errors")
26. 41bcba1d4c9b ("MLK-18082: crypto: caam: sm: Fix descriptor running functions")
27. b7385ab94784 ("MLK-20204: drivers: crypto: caam: sm: Remove deadcode")
28. 1d749430cb63 ("MLK-20204: drivers: crypto: caam: sm: test: Dealloc keyslot properly")
29. 6a5c2d9d358f ("crypto: caam - lower SM test verbosity")
30. 1a6bc92c0c87 ("MLK-21617: crypto: caam - update SM test error handling")
Signed-off-by: Dan Douglass <dan.douglass@nxp.com>
Signed-off-by: Victoria Milhoan <vicki.milhoan@freescale.com>
Signed-off-by: Steve Cornelius <steve.cornelius@nxp.com>
Signed-off-by: Octavian Purdila <octavian.purdila@nxp.com>
Signed-off-by: Radu Solea <radu.solea@nxp.com>
Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Silvano di Ninno <silvano.dininno@nxp.com>
that have been reworked:
4.
-make SM depend on JR
-enable SM, SECVIO only on i.MX SoCs
-fix resource leak - add off_node_put() where needed
Split commit in three:
1 - SNVS/SECVIO driver
2 - Secure Memory driver
3 - DT changes
11.
Clock handling dropped - logic already upstream.
17.
Keep only Secure Memory related changes.
Changes related to page 0 registers have been added previously.
Other changes are dropped.
21.
Always use first jr in ctrlpriv->jr[] array to access registers
in page 0 (aliased in jr page), irrespective of SCU presence.
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
---
drivers/crypto/caam/Kconfig | 30 +
drivers/crypto/caam/Makefile | 2 +
drivers/crypto/caam/ctrl.c | 37 ++
drivers/crypto/caam/desc.h | 21 +
drivers/crypto/caam/intern.h | 4 +
drivers/crypto/caam/regs.h | 158 ++++-
drivers/crypto/caam/sm.h | 127 ++++
drivers/crypto/caam/sm_store.c | 1332 ++++++++++++++++++++++++++++++++++++++++
drivers/crypto/caam/sm_test.c | 571 +++++++++++++++++
9 files changed, 2279 insertions(+), 3 deletions(-)
create mode 100644 drivers/crypto/caam/sm.h
create mode 100644 drivers/crypto/caam/sm_store.c
create mode 100644 drivers/crypto/caam/sm_test.c
--- a/drivers/crypto/caam/Kconfig
+++ b/drivers/crypto/caam/Kconfig
@@ -155,6 +155,36 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST
caam RNG. This test is several minutes long and executes
just before the RNG is registered with the hw_random API.
+config CRYPTO_DEV_FSL_CAAM_SM
+ tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)"
+ help
+ Enables use of a prototype kernel-level Keystore API with CAAM
+ Secure Memory for insertion/extraction of bus-protected secrets.
+
+config CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE
+ int "Size of each keystore slot in Secure Memory"
+ depends on CRYPTO_DEV_FSL_CAAM_SM
+ range 5 9
+ default 7
+ help
+ Select size of allocation units to divide Secure Memory pages into
+ (the size of a "slot" as referenced inside the API code).
+ Established as powers of two.
+ Examples:
+ 5 => 32 bytes
+ 6 => 64 bytes
+ 7 => 128 bytes
+ 8 => 256 bytes
+ 9 => 512 bytes
+
+config CRYPTO_DEV_FSL_CAAM_SM_TEST
+ tristate "CAAM Secure Memory - Keystore Test/Example (EXPERIMENTAL)"
+ depends on CRYPTO_DEV_FSL_CAAM_SM
+ help
+ Example thread to exercise the Keystore API and to verify that
+ stored and recovered secrets can be used for general purpose
+ encryption/decryption.
+
config CRYPTO_DEV_FSL_CAAM_SECVIO
tristate "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)"
help
--- a/drivers/crypto/caam/Makefile
+++ b/drivers/crypto/caam/Makefile
@@ -21,6 +21,8 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRY
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o
+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o
+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o
caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o
caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -17,6 +17,7 @@
#include "jr.h"
#include "desc_constr.h"
#include "ctrl.h"
+#include "sm.h"
bool caam_dpaa2;
EXPORT_SYMBOL(caam_dpaa2);
@@ -573,6 +574,7 @@ static int caam_probe(struct platform_de
const struct soc_device_attribute *imx_soc_match;
struct device *dev;
struct device_node *nprop, *np;
+ struct resource res_regs;
struct caam_ctrl __iomem *ctrl;
struct caam_drv_private *ctrlpriv;
struct caam_perfmon __iomem *perfmon;
@@ -719,9 +721,44 @@ iomap_ctrl:
BLOCK_OFFSET * DECO_BLOCK_NUMBER
);
+ /* Only i.MX SoCs have sm */
+ if (!imx_soc_match)
+ goto mc_fw;
+
+ /* Get CAAM-SM node and of_iomap() and save */
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm");
+ if (!np)
+ return -ENODEV;
+
+ /* Get CAAM SM registers base address from device tree */
+ ret = of_address_to_resource(np, 0, &res_regs);
+ if (ret) {
+ dev_err(dev, "failed to retrieve registers base from device tree\n");
+ of_node_put(np);
+ return -ENODEV;
+ }
+
+ ctrlpriv->sm_phy = res_regs.start;
+ ctrlpriv->sm_base = devm_ioremap_resource(dev, &res_regs);
+ if (IS_ERR(ctrlpriv->sm_base)) {
+ of_node_put(np);
+ return PTR_ERR(ctrlpriv->sm_base);
+ }
+
+ if (!of_machine_is_compatible("fsl,imx8mn") &&
+ !of_machine_is_compatible("fsl,imx8mm") &&
+ !of_machine_is_compatible("fsl,imx8mq") &&
+ !of_machine_is_compatible("fsl,imx8qm") &&
+ !of_machine_is_compatible("fsl,imx8qxp"))
+ ctrlpriv->sm_size = resource_size(&res_regs);
+ else
+ ctrlpriv->sm_size = PG_SIZE_64K;
+ of_node_put(np);
+
if (!reg_access)
goto set_dma_mask;
+mc_fw:
/*
* Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
* long pointers in master configuration register.
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -403,6 +403,10 @@
#define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_CCM_JKEK (0x10 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_CCM_TKEK (0x11 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_CCM_JKEK (0x14 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_CCM_TKEK (0x15 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_JKEK (0x20 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
#define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT)
@@ -1136,6 +1140,23 @@
#define OP_PCL_PKPROT_ECC 0x0002
#define OP_PCL_PKPROT_F2M 0x0001
+/* Blob protocol protinfo bits */
+#define OP_PCL_BLOB_TK 0x0200
+#define OP_PCL_BLOB_EKT 0x0100
+
+#define OP_PCL_BLOB_K2KR_MEM 0x0000
+#define OP_PCL_BLOB_K2KR_C1KR 0x0010
+#define OP_PCL_BLOB_K2KR_C2KR 0x0030
+#define OP_PCL_BLOB_K2KR_AFHAS 0x0050
+#define OP_PCL_BLOB_K2KR_C2KR_SPLIT 0x0070
+
+#define OP_PCL_BLOB_PTXT_SECMEM 0x0008
+#define OP_PCL_BLOB_BLACK 0x0004
+
+#define OP_PCL_BLOB_FMT_NORMAL 0x0000
+#define OP_PCL_BLOB_FMT_MSTR 0x0002
+#define OP_PCL_BLOB_FMT_TEST 0x0003
+
/* For non-protocol/alg-only op commands */
#define OP_ALG_TYPE_SHIFT 24
#define OP_ALG_TYPE_MASK (0x7 << OP_ALG_TYPE_SHIFT)
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -66,6 +66,7 @@ struct caam_drv_private_jr {
* Driver-private storage for a single CAAM block instance
*/
struct caam_drv_private {
+ struct device *smdev;
/* Physical-presence section */
struct caam_ctrl __iomem *ctrl; /* controller region */
@@ -73,6 +74,9 @@ struct caam_drv_private {
struct caam_assurance __iomem *assure;
struct caam_queue_if __iomem *qi; /* QI control region */
struct caam_job_ring __iomem *jr[4]; /* JobR's register space */
+ dma_addr_t __iomem *sm_base; /* Secure memory storage base */
+ phys_addr_t sm_phy; /* Secure memory storage physical */
+ u32 sm_size;
struct iommu_domain *domain;
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -382,6 +382,12 @@ struct version_regs {
#define CHA_VER_VID_MD_LP512 0x1ull
#define CHA_VER_VID_MD_HP 0x2ull
+/*
+ * caam_perfmon - Performance Monitor/Secure Memory Status/
+ * CAAM Global Status/Component Version IDs
+ *
+ * Spans f00-fff wherever instantiated
+ */
struct sec_vid {
u16 ip_id;
u8 maj_rev;
@@ -412,17 +418,22 @@ struct caam_perfmon {
#define CTPR_MS_PG_SZ_SHIFT 4
u32 comp_parms_ms; /* CTPR - Compile Parameters Register */
u32 comp_parms_ls; /* CTPR - Compile Parameters Register */
- u64 rsvd1[2];
+ /* Secure Memory State Visibility */
+ u32 rsvd1;
+ u32 smstatus; /* Secure memory status */
+ u32 rsvd2;
+ u32 smpartown; /* Secure memory partition owner */
/* CAAM Global Status fc0-fdf */
u64 faultaddr; /* FAR - Fault Address */
u32 faultliodn; /* FALR - Fault Address LIODN */
u32 faultdetail; /* FADR - Fault Addr Detail */
- u32 rsvd2;
#define CSTA_PLEND BIT(10)
#define CSTA_ALT_PLEND BIT(18)
+ u32 rsvd3;
u32 status; /* CSTA - CAAM Status */
- u64 rsvd3;
+ u32 smpart; /* Secure Memory Partition Parameters */
+ u32 smvid; /* Secure Memory Version ID */
/* Component Instantiation Parameters fe0-fff */
u32 rtic_id; /* RVID - RTIC Version ID */
@@ -441,6 +452,62 @@ struct caam_perfmon {
u32 caam_id_ls; /* CAAMVID - CAAM Version ID LS */
};
+#define SMSTATUS_PART_SHIFT 28
+#define SMSTATUS_PART_MASK (0xf << SMSTATUS_PART_SHIFT)
+#define SMSTATUS_PAGE_SHIFT 16
+#define SMSTATUS_PAGE_MASK (0x7ff << SMSTATUS_PAGE_SHIFT)
+#define SMSTATUS_MID_SHIFT 8
+#define SMSTATUS_MID_MASK (0x3f << SMSTATUS_MID_SHIFT)
+#define SMSTATUS_ACCERR_SHIFT 4
+#define SMSTATUS_ACCERR_MASK (0xf << SMSTATUS_ACCERR_SHIFT)
+#define SMSTATUS_ACCERR_NONE 0
+#define SMSTATUS_ACCERR_ALLOC 1 /* Page not allocated */
+#define SMSTATUS_ACCESS_ID 2 /* Not granted by ID */
+#define SMSTATUS_ACCESS_WRITE 3 /* Writes not allowed */
+#define SMSTATUS_ACCESS_READ 4 /* Reads not allowed */
+#define SMSTATUS_ACCESS_NONKEY 6 /* Non-key reads not allowed */
+#define SMSTATUS_ACCESS_BLOB 9 /* Blob access not allowed */
+#define SMSTATUS_ACCESS_DESCB 10 /* Descriptor Blob access spans pages */
+#define SMSTATUS_ACCESS_NON_SM 11 /* Outside Secure Memory range */
+#define SMSTATUS_ACCESS_XPAGE 12 /* Access crosses pages */
+#define SMSTATUS_ACCESS_INITPG 13 /* Page still initializing */
+#define SMSTATUS_STATE_SHIFT 0
+#define SMSTATUS_STATE_MASK (0xf << SMSTATUS_STATE_SHIFT)
+#define SMSTATUS_STATE_RESET 0
+#define SMSTATUS_STATE_INIT 1
+#define SMSTATUS_STATE_NORMAL 2
+#define SMSTATUS_STATE_FAIL 3
+
+/* up to 15 rings, 2 bits shifted by ring number */
+#define SMPARTOWN_RING_SHIFT 2
+#define SMPARTOWN_RING_MASK 3
+#define SMPARTOWN_AVAILABLE 0
+#define SMPARTOWN_NOEXIST 1
+#define SMPARTOWN_UNAVAILABLE 2
+#define SMPARTOWN_OURS 3
+
+/* Maximum number of pages possible */
+#define SMPART_MAX_NUMPG_SHIFT 16
+#define SMPART_MAX_NUMPG_MASK (0x3f << SMPART_MAX_NUMPG_SHIFT)
+
+/* Maximum partition number */
+#define SMPART_MAX_PNUM_SHIFT 12
+#define SMPART_MAX_PNUM_MASK (0xf << SMPART_MAX_PNUM_SHIFT)
+
+/* Highest possible page number */
+#define SMPART_MAX_PG_SHIFT 0
+#define SMPART_MAX_PG_MASK (0x3f << SMPART_MAX_PG_SHIFT)
+
+/* Max size of a page */
+#define SMVID_PG_SIZE_SHIFT 16
+#define SMVID_PG_SIZE_MASK (0x7 << SMVID_PG_SIZE_SHIFT)
+
+/* Major/Minor Version ID */
+#define SMVID_MAJ_VERS_SHIFT 8
+#define SMVID_MAJ_VERS (0xf << SMVID_MAJ_VERS_SHIFT)
+#define SMVID_MIN_VERS_SHIFT 0
+#define SMVID_MIN_VERS (0xf << SMVID_MIN_VERS_SHIFT)
+
/* LIODN programming for DMA configuration */
#define MSTRID_LOCK_LIODN 0x80000000
#define MSTRID_LOCK_MAKETRUSTED 0x00010000 /* only for JR masterid */
@@ -645,6 +712,35 @@ struct caam_ctrl {
#define JRSTART_JR2_START 0x00000004 /* Start Job ring 2 */
#define JRSTART_JR3_START 0x00000008 /* Start Job ring 3 */
+/* Secure Memory Configuration - if you have it */
+/* Secure Memory Register Offset from JR Base Reg*/
+#define SM_V1_OFFSET 0x0f4
+#define SM_V2_OFFSET 0xa00
+
+/* Minimum SM Version ID requiring v2 SM register mapping */
+#define SMVID_V2 0x20105
+
+struct caam_secure_mem_v1 {
+ u32 sm_cmd; /* SMCJRx - Secure memory command */
+ u32 rsvd1;
+ u32 sm_status; /* SMCSJRx - Secure memory status */
+ u32 rsvd2;
+
+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */
+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
+};
+
+struct caam_secure_mem_v2 {
+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */
+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */
+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */
+ u32 rsvd1[118];
+ u32 sm_cmd; /* SMCJRx - Secure memory command */
+ u32 rsvd2;
+ u32 sm_status; /* SMCSJRx - Secure memory status */
+};
+
/*
* caam_job_ring - direct job ring setup
* 1-4 possible per instantiation, base + 1000/2000/3000/4000
@@ -815,6 +911,62 @@ struct caam_job_ring {
#define JRCR_RESET 0x01
+/* secure memory command */
+#define SMC_PAGE_SHIFT 16
+#define SMC_PAGE_MASK (0xffff << SMC_PAGE_SHIFT)
+#define SMC_PART_SHIFT 8
+#define SMC_PART_MASK (0x0f << SMC_PART_SHIFT)
+#define SMC_CMD_SHIFT 0
+#define SMC_CMD_MASK (0x0f << SMC_CMD_SHIFT)
+
+#define SMC_CMD_ALLOC_PAGE 0x01 /* allocate page to this partition */
+#define SMC_CMD_DEALLOC_PAGE 0x02 /* deallocate page from partition */
+#define SMC_CMD_DEALLOC_PART 0x03 /* deallocate partition */
+#define SMC_CMD_PAGE_INQUIRY 0x05 /* find partition associate with page */
+
+/* secure memory (command) status */
+#define SMCS_PAGE_SHIFT 16
+#define SMCS_PAGE_MASK (0x0fff << SMCS_PAGE_SHIFT)
+#define SMCS_CMDERR_SHIFT 14
+#define SMCS_CMDERR_MASK (3 << SMCS_CMDERR_SHIFT)
+#define SMCS_ALCERR_SHIFT 12
+#define SMCS_ALCERR_MASK (3 << SMCS_ALCERR_SHIFT)
+#define SMCS_PGOWN_SHIFT 6
+#define SMCS_PGWON_MASK (3 << SMCS_PGOWN_SHIFT)
+#define SMCS_PART_SHIFT 0
+#define SMCS_PART_MASK (0xf << SMCS_PART_SHIFT)
+
+#define SMCS_CMDERR_NONE 0
+#define SMCS_CMDERR_INCOMP 1 /* Command not yet complete */
+#define SMCS_CMDERR_SECFAIL 2 /* Security failure occurred */
+#define SMCS_CMDERR_OVERFLOW 3 /* Command overflow */
+
+#define SMCS_ALCERR_NONE 0
+#define SMCS_ALCERR_PSPERR 1 /* Partion marked PSP (dealloc only) */
+#define SMCS_ALCERR_PAGEAVAIL 2 /* Page not available */
+#define SMCS_ALCERR_PARTOWN 3 /* Partition ownership error */
+
+#define SMCS_PGOWN_AVAIL 0 /* Page is available */
+#define SMCS_PGOWN_NOEXIST 1 /* Page initializing or nonexistent */
+#define SMCS_PGOWN_NOOWN 2 /* Page owned by another processor */
+#define SMCS_PGOWN_OWNED 3 /* Page belongs to this processor */
+
+/* secure memory access permissions */
+#define SMCS_PERM_KEYMOD_SHIFT 16
+#define SMCA_PERM_KEYMOD_MASK (0xff << SMCS_PERM_KEYMOD_SHIFT)
+#define SMCA_PERM_CSP_ZERO 0x8000 /* Zero when deallocated or released */
+#define SMCA_PERM_PSP_LOCK 0x4000 /* Part./pages can't be deallocated */
+#define SMCA_PERM_PERM_LOCK 0x2000 /* Lock permissions */
+#define SMCA_PERM_GRP_LOCK 0x1000 /* Lock access groups */
+#define SMCA_PERM_RINGID_SHIFT 10
+#define SMCA_PERM_RINGID_MASK (3 << SMCA_PERM_RINGID_SHIFT)
+#define SMCA_PERM_G2_BLOB 0x0080 /* Group 2 blob import/export */
+#define SMCA_PERM_G2_WRITE 0x0020 /* Group 2 write */
+#define SMCA_PERM_G2_READ 0x0010 /* Group 2 read */
+#define SMCA_PERM_G1_BLOB 0x0008 /* Group 1... */
+#define SMCA_PERM_G1_WRITE 0x0002
+#define SMCA_PERM_G1_READ 0x0001
+
/*
* caam_assurance - Assurance Controller View
* base + 0x6000 padded out to 0x1000
--- /dev/null
+++ b/drivers/crypto/caam/sm.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * CAAM Secure Memory/Keywrap API Definitions
+ *
+ * Copyright 2008-2015 Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ */
+
+#ifndef SM_H
+#define SM_H
+
+
+/* Storage access permissions */
+#define SM_PERM_READ 0x01
+#define SM_PERM_WRITE 0x02
+#define SM_PERM_BLOB 0x03
+
+/* Define treatment of secure memory vs. general memory blobs */
+#define SM_SECMEM 0
+#define SM_GENMEM 1
+
+/* Define treatment of red/black keys */
+#define RED_KEY 0
+#define BLACK_KEY 1
+
+/* Define key encryption/covering options */
+#define KEY_COVER_ECB 0 /* cover key in AES-ECB */
+#define KEY_COVER_CCM 1 /* cover key with AES-CCM */
+
+/*
+ * Round a key size up to an AES blocksize boundary so to allow for
+ * padding out to a full block
+ */
+#define AES_BLOCK_PAD(x) ((x % 16) ? ((x >> 4) + 1) << 4 : x)
+
+/* Define space required for BKEK + MAC tag storage in any blob */
+#define BLOB_OVERHEAD (32 + 16)
+
+/* Keystore maintenance functions */
+void sm_init_keystore(struct device *dev);
+u32 sm_detect_keystore_units(struct device *dev);
+int sm_establish_keystore(struct device *dev, u32 unit);
+void sm_release_keystore(struct device *dev, u32 unit);
+void caam_sm_shutdown(struct platform_device *pdev);
+int caam_sm_example_init(struct platform_device *pdev);
+
+/* Keystore accessor functions */
+extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size,
+ u32 *slot);
+extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot);
+extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot,
+ const u8 *key_data, u32 key_length);
+extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot,
+ u32 key_length, u8 *key_data);
+extern int sm_keystore_cover_key(struct device *dev, u32 unit, u32 slot,
+ u16 key_length, u8 keyauth);
+extern int sm_keystore_slot_export(struct device *dev, u32 unit, u32 slot,
+ u8 keycolor, u8 keyauth, u8 *outbuf,
+ u16 keylen, u8 *keymod);
+extern int sm_keystore_slot_import(struct device *dev, u32 unit, u32 slot,
+ u8 keycolor, u8 keyauth, u8 *inbuf,
+ u16 keylen, u8 *keymod);
+
+/* Prior functions from legacy API, deprecated */
+extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit,
+ u32 inslot, u32 outslot, u16 secretlen,
+ u8 *keymod, u16 keymodlen);
+extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit,
+ u32 inslot, u32 outslot, u16 secretlen,
+ u8 *keymod, u16 keymodlen);
+
+/* Data structure to hold per-slot information */
+struct keystore_data_slot_info {
+ u8 allocated; /* Track slot assignments */
+ u32 key_length; /* Size of the key */
+};
+
+/* Data structure to hold keystore information */
+struct keystore_data {
+ void *base_address; /* Virtual base of secure memory pages */
+ void *phys_address; /* Physical base of secure memory pages */
+ u32 slot_count; /* Number of slots in the keystore */
+ struct keystore_data_slot_info *slot; /* Per-slot information */
+};
+
+/* store the detected attributes of a secure memory page */
+struct sm_page_descriptor {
+ u16 phys_pagenum; /* may be discontiguous */
+ u16 own_part; /* Owning partition */
+ void *pg_base; /* Calculated virtual address */
+ void *pg_phys; /* Calculated physical address */
+ struct keystore_data *ksdata;
+};
+
+struct caam_drv_private_sm {
+ struct device *parentdev; /* this ends up as the controller */
+ struct device *smringdev; /* ring that owns this instance */
+ struct platform_device *sm_pdev; /* Secure Memory platform device */
+ spinlock_t kslock ____cacheline_aligned;
+
+ /* SM Register offset from JR base address */
+ u32 sm_reg_offset;
+
+ /* Default parameters for geometry */
+ u32 max_pages; /* maximum pages this instance can support */
+ u32 top_partition; /* highest partition number in this instance */
+ u32 top_page; /* highest page number in this instance */
+ u32 page_size; /* page size */
+ u32 slot_size; /* selected size of each storage block */
+
+ /* Partition/Page Allocation Map */
+ u32 localpages; /* Number of pages we can access */
+ struct sm_page_descriptor *pagedesc; /* Allocated per-page */
+
+ /* Installed handlers for keystore access */
+ int (*data_init)(struct device *dev, u32 unit);
+ void (*data_cleanup)(struct device *dev, u32 unit);
+ int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot);
+ int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot);
+ void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle);
+ void *(*slot_get_physical)(struct device *dev, u32 unit, u32 handle);
+ u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle);
+ u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle);
+ u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle);
+};
+
+#endif /* SM_H */
--- /dev/null
+++ b/drivers/crypto/caam/sm_store.c
@@ -0,0 +1,1332 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * CAAM Secure Memory Storage Interface
+ *
+ * Copyright 2008-2015 Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ *
+ * Loosely based on the SHW Keystore API for SCC/SCC2
+ * Experimental implementation and NOT intended for upstream use. Expect
+ * this interface to be amended significantly in the future once it becomes
+ * integrated into live applications.
+ *
+ * Known issues:
+ *
+ * - Executes one instance of an secure memory "driver". This is tied to the
+ * fact that job rings can't run as standalone instances in the present
+ * configuration.
+ *
+ * - It does not expose a userspace interface. The value of a userspace
+ * interface for access to secrets is a point for further architectural
+ * discussion.
+ *
+ * - Partition/permission management is not part of this interface. It
+ * depends on some level of "knowledge" agreed upon between bootloader,
+ * provisioning applications, and OS-hosted software (which uses this
+ * driver).
+ *
+ * - No means of identifying the location or purpose of secrets managed by
+ * this interface exists; "slot location" and format of a given secret
+ * needs to be agreed upon between bootloader, provisioner, and OS-hosted
+ * application.
+ */
+
+#include "compat.h"
+#include "regs.h"
+#include "jr.h"
+#include "desc.h"
+#include "intern.h"
+#include "error.h"
+#include "sm.h"
+#include <linux/of_address.h>
+
+#define SECMEM_KEYMOD_LEN 8
+#define GENMEM_KEYMOD_LEN 16
+
+#ifdef SM_DEBUG_CONT
+void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc)
+{
+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev);
+ u32 i, *smdata;
+
+ dev_info(dev, "physical page %d content at 0x%08x\n",
+ pgdesc->phys_pagenum, pgdesc->pg_base);
+ smdata = pgdesc->pg_base;
+ for (i = 0; i < (smpriv->page_size / sizeof(u32)); i += 4)
+ dev_info(dev, "[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ (u32)&smdata[i], smdata[i], smdata[i+1], smdata[i+2],
+ smdata[i+3]);
+}
+#endif
+
+#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */
+
+static __always_inline u32 sm_send_cmd(struct caam_drv_private_sm *smpriv,
+ struct caam_drv_private_jr *jrpriv,
+ u32 cmd, u32 *status)
+{
+ void __iomem *write_address;
+ void __iomem *read_address;
+
+ if (smpriv->sm_reg_offset == SM_V1_OFFSET) {
+ struct caam_secure_mem_v1 *sm_regs_v1;
+
+ sm_regs_v1 = (struct caam_secure_mem_v1 *)
+ ((void *)jrpriv->rregs + SM_V1_OFFSET);
+ write_address = &sm_regs_v1->sm_cmd;
+ read_address = &sm_regs_v1->sm_status;
+
+ } else if (smpriv->sm_reg_offset == SM_V2_OFFSET) {
+ struct caam_secure_mem_v2 *sm_regs_v2;
+
+ sm_regs_v2 = (struct caam_secure_mem_v2 *)
+ ((void *)jrpriv->rregs + SM_V2_OFFSET);
+ write_address = &sm_regs_v2->sm_cmd;
+ read_address = &sm_regs_v2->sm_status;
+
+ } else {
+ return -EINVAL;
+ }
+
+ wr_reg32(write_address, cmd);
+
+ udelay(10);
+
+ /* Read until the command has terminated and the status is correct */
+ do {
+ *status = rd_reg32(read_address);
+ } while (((*status & SMCS_CMDERR_MASK) >> SMCS_CMDERR_SHIFT)
+ == SMCS_CMDERR_INCOMP);
+
+ return 0;
+}
+
+/*
+ * Construct a black key conversion job descriptor
+ *
+ * This function constructs a job descriptor capable of performing
+ * a key blackening operation on a plaintext secure memory resident object.
+ *
+ * - desc pointer to a pointer to the descriptor generated by this
+ * function. Caller will be responsible to kfree() this
+ * descriptor after execution.
+ * - key physical pointer to the plaintext, which will also hold
+ * the result. Since encryption occurs in place, caller must
+ * ensure that the space is large enough to accommodate the
+ * blackened key
+ * - keysz size of the plaintext
+ * - auth if a CCM-covered key is required, use KEY_COVER_CCM, else
+ * use KEY_COVER_ECB.
+ *
+ * KEY to key1 from @key_addr LENGTH 16 BYTES;
+ * FIFO STORE from key1[ecb] TO @key_addr LENGTH 16 BYTES;
+ *
+ * Note that this variant uses the JDKEK only; it does not accommodate the
+ * trusted key encryption key at this time.
+ *
+ */
+static int blacken_key_jobdesc(u32 **desc, void *key, u16 keysz, bool auth)
+{
+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
+ u16 dsize, idx;
+
+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
+ idx = 1;
+
+ /* Load key to class 1 key register */
+ tmpdesc[idx++] = CMD_KEY | CLASS_1 | (keysz & KEY_LENGTH_MASK);
+ tmpdesc[idx++] = (uintptr_t)key;
+
+ /* ...and write back out via FIFO store*/
+ tmpdesc[idx] = CMD_FIFO_STORE | CLASS_1 | (keysz & KEY_LENGTH_MASK);
+
+ /* plus account for ECB/CCM option in FIFO_STORE */
+ if (auth == KEY_COVER_ECB)
+ tmpdesc[idx] |= FIFOST_TYPE_KEY_KEK;
+ else
+ tmpdesc[idx] |= FIFOST_TYPE_KEY_CCM_JKEK;
+
+ idx++;
+ tmpdesc[idx++] = (uintptr_t)key;
+
+ /* finish off the job header */
+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
+ dsize = idx * sizeof(u32);
+
+ /* now allocate execution buffer and coat it with executable */
+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
+ if (tdesc == NULL)
+ return 0;
+
+ memcpy(tdesc, tmpdesc, dsize);
+ *desc = tdesc;
+
+ return dsize;
+}
+
+/*
+ * Construct a blob encapsulation job descriptor
+ *
+ * This function dynamically constructs a blob encapsulation job descriptor
+ * from the following arguments:
+ *
+ * - desc pointer to a pointer to the descriptor generated by this
+ * function. Caller will be responsible to kfree() this
+ * descriptor after execution.
+ * - keymod Physical pointer to a key modifier, which must reside in a
+ * contiguous piece of memory. Modifier will be assumed to be
+ * 8 bytes long for a blob of type SM_SECMEM, or 16 bytes long
+ * for a blob of type SM_GENMEM (see blobtype argument).
+ * - secretbuf Physical pointer to a secret, normally a black or red key,
+ * possibly residing within an accessible secure memory page,
+ * of the secret to be encapsulated to an output blob.
+ * - outbuf Physical pointer to the destination buffer to receive the
+ * encapsulated output. This buffer will need to be 48 bytes
+ * larger than the input because of the added encapsulation data.
+ * The generated descriptor will account for the increase in size,
+ * but the caller must also account for this increase in the
+ * buffer allocator.
+ * - secretsz Size of input secret, in bytes. This is limited to 65536
+ * less the size of blob overhead, since the length embeds into
+ * DECO pointer in/out instructions.
+ * - keycolor Determines if the source data is covered (black key) or
+ * plaintext (red key). RED_KEY or BLACK_KEY are defined in
+ * for this purpose.
+ * - blobtype Determine if encapsulated blob should be a secure memory
+ * blob (SM_SECMEM), with partition data embedded with key
+ * material, or a general memory blob (SM_GENMEM).
+ * - auth If BLACK_KEY source is covered via AES-CCM, specify
+ * KEY_COVER_CCM, else uses AES-ECB (KEY_COVER_ECB).
+ *
+ * Upon completion, desc points to a buffer containing a CAAM job
+ * descriptor which encapsulates data into an externally-storable blob
+ * suitable for use across power cycles.
+ *
+ * This is an example of a black key encapsulation job into a general memory
+ * blob. Notice the 16-byte key modifier in the LOAD instruction. Also note
+ * the output 48 bytes longer than the input:
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400010 ld: ccb2-key len=16 offs=0
+ * [02] 08144891 ptr->@0x08144891
+ * [03] F800003A seqoutptr: len=58
+ * [04] 01000000 out_ptr->@0x01000000
+ * [05] F000000A seqinptr: len=10
+ * [06] 09745090 in_ptr->@0x09745090
+ * [07] 870D0004 operation: encap blob reg=memory, black, format=normal
+ *
+ * This is an example of a red key encapsulation job for storing a red key
+ * into a secure memory blob. Note the 8 byte modifier on the 12 byte offset
+ * in the LOAD instruction; this accounts for blob permission storage:
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400C08 ld: ccb2-key len=8 offs=12
+ * [02] 087D0784 ptr->@0x087d0784
+ * [03] F8000050 seqoutptr: len=80
+ * [04] 09251BB2 out_ptr->@0x09251bb2
+ * [05] F0000020 seqinptr: len=32
+ * [06] 40000F31 in_ptr->@0x40000f31
+ * [07] 870D0008 operation: encap blob reg=memory, red, sec_mem,
+ * format=normal
+ *
+ * Note: this function only generates 32-bit pointers at present, and should
+ * be refactored using a scheme that allows both 32 and 64 bit addressing
+ */
+
+static int blob_encap_jobdesc(u32 **desc, dma_addr_t keymod,
+ void *secretbuf, dma_addr_t outbuf,
+ u16 secretsz, u8 keycolor, u8 blobtype, u8 auth)
+{
+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
+ u16 dsize, idx;
+
+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
+ idx = 1;
+
+ /*
+ * Key modifier works differently for secure/general memory blobs
+ * This accounts for the permission/protection data encapsulated
+ * within the blob if a secure memory blob is requested
+ */
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY |
+ ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK)
+ | (8 & LDST_LEN_MASK);
+ else /* is general memory blob */
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY | (16 & LDST_LEN_MASK);
+
+ tmpdesc[idx++] = (u32)keymod;
+
+ /*
+ * Encapsulation output must include space for blob key encryption
+ * key and MAC tag
+ */
+ tmpdesc[idx++] = CMD_SEQ_OUT_PTR | (secretsz + BLOB_OVERHEAD);
+ tmpdesc[idx++] = (u32)outbuf;
+
+ /* Input data, should be somewhere in secure memory */
+ tmpdesc[idx++] = CMD_SEQ_IN_PTR | secretsz;
+ tmpdesc[idx++] = (uintptr_t)secretbuf;
+
+ /* Set blob encap, then color */
+ tmpdesc[idx] = CMD_OPERATION | OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB;
+
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx] |= OP_PCL_BLOB_PTXT_SECMEM;
+
+ if (auth == KEY_COVER_CCM)
+ tmpdesc[idx] |= OP_PCL_BLOB_EKT;
+
+ if (keycolor == BLACK_KEY)
+ tmpdesc[idx] |= OP_PCL_BLOB_BLACK;
+
+ idx++;
+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
+ dsize = idx * sizeof(u32);
+
+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);
+ if (tdesc == NULL)
+ return 0;
+
+ memcpy(tdesc, tmpdesc, dsize);
+ *desc = tdesc;
+ return dsize;
+}
+
+/*
+ * Construct a blob decapsulation job descriptor
+ *
+ * This function dynamically constructs a blob decapsulation job descriptor
+ * from the following arguments:
+ *
+ * - desc pointer to a pointer to the descriptor generated by this
+ * function. Caller will be responsible to kfree() this
+ * descriptor after execution.
+ * - keymod Physical pointer to a key modifier, which must reside in a
+ * contiguous piece of memory. Modifier will be assumed to be
+ * 8 bytes long for a blob of type SM_SECMEM, or 16 bytes long
+ * for a blob of type SM_GENMEM (see blobtype argument).
+ * - blobbuf Physical pointer (into external memory) of the blob to
+ * be decapsulated. Blob must reside in a contiguous memory
+ * segment.
+ * - outbuf Physical pointer of the decapsulated output, possibly into
+ * a location within a secure memory page. Must be contiguous.
+ * - secretsz Size of encapsulated secret in bytes (not the size of the
+ * input blob).
+ * - keycolor Determines if decapsulated content is encrypted (BLACK_KEY)
+ * or left as plaintext (RED_KEY).
+ * - blobtype Determine if encapsulated blob should be a secure memory
+ * blob (SM_SECMEM), with partition data embedded with key
+ * material, or a general memory blob (SM_GENMEM).
+ * - auth If decapsulation path is specified by BLACK_KEY, then if
+ * AES-CCM is requested for key covering use KEY_COVER_CCM, else
+ * use AES-ECB (KEY_COVER_ECB).
+ *
+ * Upon completion, desc points to a buffer containing a CAAM job descriptor
+ * that decapsulates a key blob from external memory into a black (encrypted)
+ * key or red (plaintext) content.
+ *
+ * This is an example of a black key decapsulation job from a general memory
+ * blob. Notice the 16-byte key modifier in the LOAD instruction.
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400010 ld: ccb2-key len=16 offs=0
+ * [02] 08A63B7F ptr->@0x08a63b7f
+ * [03] F8000010 seqoutptr: len=16
+ * [04] 01000000 out_ptr->@0x01000000
+ * [05] F000003A seqinptr: len=58
+ * [06] 01000010 in_ptr->@0x01000010
+ * [07] 860D0004 operation: decap blob reg=memory, black, format=normal
+ *
+ * This is an example of a red key decapsulation job for restoring a red key
+ * from a secure memory blob. Note the 8 byte modifier on the 12 byte offset
+ * in the LOAD instruction:
+ *
+ * [00] B0800008 jobhdr: stidx=0 len=8
+ * [01] 14400C08 ld: ccb2-key len=8 offs=12
+ * [02] 01000000 ptr->@0x01000000
+ * [03] F8000020 seqoutptr: len=32
+ * [04] 400000E6 out_ptr->@0x400000e6
+ * [05] F0000050 seqinptr: len=80
+ * [06] 08F0C0EA in_ptr->@0x08f0c0ea
+ * [07] 860D0008 operation: decap blob reg=memory, red, sec_mem,
+ * format=normal
+ *
+ * Note: this function only generates 32-bit pointers at present, and should
+ * be refactored using a scheme that allows both 32 and 64 bit addressing
+ */
+
+static int blob_decap_jobdesc(u32 **desc, dma_addr_t keymod, dma_addr_t blobbuf,
+ u8 *outbuf, u16 secretsz, u8 keycolor,
+ u8 blobtype, u8 auth)
+{
+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ];
+ u16 dsize, idx;
+
+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));
+ idx = 1;
+
+ /* Load key modifier */
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY |
+ ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK)
+ | (8 & LDST_LEN_MASK);
+ else /* is general memory blob */
+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB |
+ LDST_SRCDST_BYTE_KEY | (16 & LDST_LEN_MASK);
+
+ tmpdesc[idx++] = (u32)keymod;
+
+ /* Compensate BKEK + MAC tag over size of encapsulated secret */
+ tmpdesc[idx++] = CMD_SEQ_IN_PTR | (secretsz + BLOB_OVERHEAD);
+ tmpdesc[idx++] = (u32)blobbuf;
+ tmpdesc[idx++] = CMD_SEQ_OUT_PTR | secretsz;
+ tmpdesc[idx++] = (uintptr_t)outbuf;
+
+ /* Decapsulate from secure memory partition to black blob */
+ tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB;
+
+ if (blobtype == SM_SECMEM)
+ tmpdesc[idx] |= OP_PCL_BLOB_PTXT_SECMEM;
+
+ if (auth == KEY_COVER_CCM)
+ tmpdesc[idx] |= OP_PCL_BLOB_EKT;
+
+ if (keycolor == BLACK_KEY)
+ tmpdesc[idx] |= OP_PCL_BLOB_BLACK;
+
+ idx++;
+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);
+ dsize = idx * sizeof(u32);