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