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