Commit 1d7f31a55b284ea5bf206ea30e07cc96c851c6ec
Committed by
Ye Li
1 parent
b4b1dc8ed7
Exists in
smarc-imx_v2017.03_o8.1.0_1.3.0_8m
and in
1 other branch
crypto/fsl: fix BLOB encapsulation and decapsulation
The blob_encap and blob_decap functions were not flushing the dcache before passing data to CAAM/DMA and not invalidating the dcache when getting data back. Therefore, blob encapsulation and decapsulation failed with errors like the following due to data cache incoherency: "40000006: DECO: desc idx 0: Invalid KEY command" To ensure coherency, we require the key_mod, src and dst buffers to be aligned to the cache line size and flush/invalidate the memory regions. The same requirements apply to the job descriptor. Tested on an i.MX6Q board. Reviewed-by: Sumit Garg <sumit.garg@nxp.com> Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com> [Breno: Backported to v2017.03] Signed-off-by: Breno Lima <breno.lima@nxp.com> Reviewed-by: Ye Li <ye.li@nxp.com> (cherry picked from commit f4e19b92bc40184eee7d33e53cd190dfb692b196)
Showing 2 changed files with 91 additions and 16 deletions Side-by-side Diff
drivers/crypto/fsl/fsl_blob.c
... | ... | @@ -7,63 +7,138 @@ |
7 | 7 | |
8 | 8 | #include <common.h> |
9 | 9 | #include <malloc.h> |
10 | +#include <memalign.h> | |
10 | 11 | #include <fsl_sec.h> |
11 | 12 | #include <linux/errno.h> |
12 | 13 | #include "jobdesc.h" |
13 | 14 | #include "desc.h" |
14 | 15 | #include "jr.h" |
15 | 16 | |
17 | +/** | |
18 | + * blob_decap() - Decapsulate the data from a blob | |
19 | + * @key_mod: - Key modifier address | |
20 | + * @src: - Source address (blob) | |
21 | + * @dst: - Destination address (data) | |
22 | + * @len: - Size of decapsulated data | |
23 | + * | |
24 | + * Note: Start and end of the key_mod, src and dst buffers have to be aligned to | |
25 | + * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed. | |
26 | + * | |
27 | + * Returns zero on success, negative on error. | |
28 | + */ | |
16 | 29 | int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len) |
17 | 30 | { |
18 | - int ret, i = 0; | |
31 | + int ret, size, i = 0; | |
19 | 32 | u32 *desc; |
20 | 33 | |
34 | + if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || | |
35 | + !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || | |
36 | + !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { | |
37 | + puts("Error: blob_decap: Address arguments are not aligned!\n"); | |
38 | + return -EINVAL; | |
39 | + } | |
40 | + | |
21 | 41 | printf("\nDecapsulating blob to get data\n"); |
22 | - desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE); | |
42 | + desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); | |
23 | 43 | if (!desc) { |
24 | 44 | debug("Not enough memory for descriptor allocation\n"); |
25 | - return -1; | |
45 | + return -ENOMEM; | |
26 | 46 | } |
27 | 47 | |
48 | + size = ALIGN(16, ARCH_DMA_MINALIGN); | |
49 | + flush_dcache_range((unsigned long)key_mod, | |
50 | + (unsigned long)key_mod + size); | |
51 | + | |
52 | + size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); | |
53 | + flush_dcache_range((unsigned long)src, | |
54 | + (unsigned long)src + size); | |
55 | + | |
28 | 56 | inline_cnstr_jobdesc_blob_decap(desc, key_mod, src, dst, len); |
29 | 57 | |
30 | 58 | debug("Descriptor dump:\n"); |
31 | 59 | for (i = 0; i < 14; i++) |
32 | 60 | debug("Word[%d]: %08x\n", i, *(desc + i)); |
61 | + | |
62 | + size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); | |
63 | + flush_dcache_range((unsigned long)desc, | |
64 | + (unsigned long)desc + size); | |
65 | + | |
33 | 66 | ret = run_descriptor_jr(desc); |
34 | 67 | |
35 | - if (ret) | |
36 | - printf("Error in Decapsulation %d\n", ret); | |
37 | - else | |
38 | - printf("Decapsulation Success\n"); | |
68 | + if (ret) { | |
69 | + printf("Error in blob decapsulation: %d\n", ret); | |
70 | + } else { | |
71 | + size = ALIGN(len, ARCH_DMA_MINALIGN); | |
72 | + invalidate_dcache_range((unsigned long)dst, | |
73 | + (unsigned long)dst + size); | |
39 | 74 | |
75 | + puts("Blob decapsulation successful.\n"); | |
76 | + } | |
77 | + | |
40 | 78 | free(desc); |
41 | 79 | return ret; |
42 | 80 | } |
43 | 81 | |
82 | +/** | |
83 | + * blob_encap() - Encapsulate the data as a blob | |
84 | + * @key_mod: - Key modifier address | |
85 | + * @src: - Source address (data) | |
86 | + * @dst: - Destination address (blob) | |
87 | + * @len: - Size of data to be encapsulated | |
88 | + * | |
89 | + * Note: Start and end of the key_mod, src and dst buffers have to be aligned to | |
90 | + * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed. | |
91 | + * | |
92 | + * Returns zero on success, negative on error. | |
93 | + */ | |
44 | 94 | int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len) |
45 | 95 | { |
46 | - int ret, i = 0; | |
96 | + int ret, size, i = 0; | |
47 | 97 | u32 *desc; |
48 | 98 | |
99 | + if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || | |
100 | + !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || | |
101 | + !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { | |
102 | + puts("Error: blob_encap: Address arguments are not aligned!\n"); | |
103 | + return -EINVAL; | |
104 | + } | |
105 | + | |
49 | 106 | printf("\nEncapsulating data to form blob\n"); |
50 | - desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE); | |
107 | + desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); | |
51 | 108 | if (!desc) { |
52 | 109 | debug("Not enough memory for descriptor allocation\n"); |
53 | - return -1; | |
110 | + return -ENOMEM; | |
54 | 111 | } |
55 | 112 | |
113 | + size = ALIGN(16, ARCH_DMA_MINALIGN); | |
114 | + flush_dcache_range((unsigned long)key_mod, | |
115 | + (unsigned long)key_mod + size); | |
116 | + | |
117 | + size = ALIGN(len, ARCH_DMA_MINALIGN); | |
118 | + flush_dcache_range((unsigned long)src, | |
119 | + (unsigned long)src + size); | |
120 | + | |
56 | 121 | inline_cnstr_jobdesc_blob_encap(desc, key_mod, src, dst, len); |
57 | 122 | |
58 | 123 | debug("Descriptor dump:\n"); |
59 | 124 | for (i = 0; i < 14; i++) |
60 | 125 | debug("Word[%d]: %08x\n", i, *(desc + i)); |
126 | + | |
127 | + size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); | |
128 | + flush_dcache_range((unsigned long)desc, | |
129 | + (unsigned long)desc + size); | |
130 | + | |
61 | 131 | ret = run_descriptor_jr(desc); |
62 | 132 | |
63 | - if (ret) | |
64 | - printf("Error in Encapsulation %d\n", ret); | |
65 | - else | |
66 | - printf("Encapsulation Success\n"); | |
133 | + if (ret) { | |
134 | + printf("Error in blob encapsulation: %d\n", ret); | |
135 | + } else { | |
136 | + size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); | |
137 | + invalidate_dcache_range((unsigned long)dst, | |
138 | + (unsigned long)dst + size); | |
139 | + | |
140 | + puts("Blob encapsulation successful.\n"); | |
141 | + } | |
67 | 142 | |
68 | 143 | free(desc); |
69 | 144 | return ret; |
include/fsl_sec.h
... | ... | @@ -215,6 +215,8 @@ |
215 | 215 | #define SG_ENTRY_OFFSET_SHIFT 0 |
216 | 216 | }; |
217 | 217 | |
218 | +#define BLOB_SIZE(x) ((x) + 32 + 16) /* Blob buffer size */ | |
219 | + | |
218 | 220 | #if defined(CONFIG_MX6) || defined(CONFIG_MX7) |
219 | 221 | /* Job Ring Base Address */ |
220 | 222 | #define JR_BASE_ADDR(x) (CONFIG_SYS_FSL_SEC_ADDR + 0x1000 * (x + 1)) |
... | ... | @@ -273,8 +275,6 @@ |
273 | 275 | #define KS_G1 (1 << JR_MID) /* CAAM only */ |
274 | 276 | #define PERM 0x0000B008 /* Clear on release, lock SMAP |
275 | 277 | * lock SMAG group 1 Blob */ |
276 | - | |
277 | -#define BLOB_SIZE(x) (x + 32 + 16) /* Blob buffer size */ | |
278 | 278 | |
279 | 279 | /* HAB WRAPPED KEY header */ |
280 | 280 | #define WRP_HDR_SIZE 0x08 |