Commit 98a6ffadeade0e42ac70cfc57b810382b961b7d0
Committed by
Ye Li
1 parent
d1515ca9cd
Exists in
smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga
and in
4 other branches
MLK-21420 crypto: fsl: blob: Flush dcache range for destination address
The blob command is not working on i.MX7D, i.MX8MQ and i.MX8MM devices. Due to different cache management it's necessary to flush dcache range for destination address so data can be available in memory. Add necessary operations in blob_encap() and blob_decap() functions. Signed-off-by: Breno Lima <breno.lima@nxp.com> Reviewed-by: Ye Li <ye.li@nxp.com> (cherry picked from commit 639e5c15816c3eea0d4904a72ad175627be043d8)
Showing 1 changed file with 6 additions and 0 deletions Inline Diff
drivers/crypto/fsl/fsl_blob.c
1 | /* | 1 | /* |
2 | * Copyright 2014 Freescale Semiconductor, Inc. | 2 | * Copyright 2014 Freescale Semiconductor, Inc. |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <common.h> | 8 | #include <common.h> |
9 | #include <malloc.h> | 9 | #include <malloc.h> |
10 | #include <memalign.h> | 10 | #include <memalign.h> |
11 | #include <fsl_sec.h> | 11 | #include <fsl_sec.h> |
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include "jobdesc.h" | 13 | #include "jobdesc.h" |
14 | #include "desc.h" | 14 | #include "desc.h" |
15 | #include "jr.h" | 15 | #include "jr.h" |
16 | 16 | ||
17 | /** | 17 | /** |
18 | * blob_decap() - Decapsulate the data from a blob | 18 | * blob_decap() - Decapsulate the data from a blob |
19 | * @key_mod: - Key modifier address | 19 | * @key_mod: - Key modifier address |
20 | * @src: - Source address (blob) | 20 | * @src: - Source address (blob) |
21 | * @dst: - Destination address (data) | 21 | * @dst: - Destination address (data) |
22 | * @len: - Size of decapsulated data | 22 | * @len: - Size of decapsulated data |
23 | * | 23 | * |
24 | * Note: Start and end of the key_mod, src and dst buffers have to be aligned to | 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. | 25 | * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed. |
26 | * | 26 | * |
27 | * Returns zero on success, negative on error. | 27 | * Returns zero on success, negative on error. |
28 | */ | 28 | */ |
29 | int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len) | 29 | int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len) |
30 | { | 30 | { |
31 | int ret, size, i = 0; | 31 | int ret, size, i = 0; |
32 | u32 *desc; | 32 | u32 *desc; |
33 | 33 | ||
34 | if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || | 34 | if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || |
35 | !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || | 35 | !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || |
36 | !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { | 36 | !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { |
37 | puts("Error: blob_decap: Address arguments are not aligned!\n"); | 37 | puts("Error: blob_decap: Address arguments are not aligned!\n"); |
38 | return -EINVAL; | 38 | return -EINVAL; |
39 | } | 39 | } |
40 | 40 | ||
41 | printf("\nDecapsulating blob to get data\n"); | 41 | printf("\nDecapsulating blob to get data\n"); |
42 | desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); | 42 | desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); |
43 | if (!desc) { | 43 | if (!desc) { |
44 | debug("Not enough memory for descriptor allocation\n"); | 44 | debug("Not enough memory for descriptor allocation\n"); |
45 | return -ENOMEM; | 45 | return -ENOMEM; |
46 | } | 46 | } |
47 | 47 | ||
48 | size = ALIGN(16, ARCH_DMA_MINALIGN); | 48 | size = ALIGN(16, ARCH_DMA_MINALIGN); |
49 | flush_dcache_range((unsigned long)key_mod, | 49 | flush_dcache_range((unsigned long)key_mod, |
50 | (unsigned long)key_mod + size); | 50 | (unsigned long)key_mod + size); |
51 | 51 | ||
52 | size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); | 52 | size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); |
53 | flush_dcache_range((unsigned long)src, | 53 | flush_dcache_range((unsigned long)src, |
54 | (unsigned long)src + size); | 54 | (unsigned long)src + size); |
55 | 55 | ||
56 | inline_cnstr_jobdesc_blob_decap(desc, key_mod, src, dst, len); | 56 | inline_cnstr_jobdesc_blob_decap(desc, key_mod, src, dst, len); |
57 | 57 | ||
58 | debug("Descriptor dump:\n"); | 58 | debug("Descriptor dump:\n"); |
59 | for (i = 0; i < 14; i++) | 59 | for (i = 0; i < 14; i++) |
60 | debug("Word[%d]: %08x\n", i, *(desc + i)); | 60 | debug("Word[%d]: %08x\n", i, *(desc + i)); |
61 | 61 | ||
62 | size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); | 62 | size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); |
63 | flush_dcache_range((unsigned long)desc, | 63 | flush_dcache_range((unsigned long)desc, |
64 | (unsigned long)desc + size); | 64 | (unsigned long)desc + size); |
65 | 65 | ||
66 | flush_dcache_range((unsigned long)dst, | ||
67 | (unsigned long)dst + size); | ||
68 | |||
66 | ret = run_descriptor_jr(desc); | 69 | ret = run_descriptor_jr(desc); |
67 | 70 | ||
68 | if (ret) { | 71 | if (ret) { |
69 | printf("Error in blob decapsulation: %d\n", ret); | 72 | printf("Error in blob decapsulation: %d\n", ret); |
70 | } else { | 73 | } else { |
71 | size = ALIGN(len, ARCH_DMA_MINALIGN); | 74 | size = ALIGN(len, ARCH_DMA_MINALIGN); |
72 | invalidate_dcache_range((unsigned long)dst, | 75 | invalidate_dcache_range((unsigned long)dst, |
73 | (unsigned long)dst + size); | 76 | (unsigned long)dst + size); |
74 | 77 | ||
75 | puts("Blob decapsulation successful.\n"); | 78 | puts("Blob decapsulation successful.\n"); |
76 | } | 79 | } |
77 | 80 | ||
78 | free(desc); | 81 | free(desc); |
79 | return ret; | 82 | return ret; |
80 | } | 83 | } |
81 | 84 | ||
82 | /** | 85 | /** |
83 | * blob_encap() - Encapsulate the data as a blob | 86 | * blob_encap() - Encapsulate the data as a blob |
84 | * @key_mod: - Key modifier address | 87 | * @key_mod: - Key modifier address |
85 | * @src: - Source address (data) | 88 | * @src: - Source address (data) |
86 | * @dst: - Destination address (blob) | 89 | * @dst: - Destination address (blob) |
87 | * @len: - Size of data to be encapsulated | 90 | * @len: - Size of data to be encapsulated |
88 | * | 91 | * |
89 | * Note: Start and end of the key_mod, src and dst buffers have to be aligned to | 92 | * 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. | 93 | * the cache line size (ARCH_DMA_MINALIGN) for the CAAM operation to succeed. |
91 | * | 94 | * |
92 | * Returns zero on success, negative on error. | 95 | * Returns zero on success, negative on error. |
93 | */ | 96 | */ |
94 | int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len) | 97 | int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len) |
95 | { | 98 | { |
96 | int ret, size, i = 0; | 99 | int ret, size, i = 0; |
97 | u32 *desc; | 100 | u32 *desc; |
98 | 101 | ||
99 | if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || | 102 | if (!IS_ALIGNED((uintptr_t)key_mod, ARCH_DMA_MINALIGN) || |
100 | !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || | 103 | !IS_ALIGNED((uintptr_t)src, ARCH_DMA_MINALIGN) || |
101 | !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { | 104 | !IS_ALIGNED((uintptr_t)dst, ARCH_DMA_MINALIGN)) { |
102 | puts("Error: blob_encap: Address arguments are not aligned!\n"); | 105 | puts("Error: blob_encap: Address arguments are not aligned!\n"); |
103 | return -EINVAL; | 106 | return -EINVAL; |
104 | } | 107 | } |
105 | 108 | ||
106 | printf("\nEncapsulating data to form blob\n"); | 109 | printf("\nEncapsulating data to form blob\n"); |
107 | desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); | 110 | desc = malloc_cache_aligned(sizeof(int) * MAX_CAAM_DESCSIZE); |
108 | if (!desc) { | 111 | if (!desc) { |
109 | debug("Not enough memory for descriptor allocation\n"); | 112 | debug("Not enough memory for descriptor allocation\n"); |
110 | return -ENOMEM; | 113 | return -ENOMEM; |
111 | } | 114 | } |
112 | 115 | ||
113 | size = ALIGN(16, ARCH_DMA_MINALIGN); | 116 | size = ALIGN(16, ARCH_DMA_MINALIGN); |
114 | flush_dcache_range((unsigned long)key_mod, | 117 | flush_dcache_range((unsigned long)key_mod, |
115 | (unsigned long)key_mod + size); | 118 | (unsigned long)key_mod + size); |
116 | 119 | ||
117 | size = ALIGN(len, ARCH_DMA_MINALIGN); | 120 | size = ALIGN(len, ARCH_DMA_MINALIGN); |
118 | flush_dcache_range((unsigned long)src, | 121 | flush_dcache_range((unsigned long)src, |
119 | (unsigned long)src + size); | 122 | (unsigned long)src + size); |
120 | 123 | ||
121 | inline_cnstr_jobdesc_blob_encap(desc, key_mod, src, dst, len); | 124 | inline_cnstr_jobdesc_blob_encap(desc, key_mod, src, dst, len); |
122 | 125 | ||
123 | debug("Descriptor dump:\n"); | 126 | debug("Descriptor dump:\n"); |
124 | for (i = 0; i < 14; i++) | 127 | for (i = 0; i < 14; i++) |
125 | debug("Word[%d]: %08x\n", i, *(desc + i)); | 128 | debug("Word[%d]: %08x\n", i, *(desc + i)); |
126 | 129 | ||
127 | size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); | 130 | size = ALIGN(sizeof(int) * MAX_CAAM_DESCSIZE, ARCH_DMA_MINALIGN); |
128 | flush_dcache_range((unsigned long)desc, | 131 | flush_dcache_range((unsigned long)desc, |
129 | (unsigned long)desc + size); | 132 | (unsigned long)desc + size); |
133 | |||
134 | flush_dcache_range((unsigned long)dst, | ||
135 | (unsigned long)dst + size); | ||
130 | 136 | ||
131 | ret = run_descriptor_jr(desc); | 137 | ret = run_descriptor_jr(desc); |
132 | 138 | ||
133 | if (ret) { | 139 | if (ret) { |
134 | printf("Error in blob encapsulation: %d\n", ret); | 140 | printf("Error in blob encapsulation: %d\n", ret); |
135 | } else { | 141 | } else { |
136 | size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); | 142 | size = ALIGN(BLOB_SIZE(len), ARCH_DMA_MINALIGN); |
137 | invalidate_dcache_range((unsigned long)dst, | 143 | invalidate_dcache_range((unsigned long)dst, |
138 | (unsigned long)dst + size); | 144 | (unsigned long)dst + size); |
139 | 145 | ||
140 | puts("Blob encapsulation successful.\n"); | 146 | puts("Blob encapsulation successful.\n"); |
141 | } | 147 | } |
142 | 148 | ||
143 | free(desc); | 149 | free(desc); |
144 | return ret; | 150 | return ret; |
145 | } | 151 | } |
146 | 152 | ||
147 | #ifdef CONFIG_CMD_DEKBLOB | 153 | #ifdef CONFIG_CMD_DEKBLOB |
148 | int blob_dek(const u8 *src, u8 *dst, u8 len) | 154 | int blob_dek(const u8 *src, u8 *dst, u8 len) |
149 | { | 155 | { |
150 | int ret, size, i = 0; | 156 | int ret, size, i = 0; |
151 | u32 *desc; | 157 | u32 *desc; |
152 | 158 | ||
153 | int out_sz = WRP_HDR_SIZE + len + KEY_BLOB_SIZE + MAC_SIZE; | 159 | int out_sz = WRP_HDR_SIZE + len + KEY_BLOB_SIZE + MAC_SIZE; |
154 | 160 | ||
155 | puts("\nEncapsulating provided DEK to form blob\n"); | 161 | puts("\nEncapsulating provided DEK to form blob\n"); |
156 | desc = memalign(ARCH_DMA_MINALIGN, | 162 | desc = memalign(ARCH_DMA_MINALIGN, |
157 | sizeof(uint32_t) * DEK_BLOB_DESCSIZE); | 163 | sizeof(uint32_t) * DEK_BLOB_DESCSIZE); |
158 | if (!desc) { | 164 | if (!desc) { |
159 | debug("Not enough memory for descriptor allocation\n"); | 165 | debug("Not enough memory for descriptor allocation\n"); |
160 | return -ENOMEM; | 166 | return -ENOMEM; |
161 | } | 167 | } |
162 | 168 | ||
163 | ret = inline_cnstr_jobdesc_blob_dek(desc, src, dst, len); | 169 | ret = inline_cnstr_jobdesc_blob_dek(desc, src, dst, len); |
164 | if (ret) { | 170 | if (ret) { |
165 | debug("Error in Job Descriptor Construction: %d\n", ret); | 171 | debug("Error in Job Descriptor Construction: %d\n", ret); |
166 | } else { | 172 | } else { |
167 | size = roundup(sizeof(uint32_t) * DEK_BLOB_DESCSIZE, | 173 | size = roundup(sizeof(uint32_t) * DEK_BLOB_DESCSIZE, |
168 | ARCH_DMA_MINALIGN); | 174 | ARCH_DMA_MINALIGN); |
169 | flush_dcache_range((unsigned long)desc, | 175 | flush_dcache_range((unsigned long)desc, |
170 | (unsigned long)desc + size); | 176 | (unsigned long)desc + size); |
171 | size = roundup(sizeof(uint8_t) * out_sz, ARCH_DMA_MINALIGN); | 177 | size = roundup(sizeof(uint8_t) * out_sz, ARCH_DMA_MINALIGN); |
172 | flush_dcache_range((unsigned long)dst, | 178 | flush_dcache_range((unsigned long)dst, |
173 | (unsigned long)dst + size); | 179 | (unsigned long)dst + size); |
174 | 180 | ||
175 | ret = run_descriptor_jr(desc); | 181 | ret = run_descriptor_jr(desc); |
176 | } | 182 | } |
177 | 183 | ||
178 | if (ret) { | 184 | if (ret) { |
179 | debug("Error in Encapsulation %d\n", ret); | 185 | debug("Error in Encapsulation %d\n", ret); |
180 | goto err; | 186 | goto err; |
181 | } | 187 | } |
182 | 188 | ||
183 | size = roundup(out_sz, ARCH_DMA_MINALIGN); | 189 | size = roundup(out_sz, ARCH_DMA_MINALIGN); |
184 | invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size); | 190 | invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size); |
185 | 191 | ||
186 | puts("DEK Blob\n"); | 192 | puts("DEK Blob\n"); |
187 | for (i = 0; i < out_sz; i++) | 193 | for (i = 0; i < out_sz; i++) |
188 | printf("%02X", ((uint8_t *)dst)[i]); | 194 | printf("%02X", ((uint8_t *)dst)[i]); |
189 | printf("\n"); | 195 | printf("\n"); |
190 | 196 | ||
191 | err: | 197 | err: |
192 | free(desc); | 198 | free(desc); |
193 | return ret; | 199 | return ret; |
194 | } | 200 | } |
195 | #endif | 201 | #endif |
196 | 202 |