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-05-14 tyx the first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <hw_gcm.h>
14
15 /**
16 * @brief Creating GCM Context
17 *
18 * @param device Hardware crypto device
19 * @param type Type of symmetric crypto context
20 *
21 * @return GCM context
22 */
rt_hwcrypto_gcm_create(struct rt_hwcrypto_device * device,hwcrypto_type crypt_type)23 struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
24 hwcrypto_type crypt_type)
25 {
26 struct rt_hwcrypto_ctx *ctx;
27
28 ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_GCM, sizeof(struct hwcrypto_gcm));
29 if (ctx)
30 {
31 ((struct hwcrypto_gcm *)ctx)->crypt_type = crypt_type;
32 }
33 return ctx;
34 }
35
36 /**
37 * @brief Destroy GCM Context
38 *
39 * @param ctx GCM context
40 */
rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx * ctx)41 void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx)
42 {
43 rt_hwcrypto_ctx_destroy(ctx);
44 }
45
46 /**
47 * @brief This function starts a GCM encryption or decryption operation
48 *
49 * @param ctx GCM context
50 * @param add The buffer holding the additional data
51 * @param add_len The length of the additional data
52 *
53 * @return RT_EOK on success.
54 */
rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx * ctx,const rt_uint8_t * add,rt_size_t add_len)55 rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
56 rt_size_t add_len)
57 {
58 struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
59
60 if (gcm_ctx && gcm_ctx->ops->start)
61 {
62 return gcm_ctx->ops->start(gcm_ctx, add, add_len);
63 }
64 return -RT_EINVAL;
65 }
66
67 /**
68 * @brief This function finishes the GCM operation and generates the authentication tag
69 *
70 * @param ctx GCM context
71 * @param tag The buffer for holding the tag
72 * @param tag_len The length of the tag to generate
73 *
74 * @return RT_EOK on success.
75 */
rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx * ctx,const rt_uint8_t * tag,rt_size_t tag_len)76 rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag,
77 rt_size_t tag_len)
78 {
79 struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
80
81 if (gcm_ctx && gcm_ctx->ops->finish)
82 {
83 return gcm_ctx->ops->finish(gcm_ctx, tag, tag_len);
84 }
85 return -RT_EINVAL;
86 }
87
88 /**
89 * @brief This function performs a symmetric encryption or decryption operation
90 *
91 * @param ctx GCM context
92 * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
93 * @param length The length of the input data in Bytes. This must be a multiple of the block size
94 * @param in The buffer holding the input data
95 * @param out The buffer holding the output data
96 *
97 * @return RT_EOK on success.
98 */
rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx * ctx,hwcrypto_mode mode,rt_size_t length,const rt_uint8_t * in,rt_uint8_t * out)99 rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
100 rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
101 {
102 return rt_hwcrypto_symmetric_crypt(ctx, mode, length, in, out);
103 }
104
105 /**
106 * @brief Set Symmetric Encryption and Decryption Key
107 *
108 * @param ctx GCM context
109 * @param key The crypto key
110 * @param bitlen The crypto key bit length
111 *
112 * @return RT_EOK on success.
113 */
rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx * ctx,const rt_uint8_t * key,rt_uint32_t bitlen)114 rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
115 const rt_uint8_t *key, rt_uint32_t bitlen)
116 {
117 return rt_hwcrypto_symmetric_setkey(ctx, key, bitlen);
118 }
119
120 /**
121 * @brief Get Symmetric Encryption and Decryption Key
122 *
123 * @param ctx GCM context
124 * @param key The crypto key buffer
125 * @param bitlen The crypto key bit length
126 *
127 * @return Key length of copy
128 */
rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx * ctx,rt_uint8_t * key,rt_uint32_t bitlen)129 rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
130 rt_uint8_t *key, rt_uint32_t bitlen)
131 {
132 return rt_hwcrypto_symmetric_getkey(ctx, key, bitlen);
133 }
134
135 /**
136 * @brief Set Symmetric Encryption and Decryption initialization vector
137 *
138 * @param ctx GCM 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_gcm_setiv(struct rt_hwcrypto_ctx * ctx,const rt_uint8_t * iv,rt_size_t len)144 rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
145 const rt_uint8_t *iv, rt_size_t len)
146 {
147 return rt_hwcrypto_symmetric_setiv(ctx, iv, len);
148 }
149
150 /**
151 * @brief Get Symmetric Encryption and Decryption initialization vector
152 *
153 * @param ctx GCM context
154 * @param iv The crypto initialization vector buffer
155 * @param len The crypto initialization vector buffer length
156 *
157 * @return IV length of copy
158 */
rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx * ctx,rt_uint8_t * iv,rt_size_t len)159 rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
160 rt_uint8_t *iv, rt_size_t len)
161 {
162 return rt_hwcrypto_symmetric_getiv(ctx, iv, len);
163 }
164
165 /**
166 * @brief Set offset in initialization vector
167 *
168 * @param ctx GCM context
169 * @param iv_off The offset in IV
170 */
rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx * ctx,rt_int32_t iv_off)171 void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
172 {
173 rt_hwcrypto_symmetric_set_ivoff(ctx, iv_off);
174 }
175
176 /**
177 * @brief Get offset in initialization vector
178 *
179 * @param ctx GCM context
180 * @param iv_off It must point to a valid memory
181 */
rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx * ctx,rt_int32_t * iv_off)182 void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
183 {
184 rt_hwcrypto_symmetric_get_ivoff(ctx, iv_off);
185 }
186
187 /**
188 * @brief This function copy GCM context
189 *
190 * @param des The destination GCM context
191 * @param src The GCM context to be copy
192 *
193 * @return RT_EOK on success.
194 */
rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx * des,const struct rt_hwcrypto_ctx * src)195 rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
196 const struct rt_hwcrypto_ctx *src)
197 {
198 struct hwcrypto_gcm *gcm_des = (struct hwcrypto_gcm *)des;
199 struct hwcrypto_gcm *gcm_src = (struct hwcrypto_gcm *)src;
200
201 if (des != RT_NULL && src != RT_NULL)
202 {
203 gcm_des->crypt_type = gcm_src->crypt_type;
204 /* symmetric crypto context copy */
205 return rt_hwcrypto_symmetric_cpy(des, src);
206 }
207 return -RT_EINVAL;
208 }
209
210 /**
211 * @brief Reset GCM context
212 *
213 * @param ctx GCM context
214 */
rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx * ctx)215 void rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx *ctx)
216 {
217 rt_hwcrypto_symmetric_reset(ctx);
218 }
219