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