Commit 98a6ffadeade0e42ac70cfc57b810382b961b7d0

Authored by Breno Lima
Committed by Ye Li
1 parent d1515ca9cd

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