1 /*
2  *  Copyright (C) 2017-2024 Alibaba Group Holding Limited
3  */
4 
5 /*******************************************************
6  * @file    wj_aes.c
7  * @brief   source file for aes csi driver
8  * @version V1.0
9  * @date    2. July 2020
10  * ******************************************************/
11 
12 #include <drv/aes.h>
13 #include <drv/irq.h>
14 
15 #define AES_READ_CACHE_LITTLE(_addr_)   \
16     (((uint32_t) * (_addr_ + 0U) << 0)  | ((uint32_t) * (_addr_ + 1U) << 8) | \
17      ((uint32_t) * (_addr_ + 2U) << 16) | ((uint32_t) * (_addr_ + 3U) << 24))
18 
19 #define AES_WRITE_CACHE_LITTLE(_addr_, _data_) \
20     do {  \
21         *(_addr_+0U) = (uint8_t)*(_data_+0U);  \
22         *(_addr_+1U) = (uint8_t)*(_data_+1U);  \
23         *(_addr_+2U) = (uint8_t)*(_data_+2U);  \
24         *(_addr_+3U) = (uint8_t)*(_data_+3U);  \
25     } while(0)
26 
27 #define AES_IS_16BYTES_ALIGNMENT(_size_)     ((_size_ % 16U) ? -1 : 0)
28 
29 /**
30   \brief       Initialize AES Interface. Initializes the resources needed for the AES interface
31   \param[in]   aes    operate handle
32   \param[in]   idx    device id
33   \return      error code \ref csi_error_t
34 */
csi_aes_init(csi_aes_t * aes,uint32_t idx)35 csi_error_t csi_aes_init(csi_aes_t *aes, uint32_t idx)
36 {
37     CSI_PARAM_CHK(aes, CSI_ERROR);
38 
39     csi_error_t ret = CSI_OK;
40 
41     ///< 获取中断号、基地址等相关信息
42     if (0 == target_get(DEV_WJ_AES_TAG, idx, &aes->dev)) {
43 
44         ///< TODO:对AES的所有寄存器进行清零操作
45 
46     } else {
47         ret = CSI_ERROR;
48     }
49 
50     return ret;
51 }
52 /**
53   \brief       De-initialize AES Interface. stops operation and releases the software resources used by the interface
54   \param[in]   aes    aes handle to operate
55   \return      None
56 */
csi_aes_uninit(csi_aes_t * aes)57 void csi_aes_uninit(csi_aes_t *aes)
58 {
59     CSI_PARAM_CHK_NORETVAL(aes);
60 
61     ///< TODO:对AES的所有寄存器进行清零操作
62 
63 }
64 /**
65   \brief       Set encrypt key
66   \param[in]   aes        aes handle to operate
67   \param[in]   key        Pointer to the key buf
68   \param[in]   key_len    Pointer to \ref csi_aes_key_bits_t
69   \return      error code \ref csi_error_t
70 */
csi_aes_set_encrypt_key(csi_aes_t * aes,void * key,csi_aes_key_bits_t key_len)71 csi_error_t csi_aes_set_encrypt_key(csi_aes_t *aes, void *key, csi_aes_key_bits_t key_len)
72 {
73     CSI_PARAM_CHK(aes, CSI_ERROR);
74     csi_error_t ret = CSI_OK;
75 
76     switch (key_len) {
77         case AES_KEY_LEN_BITS_128:
78             ///< TODO:设置密钥长度为128 bits
79             break;
80 
81         case AES_KEY_LEN_BITS_192:
82             ///< TODO:设置密钥长度为128 bits
83             break;
84 
85         case AES_KEY_LEN_BITS_256:
86             ///< TODO:设置密钥长度为128 bits
87             break;
88 
89         default:
90             ret = CSI_ERROR;
91             break;
92     }
93 
94         ///< TODO:设置密钥
95         ///< TODO:使能AES
96         ///< TODO:停止AES
97 
98     return ret;
99 }
100 /**
101   \brief       Set decrypt key
102   \param[in]   aes        aes handle to operate
103   \param[in]   key        Pointer to the key buf
104   \param[in]   key_len    Pointer to \ref csi_aes_key_bits_t
105   \return      error code \ref csi_error_t
106 */
csi_aes_set_decrypt_key(csi_aes_t * aes,void * key,csi_aes_key_bits_t key_len)107 csi_error_t csi_aes_set_decrypt_key(csi_aes_t *aes, void *key, csi_aes_key_bits_t key_len)
108 {
109     CSI_PARAM_CHK(aes, CSI_ERROR);
110     csi_error_t ret = CSI_OK;
111 
112     switch (key_len) {
113         case AES_KEY_LEN_BITS_128:
114             ///< TODO:设置密钥长度为128 bits
115             break;
116 
117         case AES_KEY_LEN_BITS_192:
118             ///< TODO:设置密钥长度为128 bits
119             break;
120 
121         case AES_KEY_LEN_BITS_256:
122             ///< TODO:设置密钥长度为128 bits
123             break;
124 
125         default:
126             ret = CSI_ERROR;
127             break;
128     }
129 
130        ///< TODO:设置密钥
131        ///< TODO:使能AES
132        ///< TODO:停止AES
133 
134     return ret;
135 }
136 
137 /**
138   \brief       Aes ecb encrypt or decrypt
139   \param[in]   aes     aes handle to operate
140   \param[in]   in      Pointer to the Source data
141   \param[out]  out     Pointer to the Result data
142   \param[in]   size    the Source data size
143   \return      error code \ref csi_error_t
144 */
csi_aes_ecb_encrypt(csi_aes_t * aes,void * in,void * out,uint32_t size)145 csi_error_t csi_aes_ecb_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size)
146 {
147     CSI_PARAM_CHK(aes, CSI_ERROR);
148     csi_error_t ret = CSI_OK;
149 
150     uint32_t i = 0U;
151     uint32_t j = 0U;
152     uint32_t n = 0U;
153     uint32_t temp;
154     ///< 加密数据长度判断
155     if (0 == AES_IS_16BYTES_ALIGNMENT(size)) {
156 
157        ///< TODO:设置ECB模式
158        ///< TODO:设置加密
159 
160         /* set the text before aes calculating */
161         for (i = 0U; i < size; i = i + 16U) {
162             for (j = 0U; j < 4U; j++) {
163                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
164                 temp = AES_READ_CACHE_LITTLE((uint8_t *)in + n);
165                 ///< TODO:写入待加密数据
166             }
167 
168             ///< TODO:开始加密
169 
170             ///< TODO:等待加密完成
171 
172             for (j = 0U; j < 4U; j++) {
173                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
174                 ///< TODO:获取加密数据到 temp
175                 AES_WRITE_CACHE_LITTLE((uint8_t *)out + n, (uint8_t *)&temp);
176             }
177         }
178     } else {
179         ret = CSI_ERROR;
180     }
181 
182     return ret;
183 }
184 /**
185   \brief       Aes ecb decrypt
186   \param[in]   aes     aes handle to operate
187   \param[in]   in      Pointer to the Source data
188   \param[out]  out     Pointer to the Result data
189   \param[in]   size    the Source data size
190   \return      error code \ref csi_error_t
191 */
csi_aes_ecb_decrypt(csi_aes_t * aes,void * in,void * out,uint32_t size)192 csi_error_t csi_aes_ecb_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size)
193 {
194     CSI_PARAM_CHK(aes, CSI_ERROR);
195     csi_error_t ret = CSI_OK;
196 
197     uint32_t i = 0U;
198     uint32_t j = 0U;
199     uint32_t n = 0U;
200     uint32_t temp;
201 
202     if (0 == AES_IS_16BYTES_ALIGNMENT(size)) {
203 
204        ///< TODO:设置ECB模式
205        ///< TODO:设置解密
206 
207 
208         /* set the text before aes calculating */
209         for (i = 0U; i < size; i = i + 16U) {
210             for (j = 0U; j < 4U; j++) {
211                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
212                 temp = AES_READ_CACHE_LITTLE((uint8_t *)in + n);
213                  ///< TODO:写入待解密数据
214             }
215 
216             ///< TODO:开始解密
217 
218 
219             ///< TODO:等待加密完成
220 
221             for (j = 0U; j < 4U; j++) {
222                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
223                 ///< TODO:获取解密数据到 temp
224                 AES_WRITE_CACHE_LITTLE((uint8_t *)out + n, (uint8_t *)&temp);
225             }
226         }
227     } else {
228         ret = CSI_ERROR;
229     }
230 
231     return ret;
232 }
233 /**
234   \brief       Aes cbc encrypt or decrypt
235   \param[in]   aes     aes handle to operate
236   \param[in]   in      Pointer to the Source data
237   \param[out]  out     Pointer to the Result data
238   \param[in]   size    the Source data size
239   \return      error code \ref csi_error_t
240 */
csi_aes_cbc_encrypt(csi_aes_t * aes,void * in,void * out,uint32_t size,void * iv)241 csi_error_t csi_aes_cbc_encrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv)
242 {
243     CSI_PARAM_CHK(aes, CSI_ERROR);
244     csi_error_t ret = CSI_OK;
245 
246     uint32_t i = 0U;
247     uint32_t j = 0U;
248     uint32_t n = 0U;
249     uint32_t temp;
250 
251     if (0 == AES_IS_16BYTES_ALIGNMENT(size)) {
252         ///< TODO:清除IV 值
253 
254        ///< TODO:设置CBC模式
255        ///< TODO:设置加密密
256 
257         /* set iv if the mode is CBC */
258         for (i = 0U; i < 4U; i++) {
259             temp = AES_READ_CACHE_LITTLE((uint8_t *)iv + (i << 2));
260             ///< TODO:设置CBC值
261         }
262 
263         /* set the text before aes calculating */
264         for (i = 0U; i < size; i = i + 16U) {
265             for (j = 0U; j < 4U; j++) {
266                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
267                 temp = AES_READ_CACHE_LITTLE((uint8_t *)in + n);
268                 ///< TODO:写入待加密数据
269             }
270 
271             ///< TODO:开始加密
272 
273             ///< TODO:等待加密
274 
275             for (j = 0U; j < 4U; j++) {
276                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
277                 ///< TODO:获取加密数据到 temp
278                 AES_WRITE_CACHE_LITTLE((uint8_t *)out + n, (uint8_t *)&temp);
279             }
280         }
281 
282         for (i = 0U; i < 4U; i++) {
283             ///< TODO:获取IV 数据到 temp
284             AES_WRITE_CACHE_LITTLE((uint8_t *)iv + (i << 2), (uint8_t *)&temp);
285         }
286     } else {
287         ret = CSI_ERROR;
288     }
289 
290     return ret;
291 }
292 /**
293   \brief       Aes cbc decrypt
294   \param[in]   aes     aes handle to operate
295   \param[in]   in      Pointer to the Source data
296   \param[out]  out     Pointer to the Result data
297   \param[in]   size    the Source data size
298   \param[in]   iv      init vector
299   \return      error code \ref csi_error_t
300 */
csi_aes_cbc_decrypt(csi_aes_t * aes,void * in,void * out,uint32_t size,void * iv)301 csi_error_t csi_aes_cbc_decrypt(csi_aes_t *aes, void *in, void *out, uint32_t size, void *iv)
302 {
303     CSI_PARAM_CHK(aes, CSI_ERROR);
304     csi_error_t ret = CSI_OK;
305 
306     uint32_t i = 0U;
307     uint32_t j = 0U;
308     uint32_t n = 0U;
309     uint32_t temp = 0U;
310 
311     if (0 == AES_IS_16BYTES_ALIGNMENT(size)) {
312         ///< TODO:清除IV 值
313 
314 
315        ///< TODO:设置CBC模式
316        ///< TODO:设置解密
317 
318         ///< TODO:设置IV 值
319 
320         /* set the text before aes calculating */
321         for (i = 0U; i < size; i = i + 16U) {
322             for (j = 0U; j < 4U; j++) {
323                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
324                 temp = AES_READ_CACHE_LITTLE((uint8_t *)in + n);
325                 ///< TODO:写入待解密数据
326             }
327 
328             ///< TODO:开始解密
329 
330             ///< TODO:等待解密
331 
332 
333             for (j = 0U; j < 4U; j++) {
334                 n = (j << 2) + i;            ///< j:each time offset 4bytes, i:each time offset 16bytes
335                 ///< TODO:获取解密数据到 temp
336                 AES_WRITE_CACHE_LITTLE((uint8_t *)out + n, (uint8_t *)&temp);
337             }
338         }
339 
340         for (i = 0U; i < 4U; i++) {
341             ///< TODO:获取IV数据到 temp
342             AES_WRITE_CACHE_LITTLE((uint8_t *)iv + (i << 2), (uint8_t *)&temp);
343         }
344     } else {
345         ret = CSI_ERROR;
346     }
347 
348     return ret;
349 }
350