1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #include <stdlib.h>
22 #include <string.h>
23 #include "mxc_sys.h"
24 #include "mxc_device.h"
25 #include "mxc_errors.h"
26 #include "mxc_assert.h"
27 #include "mxc_lock.h"
28 #include "dma.h"
29 #include "aes_regs.h"
30 #include "aes_revb.h"
31 #include "trng_revb.h"
32 
33 /* **** Variable Declaration **** */
34 typedef struct {
35     uint8_t enc;
36     uint8_t channelRX;
37     uint8_t channelTX;
38     uint32_t remain;
39     uint32_t *inputText;
40     uint32_t *outputText;
41 } mxc_aes_revb_dma_req_t;
42 
43 static mxc_aes_revb_dma_req_t dma_state;
44 
45 #define SWAP_BYTES(x)                                                                     \
46     ((((x) >> 24) & 0x000000FF) | (((x) >> 8) & 0x0000FF00) | (((x) << 8) & 0x00FF0000) | \
47      (((x) << 24) & 0xFF000000))
48 
49 /* Prevent GCC from optimimzing this function to memcpy */
50 static void __attribute__((optimize("no-tree-loop-distribute-patterns")))
memcpy32r(uint32_t * dst,const uint32_t * src,unsigned int len)51 memcpy32r(uint32_t *dst, const uint32_t *src, unsigned int len)
52 {
53     uint32_t *dstr = dst + (len / 4) - 1;
54     while (len) {
55         *dstr = SWAP_BYTES(*src);
56         dstr--;
57         src++;
58         len -= 4;
59     }
60 }
61 
MXC_AES_RevB_Init(mxc_aes_revb_regs_t * aes)62 int MXC_AES_RevB_Init(mxc_aes_revb_regs_t *aes)
63 {
64     aes->ctrl = 0x00;
65 
66     while (MXC_AES_RevB_IsBusy(aes) != E_NO_ERROR) {}
67 
68     aes->ctrl |= MXC_F_AES_REVB_CTRL_EN;
69 
70     return E_NO_ERROR;
71 }
72 
MXC_AES_RevB_Shutdown(mxc_aes_revb_regs_t * aes)73 int MXC_AES_RevB_Shutdown(mxc_aes_revb_regs_t *aes)
74 {
75     MXC_AES_RevB_FlushInputFIFO(aes);
76     MXC_AES_RevB_FlushOutputFIFO(aes);
77 
78     while (MXC_AES_RevB_IsBusy(aes) != E_NO_ERROR) {}
79 
80     aes->ctrl = 0x00;
81 
82     return E_NO_ERROR;
83 }
84 
MXC_AES_RevB_IsBusy(mxc_aes_revb_regs_t * aes)85 int MXC_AES_RevB_IsBusy(mxc_aes_revb_regs_t *aes)
86 {
87     if (aes->status & MXC_F_AES_REVB_STATUS_BUSY) {
88         return E_BUSY;
89     }
90 
91     return E_NO_ERROR;
92 }
93 
MXC_AES_RevB_SetKeySize(mxc_aes_revb_regs_t * aes,mxc_aes_revb_keys_t key)94 void MXC_AES_RevB_SetKeySize(mxc_aes_revb_regs_t *aes, mxc_aes_revb_keys_t key)
95 {
96     while (MXC_AES_IsBusy() != E_NO_ERROR) {}
97     aes->ctrl |= key;
98 }
99 
MXC_AES_RevB_GetKeySize(mxc_aes_revb_regs_t * aes)100 mxc_aes_keys_t MXC_AES_RevB_GetKeySize(mxc_aes_revb_regs_t *aes)
101 {
102     return (aes->ctrl & MXC_F_AES_REVB_CTRL_KEY_SIZE);
103 }
104 
MXC_AES_RevB_FlushInputFIFO(mxc_aes_revb_regs_t * aes)105 void MXC_AES_RevB_FlushInputFIFO(mxc_aes_revb_regs_t *aes)
106 {
107     while (MXC_AES_IsBusy() != E_NO_ERROR) {}
108     aes->ctrl |= MXC_F_AES_REVB_CTRL_INPUT_FLUSH;
109 }
110 
MXC_AES_RevB_FlushOutputFIFO(mxc_aes_revb_regs_t * aes)111 void MXC_AES_RevB_FlushOutputFIFO(mxc_aes_revb_regs_t *aes)
112 {
113     while (MXC_AES_IsBusy() != E_NO_ERROR) {}
114     aes->ctrl |= MXC_F_AES_REVB_CTRL_OUTPUT_FLUSH;
115 }
116 
MXC_AES_RevB_Start(mxc_aes_revb_regs_t * aes)117 void MXC_AES_RevB_Start(mxc_aes_revb_regs_t *aes)
118 {
119     while (MXC_AES_IsBusy() != E_NO_ERROR) {}
120     aes->ctrl |= MXC_F_AES_REVB_CTRL_START;
121 }
122 
MXC_AES_RevB_EnableInt(mxc_aes_revb_regs_t * aes,uint32_t interrupt)123 void MXC_AES_RevB_EnableInt(mxc_aes_revb_regs_t *aes, uint32_t interrupt)
124 {
125     aes->inten |= (interrupt & (MXC_F_AES_REVB_INTEN_DONE | MXC_F_AES_REVB_INTEN_KEY_CHANGE |
126                                 MXC_F_AES_REVB_INTEN_KEY_ZERO | MXC_F_AES_REVB_INTEN_OV));
127 }
128 
MXC_AES_RevB_DisableInt(mxc_aes_revb_regs_t * aes,uint32_t interrupt)129 void MXC_AES_RevB_DisableInt(mxc_aes_revb_regs_t *aes, uint32_t interrupt)
130 {
131     aes->inten &= ~(interrupt & (MXC_F_AES_REVB_INTEN_DONE | MXC_F_AES_REVB_INTEN_KEY_CHANGE |
132                                  MXC_F_AES_REVB_INTEN_KEY_ZERO | MXC_F_AES_REVB_INTEN_OV));
133 }
134 
MXC_AES_RevB_GetFlags(mxc_aes_revb_regs_t * aes)135 uint32_t MXC_AES_RevB_GetFlags(mxc_aes_revb_regs_t *aes)
136 {
137     return aes->intfl;
138 }
139 
MXC_AES_RevB_ClearFlags(mxc_aes_revb_regs_t * aes,uint32_t flags)140 void MXC_AES_RevB_ClearFlags(mxc_aes_revb_regs_t *aes, uint32_t flags)
141 {
142     aes->intfl = (flags & (MXC_F_AES_REVB_INTFL_DONE | MXC_F_AES_REVB_INTFL_KEY_CHANGE |
143                            MXC_F_AES_REVB_INTFL_KEY_ZERO | MXC_F_AES_REVB_INTFL_OV));
144 }
145 
MXC_AES_RevB_Generic(mxc_aes_revb_regs_t * aes,mxc_aes_revb_req_t * req)146 int MXC_AES_RevB_Generic(mxc_aes_revb_regs_t *aes, mxc_aes_revb_req_t *req)
147 {
148     int i;
149     int remain;
150 
151     if (req == NULL) {
152         return E_NULL_PTR;
153     }
154 
155     if (req->inputData == NULL || req->resultData == NULL) {
156         return E_NULL_PTR;
157     }
158 
159     if (req->length == 0) {
160         return E_BAD_PARAM;
161     }
162 
163     remain = req->length;
164 
165     MXC_AES_RevB_FlushInputFIFO(aes);
166     MXC_AES_RevB_FlushOutputFIFO(aes);
167 
168     MXC_AES_RevB_SetKeySize(aes, req->keySize);
169 
170     while (MXC_AES_IsBusy() != E_NO_ERROR) {}
171 
172     MXC_SETFIELD(aes->ctrl, MXC_F_AES_REVB_CTRL_TYPE,
173                  req->encryption << MXC_F_AES_REVB_CTRL_TYPE_POS);
174 
175     while (remain / 4) {
176         for (i = 0; i < 4; i++) {
177             aes->fifo = SWAP_BYTES(req->inputData[3 - i]);
178         }
179         req->inputData += 4;
180 
181         while (!(aes->intfl & MXC_F_AES_REVB_INTFL_DONE)) {}
182         aes->intfl |= MXC_F_AES_REVB_INTFL_DONE;
183 
184         for (i = 0; i < 4; i++) {
185             uint32_t tmp = aes->fifo;
186             req->resultData[3 - i] = SWAP_BYTES(tmp);
187         }
188         req->resultData += 4;
189 
190         remain -= 4;
191     }
192 
193     if (remain % 4) {
194         for (i = 0; i < remain; i++) {
195             aes->fifo = SWAP_BYTES(req->inputData[remain - 1 - i]);
196         }
197         req->inputData += remain;
198 
199         // Pad last block with 0's
200         for (i = remain; i < 4; i++) {
201             aes->fifo = 0;
202         }
203 
204         while (!(aes->intfl & MXC_F_AES_REVB_INTFL_DONE)) {}
205         aes->intfl |= MXC_F_AES_REVB_INTFL_DONE;
206 
207         for (i = 0; i < 4; i++) {
208             uint32_t tmp = aes->fifo;
209             req->resultData[3 - i] = SWAP_BYTES(tmp);
210         }
211         req->resultData += 4;
212     }
213     return E_NO_ERROR;
214 }
215 
MXC_AES_RevB_Encrypt(mxc_aes_revb_regs_t * aes,mxc_aes_revb_req_t * req)216 int MXC_AES_RevB_Encrypt(mxc_aes_revb_regs_t *aes, mxc_aes_revb_req_t *req)
217 {
218     return MXC_AES_RevB_Generic(aes, req);
219 }
220 
MXC_AES_RevB_Decrypt(mxc_aes_revb_regs_t * aes,mxc_aes_revb_req_t * req)221 int MXC_AES_RevB_Decrypt(mxc_aes_revb_regs_t *aes, mxc_aes_revb_req_t *req)
222 {
223     return MXC_AES_RevB_Generic(aes, req);
224 }
225 
MXC_AES_RevB_TXDMAConfig(void * src_addr,int len)226 int MXC_AES_RevB_TXDMAConfig(void *src_addr, int len)
227 {
228     uint8_t channel;
229     mxc_dma_config_t config;
230     mxc_dma_srcdst_t srcdst;
231 
232     if (src_addr == NULL) {
233         return E_NULL_PTR;
234     }
235 
236     if (len == 0) {
237         return E_BAD_PARAM;
238     }
239 
240     MXC_DMA_Init();
241 
242     channel = MXC_DMA_AcquireChannel();
243     dma_state.channelTX = channel;
244 
245     config.reqsel = MXC_DMA_REQUEST_AESTX;
246 
247     config.ch = channel;
248 
249     config.srcwd = MXC_DMA_WIDTH_WORD;
250     config.dstwd = MXC_DMA_WIDTH_WORD;
251 
252     config.srcinc_en = 1;
253     config.dstinc_en = 0;
254 
255     srcdst.ch = channel;
256     srcdst.source = src_addr;
257 
258     if (dma_state.enc == 1) {
259         srcdst.len = 4;
260     } else if (len > 4) {
261         srcdst.len = 4;
262     } else {
263         srcdst.len = len;
264     }
265 
266     MXC_DMA_ConfigChannel(config, srcdst);
267     MXC_DMA_SetCallback(channel, MXC_AES_RevB_DMACallback);
268 
269     MXC_DMA_EnableInt(channel);
270     MXC_DMA_Start(channel);
271     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
272     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
273 
274     return E_NO_ERROR;
275 }
276 
MXC_AES_RevB_RXDMAConfig(void * dest_addr,int len)277 int MXC_AES_RevB_RXDMAConfig(void *dest_addr, int len)
278 {
279     if (dest_addr == NULL) {
280         return E_NULL_PTR;
281     }
282 
283     if (len == 0) {
284         return E_BAD_PARAM;
285     }
286 
287     uint8_t channel;
288     mxc_dma_config_t config;
289     mxc_dma_srcdst_t srcdst;
290 
291     MXC_DMA_Init();
292 
293     channel = MXC_DMA_AcquireChannel();
294     dma_state.channelRX = channel;
295 
296     config.reqsel = MXC_DMA_REQUEST_AESRX;
297 
298     config.ch = channel;
299 
300     config.srcwd = MXC_DMA_WIDTH_WORD;
301     config.dstwd = MXC_DMA_WIDTH_WORD;
302 
303     config.srcinc_en = 0;
304     config.dstinc_en = 1;
305 
306     srcdst.ch = channel;
307     srcdst.dest = dest_addr;
308 
309     if (dma_state.enc == 0) {
310         srcdst.len = 4;
311     } else if (len > 4) {
312         srcdst.len = 4;
313     } else {
314         srcdst.len = len;
315     }
316 
317     MXC_DMA_ConfigChannel(config, srcdst);
318     MXC_DMA_SetCallback(channel, MXC_AES_RevB_DMACallback);
319 
320     MXC_DMA_EnableInt(channel);
321     MXC_DMA_Start(channel);
322     //MXC_DMA->ch[channel].ctrl |= MXC_F_DMA_CTRL_CTZ_IE;
323     MXC_DMA_SetChannelInterruptEn(channel, 0, 1);
324 
325     return E_NO_ERROR;
326 }
327 
MXC_AES_RevB_GenericAsync(mxc_aes_revb_regs_t * aes,mxc_aes_revb_req_t * req,uint8_t enc)328 int MXC_AES_RevB_GenericAsync(mxc_aes_revb_regs_t *aes, mxc_aes_revb_req_t *req, uint8_t enc)
329 {
330     if (req == NULL) {
331         return E_NULL_PTR;
332     }
333 
334     if (req->inputData == NULL || req->resultData == NULL) {
335         return E_NULL_PTR;
336     }
337 
338     if (req->length == 0) {
339         return E_BAD_PARAM;
340     }
341 
342     MXC_AES_RevB_FlushInputFIFO(aes);
343     MXC_AES_RevB_FlushOutputFIFO(aes);
344 
345     MXC_AES_RevB_SetKeySize(aes, req->keySize);
346 
347     MXC_AES_IsBusy();
348     MXC_SETFIELD(aes->ctrl, MXC_F_AES_REVB_CTRL_TYPE,
349                  req->encryption << MXC_F_AES_REVB_CTRL_TYPE_POS);
350 
351     dma_state.enc = enc;
352     dma_state.remain = req->length;
353     dma_state.inputText = req->inputData;
354     dma_state.outputText = req->resultData;
355 
356     aes->ctrl |= MXC_F_AES_REVB_CTRL_DMA_RX_EN; //Enable AES DMA
357     aes->ctrl |= MXC_F_AES_REVB_CTRL_DMA_TX_EN; //Enable AES DMA
358 
359     if (MXC_AES_RevB_TXDMAConfig(dma_state.inputText, dma_state.remain) != E_NO_ERROR) {
360         return E_BAD_PARAM;
361     }
362 
363     return E_NO_ERROR;
364 }
365 
MXC_AES_RevB_EncryptAsync(mxc_aes_revb_regs_t * aes,mxc_aes_revb_req_t * req)366 int MXC_AES_RevB_EncryptAsync(mxc_aes_revb_regs_t *aes, mxc_aes_revb_req_t *req)
367 {
368     return MXC_AES_RevB_GenericAsync(aes, req, 0);
369 }
370 
MXC_AES_RevB_DecryptAsync(mxc_aes_revb_regs_t * aes,mxc_aes_revb_req_t * req)371 int MXC_AES_RevB_DecryptAsync(mxc_aes_revb_regs_t *aes, mxc_aes_revb_req_t *req)
372 {
373     return MXC_AES_RevB_GenericAsync(aes, req, 1);
374 }
375 
MXC_AES_RevB_DMACallback(int ch,int error)376 void MXC_AES_RevB_DMACallback(int ch, int error)
377 {
378     if (error != E_NO_ERROR) {
379     } else {
380         if (dma_state.channelTX == ch) {
381             MXC_DMA_ReleaseChannel(dma_state.channelTX);
382             if (dma_state.remain < 4) {
383                 MXC_AES_Start();
384             }
385             MXC_AES_RevB_RXDMAConfig(dma_state.outputText, dma_state.remain);
386         } else if (dma_state.channelRX == ch) {
387             if (dma_state.remain > 4) {
388                 dma_state.remain -= 4;
389             } else if (dma_state.remain > 0) {
390                 dma_state.remain = 0;
391             }
392             MXC_DMA_ReleaseChannel(dma_state.channelRX);
393             if (dma_state.remain > 0) {
394                 MXC_AES_RevB_TXDMAConfig(dma_state.inputText, dma_state.remain);
395             }
396         }
397     }
398 }
399 
MXC_AES_RevB_SetExtKey(mxc_aeskeys_revb_regs_t * aeskeys,const void * key,mxc_aes_keys_t len)400 void MXC_AES_RevB_SetExtKey(mxc_aeskeys_revb_regs_t *aeskeys, const void *key, mxc_aes_keys_t len)
401 {
402     int numBytes;
403 
404     if (len == MXC_AES_128BITS) {
405         numBytes = 16;
406     } else if (len == MXC_AES_192BITS) {
407         numBytes = 24;
408     } else {
409         numBytes = 32;
410     }
411 
412     /* TODO: Figure out if this is the correct byte ordering */
413     memcpy32r((void *)&(aeskeys->key0), key, numBytes);
414 }
415