1 /*
2 * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-07-01 lik first version
9 */
10
11 #include "drv_crypto.h"
12 #include <string.h>
13
14 #ifdef RT_USING_HWCRYPTO
15
16 //#define DRV_DEBUG
17 #define LOG_TAG "drv.crypto"
18 #include <drv_log.h>
19
20 struct swm_hwcrypto_device
21 {
22 struct rt_hwcrypto_device dev;
23 struct rt_mutex mutex;
24 };
25
26 static struct swm_hwcrypto_device hwcrypto_obj;
27
28 #ifdef BSP_USING_CRC
29
30 struct swm_crc_cfg
31 {
32 CRC_TypeDef *CRCx;
33 CRC_InitStructure CRC_initstruct;
34 };
35
36 static struct hwcrypto_crc_cfg swm_crc_cfg;
37
swm_crc_update(struct hwcrypto_crc * ctx,const rt_uint8_t * in,rt_size_t length)38 static rt_uint32_t swm_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
39 {
40 rt_uint32_t result = 0;
41 struct swm_hwcrypto_device *hwcrypto_dev = (struct swm_hwcrypto_device *)ctx->parent.device->user_data;
42
43 struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->parent.contex);
44
45 rt_mutex_take(&hwcrypto_dev->mutex, RT_WAITING_FOREVER);
46
47 if (memcmp(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
48 {
49 crc_cfg->CRCx = CRC;
50
51 crc_cfg->CRC_initstruct.init_crc = ctx->crc_cfg.last_val;
52
53 switch (ctx->crc_cfg.poly)
54 {
55 case 0x07:
56 crc_cfg->CRC_initstruct.Poly = CRC_POLY_107;
57 break;
58 case 0x1021:
59 crc_cfg->CRC_initstruct.Poly = CRC_POLY_11021;
60 break;
61 case 0x8005:
62 crc_cfg->CRC_initstruct.Poly = CRC_POLY_18005;
63 break;
64 case 0x04C11DB7:
65 crc_cfg->CRC_initstruct.Poly = CRC_POLY_104C11DB7;
66 break;
67 default:
68
69 goto _exit;
70 }
71
72 switch (ctx->crc_cfg.width)
73 {
74 case 8:
75 crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_8;
76 break;
77 case 16:
78 crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_16;
79 break;
80 case 32:
81 crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_32;
82 break;
83 default:
84 goto _exit;
85 }
86
87 switch (ctx->crc_cfg.flags)
88 {
89 case 0:
90 crc_cfg->CRC_initstruct.in_not = false;
91 crc_cfg->CRC_initstruct.out_not = false;
92 break;
93 case CRC_FLAG_REFIN:
94 crc_cfg->CRC_initstruct.in_not = true;
95 crc_cfg->CRC_initstruct.out_not = false;
96 break;
97 case CRC_FLAG_REFOUT:
98 crc_cfg->CRC_initstruct.in_not = false;
99 crc_cfg->CRC_initstruct.out_not = true;
100 break;
101 case CRC_FLAG_REFIN | CRC_FLAG_REFOUT:
102 crc_cfg->CRC_initstruct.in_not = true;
103 crc_cfg->CRC_initstruct.out_not = true;
104 break;
105 default:
106 goto _exit;
107 }
108
109 crc_cfg->CRC_initstruct.in_rev = CRC_REV_NOT;
110 crc_cfg->CRC_initstruct.out_rev = CRC_REV_NOT;
111 CRC_Init(crc_cfg->CRCx, &(crc_cfg->CRC_initstruct));
112 memcpy(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
113 }
114
115 for (uint32_t i = 0; i < length; i++)
116 CRC_Write((uint32_t)in[i]);
117 result = CRC_Result();
118
119 ctx->crc_cfg.last_val = result;
120
121 swm_crc_cfg.last_val = ctx->crc_cfg.last_val;
122 result = (result ? result ^ (ctx->crc_cfg.xorout) : result);
123
124 _exit:
125 rt_mutex_release(&hwcrypto_dev->mutex);
126
127 return result;
128 }
129
130 static const struct hwcrypto_crc_ops swm_crc_ops =
131 {
132 .update = swm_crc_update,
133 };
134 #endif /* BSP_USING_CRC */
135
136 #if defined(BSP_USING_RNG)
137
138 struct swm_rng_cfg
139 {
140 SYS_TypeDef *SYSx;
141 };
142
swm_rng_update(struct hwcrypto_rng * ctx)143 static rt_uint32_t swm_rng_update(struct hwcrypto_rng *ctx)
144 {
145 rt_uint32_t gen_randoml = 0, gen_randomh = 0;
146
147 struct swm_rng_cfg *rng_cfg = (struct swm_rng_cfg *)(ctx->parent.contex);
148
149 while ((rng_cfg->SYSx->PRNGCR & SYS_PRNGCR_RDY_Msk) == 0)
150 __NOP();
151 gen_randoml = rng_cfg->SYSx->PRNGDL;
152 gen_randomh = rng_cfg->SYSx->PRNGDH;
153 return gen_randoml;
154 }
155
156 static const struct hwcrypto_rng_ops swm_rng_ops =
157 {
158 .update = swm_rng_update,
159 };
160 #endif /* BSP_USING_RNG */
161
swm_crypto_create(struct rt_hwcrypto_ctx * ctx)162 static rt_err_t swm_crypto_create(struct rt_hwcrypto_ctx *ctx)
163 {
164 rt_err_t res = RT_EOK;
165
166 switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
167 {
168 #if defined(BSP_USING_CRC)
169 case HWCRYPTO_TYPE_CRC:
170 {
171 struct swm_crc_cfg *crc_cfg = rt_calloc(1, sizeof(struct swm_crc_cfg));
172 if (RT_NULL == crc_cfg)
173 {
174 res = -RT_ERROR;
175 break;
176 }
177
178 ctx->contex = crc_cfg;
179 ((struct hwcrypto_crc *)ctx)->ops = &swm_crc_ops;
180 break;
181 }
182 #endif /* BSP_USING_CRC */
183
184 #if defined(BSP_USING_RNG)
185 case HWCRYPTO_TYPE_RNG:
186 {
187 struct swm_rng_cfg *rng_cfg = rt_calloc(1, sizeof(struct swm_rng_cfg));
188 if (RT_NULL == rng_cfg)
189 {
190 res = -RT_ERROR;
191 break;
192 }
193 rng_cfg->SYSx = SYS;
194 rng_cfg->SYSx->HRCCR |= (1 << SYS_HRCCR_ON_Pos);
195 rng_cfg->SYSx->LRCCR |= (1 << SYS_LRCCR_ON_Pos);
196 rng_cfg->SYSx->PRNGCR = (0 << SYS_PRNGCR_CLR_Pos) |
197 (3 << SYS_PRNGCR_MODE_Pos);
198 ctx->contex = rng_cfg;
199 ((struct hwcrypto_rng *)ctx)->ops = &swm_rng_ops;
200
201 break;
202 }
203 #endif /* BSP_USING_RNG */
204
205 default:
206 res = -RT_ERROR;
207 break;
208 }
209 return res;
210 }
211
swm_crypto_destroy(struct rt_hwcrypto_ctx * ctx)212 static void swm_crypto_destroy(struct rt_hwcrypto_ctx *ctx)
213 {
214 struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
215 switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
216 {
217 #if defined(BSP_USING_CRC)
218 case HWCRYPTO_TYPE_CRC:
219 crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
220 break;
221 #endif /* BSP_USING_CRC */
222
223 #if defined(BSP_USING_RNG)
224 case HWCRYPTO_TYPE_RNG:
225 break;
226 #endif /* BSP_USING_RNG */
227
228 default:
229 break;
230 }
231
232 rt_free(ctx->contex);
233 }
234
swm_crypto_clone(struct rt_hwcrypto_ctx * des,const struct rt_hwcrypto_ctx * src)235 static rt_err_t swm_crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
236 {
237 rt_err_t res = RT_EOK;
238
239 switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
240 {
241 #if defined(BSP_USING_CRC)
242 case HWCRYPTO_TYPE_CRC:
243 if (des->contex && src->contex)
244 {
245 rt_memcpy(des->contex, src->contex, sizeof(struct swm_crc_cfg));
246 }
247 break;
248 #endif /* BSP_USING_CRC */
249
250 #if defined(BSP_USING_RNG)
251 case HWCRYPTO_TYPE_RNG:
252 if (des->contex && src->contex)
253 {
254 rt_memcpy(des->contex, src->contex, sizeof(struct swm_rng_cfg));
255 }
256 break;
257 #endif /* BSP_USING_RNG */
258
259 default:
260 res = -RT_ERROR;
261 break;
262 }
263 return res;
264 }
265
swm_crypto_reset(struct rt_hwcrypto_ctx * ctx)266 static void swm_crypto_reset(struct rt_hwcrypto_ctx *ctx)
267 {
268 struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
269 switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
270 {
271 #if defined(BSP_USING_CRC)
272 case HWCRYPTO_TYPE_CRC:
273 crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
274 break;
275 #endif /* BSP_USING_CRC */
276
277 #if defined(BSP_USING_RNG)
278 case HWCRYPTO_TYPE_RNG:
279 break;
280 #endif /* BSP_USING_RNG */
281
282 default:
283 break;
284 }
285 }
286
287 static const struct rt_hwcrypto_ops swm_hwcrypto_ops =
288 {
289 .create = swm_crypto_create,
290 .destroy = swm_crypto_destroy,
291 .copy = swm_crypto_clone,
292 .reset = swm_crypto_reset,
293 };
294
swm_crypto_init(void)295 int swm_crypto_init(void)
296 {
297 rt_uint32_t cpuid[2] = {0};
298
299 hwcrypto_obj.dev.ops = &swm_hwcrypto_ops;
300
301 cpuid[0] = SCB->CPUID;
302 hwcrypto_obj.dev.id = 0;
303 rt_memcpy(&hwcrypto_obj.dev.id, cpuid, 8);
304
305 hwcrypto_obj.dev.user_data = &hwcrypto_obj;
306
307 if (rt_hwcrypto_register(&hwcrypto_obj.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
308 {
309 return -1;
310 }
311 rt_mutex_init(&hwcrypto_obj.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_FIFO);
312 return 0;
313 }
314 INIT_BOARD_EXPORT(swm_crypto_init);
315
316 #endif /* RT_USING_HWCRYPTO */
317