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