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-25 tyx the first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <hw_symmetric.h>
14
15 /**
16 * @brief Creating Symmetric Encryption and Decryption Context
17 *
18 * @param device Hardware crypto device
19 * @param type Type of symmetric crypto context
20 *
21 * @return Symmetric crypto context
22 */
rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device * device,hwcrypto_type type)23 struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
24 {
25 struct rt_hwcrypto_ctx *ctx;
26
27 ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_symmetric));
28 return ctx;
29 }
30
31 /**
32 * @brief Destroy Symmetric Encryption and Decryption Context
33 *
34 * @param ctx Symmetric crypto context
35 */
rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx * ctx)36 void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx)
37 {
38 rt_hwcrypto_ctx_destroy(ctx);
39 }
40
41 /**
42 * @brief This function performs a symmetric encryption or decryption operation
43 *
44 * @param ctx Symmetric crypto context
45 * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
46 * @param length The length of the input data in Bytes. This must be a multiple of the block size
47 * @param in The buffer holding the input data
48 * @param out The buffer holding the output data
49 *
50 * @return RT_EOK on success.
51 */
rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx * ctx,hwcrypto_mode mode,rt_size_t length,const rt_uint8_t * in,rt_uint8_t * out)52 rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode, rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
53 {
54 struct hwcrypto_symmetric *symmetric_ctx;
55 struct hwcrypto_symmetric_info symmetric_info;
56 rt_err_t err;
57
58 if (ctx == RT_NULL)
59 {
60 return -RT_EINVAL;
61 }
62 symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
63 if (symmetric_ctx->ops->crypt == RT_NULL)
64 {
65 return -RT_ERROR;
66 }
67 if (mode != HWCRYPTO_MODE_ENCRYPT && mode != HWCRYPTO_MODE_DECRYPT)
68 {
69 return -RT_EINVAL;
70 }
71
72 /* Input information packaging */
73 symmetric_info.mode = mode;
74 symmetric_info.in = in;
75 symmetric_info.out = out;
76 symmetric_info.length = length;
77
78 /* Calling Hardware Encryption and Decryption Function */
79 err = symmetric_ctx->ops->crypt(symmetric_ctx, &symmetric_info);
80
81 /* clean up flags */
82 symmetric_ctx->flags &= ~(SYMMTRIC_MODIFY_KEY | SYMMTRIC_MODIFY_IV | SYMMTRIC_MODIFY_IVOFF);
83 return err;
84 }
85
86 /**
87 * @brief Set Symmetric Encryption and Decryption Key
88 *
89 * @param ctx Symmetric crypto context
90 * @param key The crypto key
91 * @param bitlen The crypto key bit length
92 *
93 * @return RT_EOK on success.
94 */
rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx * ctx,const rt_uint8_t * key,rt_uint32_t bitlen)95 rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen)
96 {
97 struct hwcrypto_symmetric *symmetric_ctx;
98
99 if (ctx && bitlen <= RT_HWCRYPTO_KEYBIT_MAX_SIZE)
100 {
101 symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
102 rt_memcpy(symmetric_ctx->key, key, bitlen >> 3);
103 /* Record key length */
104 symmetric_ctx->key_bitlen = bitlen;
105 /* Key change flag set up */
106 symmetric_ctx->flags |= SYMMTRIC_MODIFY_KEY;
107 return RT_EOK;
108 }
109
110 return -RT_EINVAL;
111 }
112
113 /**
114 * @brief Get Symmetric Encryption and Decryption Key
115 *
116 * @param ctx Symmetric crypto context
117 * @param key The crypto key buffer
118 * @param bitlen The crypto key bit length
119 *
120 * @return Key length of copy
121 */
rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx * ctx,rt_uint8_t * key,rt_uint32_t bitlen)122 int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen)
123 {
124 struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
125
126 if (ctx && bitlen >= symmetric_ctx->key_bitlen)
127 {
128 rt_memcpy(key, symmetric_ctx->key, symmetric_ctx->key_bitlen >> 3);
129 return symmetric_ctx->key_bitlen;
130 }
131
132 return 0;
133 }
134
135 /**
136 * @brief Set Symmetric Encryption and Decryption initialization vector
137 *
138 * @param ctx Symmetric crypto context
139 * @param iv The crypto initialization vector
140 * @param len The crypto initialization vector length
141 *
142 * @return RT_EOK on success.
143 */
rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx * ctx,const rt_uint8_t * iv,rt_size_t len)144 rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len)
145 {
146 struct hwcrypto_symmetric *symmetric_ctx;
147
148 if (ctx && len <= RT_HWCRYPTO_IV_MAX_SIZE)
149 {
150 symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
151 rt_memcpy(symmetric_ctx->iv, iv, len);
152 symmetric_ctx->iv_len = len;
153 /* IV change flag set up */
154 symmetric_ctx->flags |= SYMMTRIC_MODIFY_IV;
155 return RT_EOK;
156 }
157
158 return -RT_EINVAL;
159 }
160
161 /**
162 * @brief Get Symmetric Encryption and Decryption initialization vector
163 *
164 * @param ctx Symmetric crypto context
165 * @param iv The crypto initialization vector buffer
166 * @param len The crypto initialization vector buffer length
167 *
168 * @return IV length of copy
169 */
rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx * ctx,rt_uint8_t * iv,rt_size_t len)170 int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len)
171 {
172 struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;;
173
174 if (ctx && len >= symmetric_ctx->iv_len)
175 {
176 rt_memcpy(iv, symmetric_ctx->iv, symmetric_ctx->iv_len);
177 return symmetric_ctx->iv_len;
178 }
179
180 return 0;
181 }
182
183 /**
184 * @brief Set offset in initialization vector
185 *
186 * @param ctx Symmetric crypto context
187 * @param iv_off The offset in IV
188 */
rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx * ctx,rt_int32_t iv_off)189 void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
190 {
191 if (ctx)
192 {
193 ((struct hwcrypto_symmetric *)ctx)->iv_off = iv_off;
194 /* iv_off change flag set up */
195 ((struct hwcrypto_symmetric *)ctx)->flags |= SYMMTRIC_MODIFY_IVOFF;
196 }
197 }
198
199 /**
200 * @brief Get offset in initialization vector
201 *
202 * @param ctx Symmetric crypto context
203 * @param iv_off It must point to a valid memory
204 */
rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx * ctx,rt_int32_t * iv_off)205 void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
206 {
207 if (ctx && iv_off)
208 {
209 *iv_off = ((struct hwcrypto_symmetric *)ctx)->iv_off;
210 }
211 }
212
213 /**
214 * @brief This function copy symmetric crypto context
215 *
216 * @param des The destination symmetric crypto context
217 * @param src The symmetric crypto context to be copy
218 *
219 * @return RT_EOK on success.
220 */
rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx * des,const struct rt_hwcrypto_ctx * src)221 rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
222 {
223 struct hwcrypto_symmetric *symmetric_des = (struct hwcrypto_symmetric *)des;
224 struct hwcrypto_symmetric *symmetric_src = (struct hwcrypto_symmetric *)src;
225
226 if (des != RT_NULL && src != RT_NULL)
227 {
228 /* Copy Symmetric Encryption and Decryption Context Information */
229 symmetric_des->flags = symmetric_src->flags ;
230 symmetric_des->iv_len = symmetric_src->iv_len ;
231 symmetric_des->iv_off = symmetric_src->iv_off ;
232 symmetric_des->key_bitlen = symmetric_src->key_bitlen;
233 rt_memcpy(symmetric_des->iv, symmetric_src->iv, symmetric_src->iv_len);
234 rt_memcpy(symmetric_des->key, symmetric_src->key, symmetric_src->key_bitlen >> 3);
235
236 /* Hardware context copy */
237 return rt_hwcrypto_ctx_cpy(des, src);
238 }
239 return -RT_EINVAL;
240 }
241
242 /**
243 * @brief Reset symmetric crypto context
244 *
245 * @param ctx Symmetric crypto context
246 */
rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx * ctx)247 void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx)
248 {
249 struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
250 if (ctx != RT_NULL)
251 {
252 /* Copy Symmetric Encryption and Decryption Context Information */
253 symmetric_ctx->flags = 0x00;
254 symmetric_ctx->iv_len = 0x00;
255 symmetric_ctx->iv_off = 0x00;
256 symmetric_ctx->key_bitlen = 0x00;
257 rt_memset(symmetric_ctx->iv, 0, RT_HWCRYPTO_IV_MAX_SIZE);
258 rt_memset(symmetric_ctx->key, 0, RT_HWCRYPTO_KEYBIT_MAX_SIZE >> 3);
259
260 /* Hardware context reset */
261 rt_hwcrypto_ctx_reset(ctx);
262 }
263 }
264
265 /**
266 * @brief Setting symmetric crypto context type
267 *
268 * @param ctx Symmetric crypto context
269 * @param type Types of settings
270 *
271 * @return RT_EOK on success.
272 */
rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx * ctx,hwcrypto_type type)273 rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
274 {
275 return rt_hwcrypto_set_type(ctx, type);
276 }
277