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 * 2020-07-10 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 #define DEFAULT_CRC (CRC)
31 #define DEFAULT_INIVAL (0x00000000)
32 #define DEFAULT_INBITS (2)
33 #define DEFAULT_CRC1632 (0)
34 #define DEFAULT_OUT_NOT (0)
35 #define DEFAULT_OUT_REV (0)
36
37
38 struct swm_crc_cfg
39 {
40 CRC_TypeDef *CRCx;
41 uint32_t inival;
42 uint8_t crc_inbits;
43 uint8_t crc_1632;
44 uint8_t crc_out_not;
45 uint8_t crc_out_rev;
46 };
47
48 static struct hwcrypto_crc_cfg swm_crc_cfg;
49
swm_crc_update(struct hwcrypto_crc * ctx,const rt_uint8_t * in,rt_size_t length)50 static rt_uint32_t swm_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
51 {
52 rt_uint32_t result = 0;
53 struct swm_hwcrypto_device *hwcrypto_dev = (struct swm_hwcrypto_device *)ctx->parent.device->user_data;
54
55 struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->parent.contex);
56
57 rt_mutex_take(&hwcrypto_dev->mutex, RT_WAITING_FOREVER);
58
59 if (memcmp(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
60 {
61 crc_cfg->CRCx = CRC;
62
63 crc_cfg->inival = ctx->crc_cfg.last_val;
64
65 switch (ctx->crc_cfg.poly)
66 {
67 case 0x1021:
68 crc_cfg->crc_1632 = 1;
69 break;
70 case 0x04C11DB7:
71 crc_cfg->crc_1632 = 0;
72 break;
73 default:
74 goto _exit;
75 }
76
77 switch (ctx->crc_cfg.width)
78 {
79 case 8:
80 crc_cfg->crc_inbits = 2;
81 break;
82 case 16:
83 crc_cfg->crc_inbits = 1;
84 break;
85 case 32:
86 crc_cfg->crc_inbits = 0;
87 break;
88 default:
89 goto _exit;
90 }
91
92 crc_cfg->crc_out_not = 0;
93
94 switch (ctx->crc_cfg.flags)
95 {
96 case 0:
97 case CRC_FLAG_REFIN:
98 crc_cfg->crc_out_rev = 0;
99 break;
100 case CRC_FLAG_REFOUT:
101 case CRC_FLAG_REFIN | CRC_FLAG_REFOUT:
102 crc_cfg->crc_out_rev = 1;
103 break;
104 default:
105 goto _exit;
106 }
107
108 CRC_Init(crc_cfg->CRCx, (crc_cfg->crc_inbits << 1) | crc_cfg->crc_1632, crc_cfg->crc_out_not, crc_cfg->crc_out_rev, crc_cfg->inival);
109 memcpy(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
110 }
111
112 for (uint32_t i = 0; i < length; i++)
113 CRC_Write((uint32_t)in[i]);
114 result = CRC_Result();
115
116 ctx->crc_cfg.last_val = result;
117
118 swm_crc_cfg.last_val = ctx->crc_cfg.last_val;
119 result = (result ? result ^ (ctx->crc_cfg.xorout) : result);
120
121 _exit:
122 rt_mutex_release(&hwcrypto_dev->mutex);
123
124 return result;
125 }
126
127 static const struct hwcrypto_crc_ops swm_crc_ops =
128 {
129 .update = swm_crc_update,
130 };
131 #endif /* BSP_USING_CRC */
132
swm_crypto_create(struct rt_hwcrypto_ctx * ctx)133 static rt_err_t swm_crypto_create(struct rt_hwcrypto_ctx *ctx)
134 {
135 rt_err_t res = RT_EOK;
136
137 switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
138 {
139 #if defined(BSP_USING_CRC)
140 case HWCRYPTO_TYPE_CRC:
141 {
142 struct swm_crc_cfg *crc_cfg = rt_calloc(1, sizeof(struct swm_crc_cfg));
143 if (RT_NULL == crc_cfg)
144 {
145 res = -RT_ERROR;
146 break;
147 }
148 crc_cfg->CRCx = DEFAULT_CRC;
149 crc_cfg->inival = DEFAULT_INIVAL;
150 crc_cfg->crc_inbits = DEFAULT_INBITS;
151 crc_cfg->crc_1632 = DEFAULT_CRC1632;
152 crc_cfg->crc_out_not = DEFAULT_OUT_NOT;
153 crc_cfg->crc_out_rev = DEFAULT_OUT_REV;
154
155 ctx->contex = crc_cfg;
156 ((struct hwcrypto_crc *)ctx)->ops = &swm_crc_ops;
157 break;
158 }
159 #endif /* BSP_USING_CRC */
160 default:
161 res = -RT_ERROR;
162 break;
163 }
164 return res;
165 }
166
swm_crypto_destroy(struct rt_hwcrypto_ctx * ctx)167 static void swm_crypto_destroy(struct rt_hwcrypto_ctx *ctx)
168 {
169 struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
170 switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
171 {
172 #if defined(BSP_USING_CRC)
173 case HWCRYPTO_TYPE_CRC:
174 crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
175 break;
176 #endif /* BSP_USING_CRC */
177 default:
178 break;
179 }
180
181 rt_free(ctx->contex);
182 }
183
swm_crypto_clone(struct rt_hwcrypto_ctx * des,const struct rt_hwcrypto_ctx * src)184 static rt_err_t swm_crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
185 {
186 rt_err_t res = RT_EOK;
187
188 switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
189 {
190 #if defined(BSP_USING_CRC)
191 case HWCRYPTO_TYPE_CRC:
192 if (des->contex && src->contex)
193 {
194 rt_memcpy(des->contex, src->contex, sizeof(struct swm_crc_cfg));
195 }
196 break;
197 #endif /* BSP_USING_CRC */
198 default:
199 res = -RT_ERROR;
200 break;
201 }
202 return res;
203 }
204
swm_crypto_reset(struct rt_hwcrypto_ctx * ctx)205 static void swm_crypto_reset(struct rt_hwcrypto_ctx *ctx)
206 {
207 struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
208 switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
209 {
210 #if defined(BSP_USING_CRC)
211 case HWCRYPTO_TYPE_CRC:
212 crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
213 break;
214 #endif /* BSP_USING_CRC */
215 default:
216 break;
217 }
218 }
219
220 static const struct rt_hwcrypto_ops swm_hwcrypto_ops =
221 {
222 .create = swm_crypto_create,
223 .destroy = swm_crypto_destroy,
224 .copy = swm_crypto_clone,
225 .reset = swm_crypto_reset,
226 };
227
swm_crypto_init(void)228 int swm_crypto_init(void)
229 {
230 rt_uint32_t cpuid[2] = {0};
231
232 hwcrypto_obj.dev.ops = &swm_hwcrypto_ops;
233
234 cpuid[0] = SCB->CPUID;
235 hwcrypto_obj.dev.id = 0;
236 rt_memcpy(&hwcrypto_obj.dev.id, cpuid, 8);
237
238 hwcrypto_obj.dev.user_data = &hwcrypto_obj;
239
240 if (rt_hwcrypto_register(&hwcrypto_obj.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
241 {
242 return -1;
243 }
244 rt_mutex_init(&hwcrypto_obj.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_PRIO);
245 return 0;
246 }
247 INIT_BOARD_EXPORT(swm_crypto_init);
248
249
250 #endif /* RT_USING_HWCRYPTO */
251