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