1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2019-04-23 tyx the first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <hwcrypto.h>
14
15 /**
16 * @brief Setting context type (Direct calls are not recommended)
17 *
18 * @param ctx Crypto context
19 * @param type Types of settings
20 *
21 * @return RT_EOK on success.
22 */
rt_hwcrypto_set_type(struct rt_hwcrypto_ctx * ctx,hwcrypto_type type)23 rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
24 {
25 if (ctx)
26 {
27 /* Is it the same category? */
28 if ((ctx->type & HWCRYPTO_MAIN_TYPE_MASK) == (type & HWCRYPTO_MAIN_TYPE_MASK))
29 {
30 ctx->type = type;
31 return RT_EOK;
32 }
33 /* Context is empty type */
34 else if (ctx->type == HWCRYPTO_TYPE_NULL)
35 {
36 ctx->type = type;
37 return RT_EOK;
38 }
39 else
40 {
41 return -RT_ERROR;
42 }
43 }
44 return -RT_EINVAL;
45 }
46
47 /**
48 * @brief Reset context type (Direct calls are not recommended)
49 *
50 * @param ctx Crypto context
51 *
52 */
rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx * ctx)53 void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx)
54 {
55 if (ctx && ctx->device->ops->reset)
56 {
57 ctx->device->ops->reset(ctx);
58 }
59 }
60
61 /**
62 * @brief Init crypto context
63 *
64 * @param ctx The context to initialize
65 * @param device Hardware crypto device
66 * @param type Type of context
67 * @param obj_size Size of context object
68 *
69 * @return RT_EOK on success.
70 */
rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx * ctx,struct rt_hwcrypto_device * device,hwcrypto_type type)71 rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx, struct rt_hwcrypto_device *device, hwcrypto_type type)
72 {
73 rt_err_t err;
74
75 /* Setting context type */
76 rt_hwcrypto_set_type(ctx, type);
77 ctx->device = device;
78 /* Create hardware context */
79 err = ctx->device->ops->create(ctx);
80 if (err != RT_EOK)
81 {
82 return err;
83 }
84 return RT_EOK;
85 }
86
87 /**
88 * @brief Create crypto context
89 *
90 * @param device Hardware crypto device
91 * @param type Type of context
92 * @param obj_size Size of context object
93 *
94 * @return Crypto context
95 */
rt_hwcrypto_ctx_create(struct rt_hwcrypto_device * device,hwcrypto_type type,rt_uint32_t obj_size)96 struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device, hwcrypto_type type, rt_uint32_t obj_size)
97 {
98 struct rt_hwcrypto_ctx *ctx;
99 rt_err_t err;
100
101 /* Parameter checking */
102 if (device == RT_NULL || obj_size < sizeof(struct rt_hwcrypto_ctx))
103 {
104 return RT_NULL;
105 }
106 ctx = rt_malloc(obj_size);
107 if (ctx == RT_NULL)
108 {
109 return ctx;
110 }
111 rt_memset(ctx, 0, obj_size);
112 /* Init context */
113 err = rt_hwcrypto_ctx_init(ctx, device, type);
114 if (err != RT_EOK)
115 {
116 rt_free(ctx);
117 ctx = RT_NULL;
118 }
119 return ctx;
120 }
121
122 /**
123 * @brief Destroy crypto context
124 *
125 * @param device Crypto context
126 */
rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx * ctx)127 void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx)
128 {
129 if (ctx == RT_NULL)
130 {
131 return;
132 }
133 /* Destroy hardware context */
134 if (ctx->device->ops->destroy)
135 {
136 ctx->device->ops->destroy(ctx);
137 }
138 /* Free the resources */
139 rt_free(ctx);
140 }
141
142 /**
143 * @brief Copy crypto context
144 *
145 * @param des The destination context
146 * @param src The context to be copy
147 *
148 * @return RT_EOK on success.
149 */
rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx * des,const struct rt_hwcrypto_ctx * src)150 rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
151 {
152 if (des == RT_NULL || src == RT_NULL)
153 {
154 return -RT_EINVAL;
155 }
156
157 /* The equipment is different or of different types and cannot be copied */
158 if (des->device != src->device ||
159 (des->type & HWCRYPTO_MAIN_TYPE_MASK) != (src->type & HWCRYPTO_MAIN_TYPE_MASK))
160 {
161 return -RT_EINVAL;
162 }
163 des->type = src->type;
164 /* Calling Hardware Context Copy Function */
165 return src->device->ops->copy(des, src);
166 }
167
168 /**
169 * @brief Get the default hardware crypto device
170 *
171 * @return Hardware crypto device
172 *
173 */
rt_hwcrypto_dev_default(void)174 struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void)
175 {
176 static struct rt_hwcrypto_device *hwcrypto_dev;
177
178 /* If there is a default device, return the device */
179 if (hwcrypto_dev)
180 {
181 return hwcrypto_dev;
182 }
183 /* Find by default device name */
184 hwcrypto_dev = (struct rt_hwcrypto_device *)rt_device_find(RT_HWCRYPTO_DEFAULT_NAME);
185 return hwcrypto_dev;
186 }
187
188 /**
189 * @brief Get the unique ID of the device
190 *
191 * @param device Device object
192 *
193 * @return Device unique ID
194 */
rt_hwcrypto_id(struct rt_hwcrypto_device * device)195 rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device)
196 {
197 if (device)
198 {
199 return device->id;
200 }
201 return 0;
202 }
203
204 #ifdef RT_USING_DEVICE_OPS
205 const static struct rt_device_ops hwcrypto_ops =
206 {
207 RT_NULL,
208 RT_NULL,
209 RT_NULL,
210 RT_NULL,
211 RT_NULL,
212 RT_NULL
213 };
214 #endif
215
216 /**
217 * @brief Register hardware crypto device
218 *
219 * @param device Hardware crypto device
220 * @param name Name of device
221 *
222 * @return RT_EOK on success.
223 */
rt_hwcrypto_register(struct rt_hwcrypto_device * device,const char * name)224 rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name)
225 {
226 rt_err_t err;
227
228 RT_ASSERT(device != RT_NULL);
229 RT_ASSERT(name != RT_NULL);
230 RT_ASSERT(device->ops != RT_NULL);
231 RT_ASSERT(device->ops->create != RT_NULL);
232 RT_ASSERT(device->ops->destroy != RT_NULL);
233 RT_ASSERT(device->ops->copy != RT_NULL);
234 RT_ASSERT(device->ops->reset != RT_NULL);
235
236 rt_memset(&device->parent, 0, sizeof(struct rt_device));
237 #ifdef RT_USING_DEVICE_OPS
238 device->parent.ops = &hwcrypto_ops;
239 #else
240 device->parent.init = RT_NULL;
241 device->parent.open = RT_NULL;
242 device->parent.close = RT_NULL;
243 device->parent.read = RT_NULL;
244 device->parent.write = RT_NULL;
245 device->parent.control = RT_NULL;
246 #endif
247
248 device->parent.user_data = RT_NULL;
249 device->parent.type = RT_Device_Class_Security;
250
251 /* Register device */
252 err = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
253
254 return err;
255 }
256