1 /**
2  * @file
3  * @brief   Trust Protection Unit driver.
4  */
5 
6 /******************************************************************************
7  *
8  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9  * Analog Devices, Inc.),
10  * Copyright (C) 2023-2024 Analog Devices, Inc.
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *     http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  *
24  ******************************************************************************/
25 
26 #include "mxc_device.h"
27 #include "mxc_errors.h"
28 #include "mxc_assert.h"
29 #include "mxc_sys.h"
30 #include "aes_revb.h"
31 #include "trng.h"
32 #include "flc.h"
33 #include "string.h"
34 
35 #define KEY_ADDR 0x10802008
36 #define FMV_ADDR 0x10802000
37 static const uint32_t fmv[2] = { 0x2B86D479, 0x2B86D479 };
38 
reverse_key(const void * key,uint8_t * keyr,int len)39 static void reverse_key(const void *key, uint8_t *keyr, int len)
40 {
41     int i;
42     uint8_t tmp;
43     uint8_t *k = (uint8_t *)key;
44     for (i = 0; i < len; i++) {
45         tmp = k[i];
46         k[i] = keyr[len - i - 1];
47         keyr[len - i - 1] = tmp;
48     }
49 }
50 
51 /* ************************************************************************* */
52 /* Global Control/Configuration functions                                    */
53 /* ************************************************************************* */
54 
MXC_AES_Init(void)55 int MXC_AES_Init(void)
56 {
57 #ifndef MSDK_NO_GPIO_CLK_INIT
58     MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_AES);
59     MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_TRNG);
60 #endif
61 
62     MXC_AES->ctrl = 0x00;
63     // Start with a randomly generated key.
64     MXC_AES_GenerateKey();
65 
66     MXC_AES_RevB_Init((mxc_aes_revb_regs_t *)MXC_AES);
67 
68     return E_NO_ERROR;
69 }
70 
MXC_AES_EnableInt(uint32_t interrupt)71 void MXC_AES_EnableInt(uint32_t interrupt)
72 {
73     MXC_AES_RevB_EnableInt((mxc_aes_revb_regs_t *)MXC_AES, interrupt);
74 }
75 
MXC_AES_DisableInt(uint32_t interrupt)76 void MXC_AES_DisableInt(uint32_t interrupt)
77 {
78     MXC_AES_RevB_DisableInt((mxc_aes_revb_regs_t *)MXC_AES, interrupt);
79 }
80 
MXC_AES_IsBusy(void)81 int MXC_AES_IsBusy(void)
82 {
83     return MXC_AES_RevB_IsBusy((mxc_aes_revb_regs_t *)MXC_AES);
84 }
85 
MXC_AES_Shutdown(void)86 int MXC_AES_Shutdown(void)
87 {
88     int error = MXC_AES_RevB_Shutdown((mxc_aes_revb_regs_t *)MXC_AES);
89 
90     MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_AES);
91 
92     return error;
93 }
94 
MXC_AES_DMACallback(int ch,int error)95 void MXC_AES_DMACallback(int ch, int error)
96 {
97     MXC_AES_RevB_DMACallback(ch, error);
98 }
99 
MXC_AES_GenerateKey(void)100 void MXC_AES_GenerateKey(void)
101 {
102     // Generating a random key is part of the TRNG block
103     MXC_TRNG_GenerateKey();
104 }
105 
MXC_AES_SetKeySize(mxc_aes_keys_t key)106 void MXC_AES_SetKeySize(mxc_aes_keys_t key)
107 {
108     MXC_AES_RevB_SetKeySize((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_keys_t)key);
109 }
110 
MXC_AES_GetKeySize(void)111 mxc_aes_keys_t MXC_AES_GetKeySize(void)
112 {
113     return MXC_AES_RevB_GetKeySize((mxc_aes_revb_regs_t *)MXC_AES);
114 }
115 
MXC_AES_FlushInputFIFO(void)116 void MXC_AES_FlushInputFIFO(void)
117 {
118     MXC_AES_RevB_FlushInputFIFO((mxc_aes_revb_regs_t *)MXC_AES);
119 }
120 
MXC_AES_FlushOutputFIFO(void)121 void MXC_AES_FlushOutputFIFO(void)
122 {
123     MXC_AES_RevB_FlushOutputFIFO((mxc_aes_revb_regs_t *)MXC_AES);
124 }
125 
MXC_AES_Start(void)126 void MXC_AES_Start(void)
127 {
128     MXC_AES_RevB_Start((mxc_aes_revb_regs_t *)MXC_AES);
129 }
130 
MXC_AES_GetFlags(void)131 uint32_t MXC_AES_GetFlags(void)
132 {
133     return MXC_AES_RevB_GetFlags((mxc_aes_revb_regs_t *)MXC_AES);
134 }
135 
MXC_AES_ClearFlags(uint32_t flags)136 void MXC_AES_ClearFlags(uint32_t flags)
137 {
138     MXC_AES_RevB_ClearFlags((mxc_aes_revb_regs_t *)MXC_AES, flags);
139 }
140 
MXC_AES_Generic(mxc_aes_req_t * req)141 int MXC_AES_Generic(mxc_aes_req_t *req)
142 {
143     return MXC_AES_RevB_Generic((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req);
144 }
145 
MXC_AES_Encrypt(mxc_aes_req_t * req)146 int MXC_AES_Encrypt(mxc_aes_req_t *req)
147 {
148     return MXC_AES_RevB_Encrypt((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req);
149 }
150 
MXC_AES_Decrypt(mxc_aes_req_t * req)151 int MXC_AES_Decrypt(mxc_aes_req_t *req)
152 {
153     return MXC_AES_RevB_Decrypt((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req);
154 }
155 
MXC_AES_TXDMAConfig(void * src_addr,int len)156 int MXC_AES_TXDMAConfig(void *src_addr, int len)
157 {
158     return MXC_AES_RevB_TXDMAConfig(src_addr, len);
159 }
160 
MXC_AES_RXDMAConfig(void * dest_addr,int len)161 int MXC_AES_RXDMAConfig(void *dest_addr, int len)
162 {
163     return MXC_AES_RevB_RXDMAConfig(dest_addr, len);
164 }
165 
MXC_AES_GenericAsync(mxc_aes_req_t * req,uint8_t enc)166 int MXC_AES_GenericAsync(mxc_aes_req_t *req, uint8_t enc)
167 {
168     return MXC_AES_RevB_GenericAsync((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req,
169                                      enc);
170 }
171 
MXC_AES_EncryptAsync(mxc_aes_req_t * req)172 int MXC_AES_EncryptAsync(mxc_aes_req_t *req)
173 {
174     return MXC_AES_RevB_EncryptAsync((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req);
175 }
176 
MXC_AES_DecryptAsync(mxc_aes_req_t * req)177 int MXC_AES_DecryptAsync(mxc_aes_req_t *req)
178 {
179     return MXC_AES_RevB_DecryptAsync((mxc_aes_revb_regs_t *)MXC_AES, (mxc_aes_revb_req_t *)req);
180 }
181 
MXC_AES_SetExtKey(const void * key,mxc_aes_keys_t len)182 void MXC_AES_SetExtKey(const void *key, mxc_aes_keys_t len)
183 {
184     MXC_AES_RevB_SetExtKey((mxc_aeskeys_revb_regs_t *)MXC_AESKEYS, key, len);
185 }
186 
MXC_AES_SetPORKey(const void * key,mxc_aes_keys_t len)187 int MXC_AES_SetPORKey(const void *key, mxc_aes_keys_t len)
188 {
189     int err = E_BAD_PARAM;
190     uint8_t keyr[32];
191 
192     // Make the key location readable/writable
193     MXC_FLC_UnlockInfoBlock(KEY_ADDR);
194 
195     // Write the key
196     switch (len) {
197     case MXC_AES_128BITS:
198         reverse_key(key, keyr, 16);
199         err = MXC_FLC_Write(KEY_ADDR, 16, (uint32_t *)keyr);
200         break;
201     case MXC_AES_192BITS:
202         reverse_key(key, keyr, 24);
203         err = MXC_FLC_Write(KEY_ADDR, 24, (uint32_t *)keyr);
204         break;
205     case MXC_AES_256BITS:
206         reverse_key(key, keyr, 32);
207         err = MXC_FLC_Write(KEY_ADDR, 32, (uint32_t *)keyr);
208         break;
209     }
210 
211     if (err == E_NO_ERROR) {
212         // Write the magic value to activate the key
213         err = MXC_FLC_Write(FMV_ADDR, sizeof(fmv), (uint32_t *)fmv);
214 
215         // Lock the key region from reads/writes
216         MXC_FLC_LockInfoBlock(KEY_ADDR);
217         return err;
218     }
219 
220     // Lock the key region from reads/writes
221     MXC_FLC_LockInfoBlock(KEY_ADDR);
222     return err;
223 }
224 
MXC_AES_ClearPORKey(void)225 int MXC_AES_ClearPORKey(void)
226 {
227     int err;
228 
229     // The first 40 bytes of the page contain the FMV and AES key, no
230     //  need to save those.
231     uint8_t page[MXC_FLASH_PAGE_SIZE - 40];
232 
233     // Make the key location readable/writable
234     MXC_FLC_UnlockInfoBlock(FMV_ADDR);
235 
236     // Copy the current memory contents
237     memcpy(page, (uint8_t *)FMV_ADDR + 40, MXC_FLASH_PAGE_SIZE - 40);
238 
239     err = MXC_FLC_PageErase(FMV_ADDR);
240     if (err != E_NO_ERROR) {
241         // Couldn't erase the memory.  Abort.
242         // Lock the key region from reads/writes
243         MXC_FLC_LockInfoBlock(FMV_ADDR);
244         return err;
245     }
246 
247     // Write the old contents (minus the fmv and key) back to the part
248     err = MXC_FLC_Write(FMV_ADDR + 40, MXC_FLASH_PAGE_SIZE - 40, (uint32_t *)page);
249 
250     // Lock the key region from reads/writes
251     MXC_FLC_LockInfoBlock(FMV_ADDR);
252 
253     return err;
254 }
255 
MXC_AES_CopyPORKeyToKeyRegisters(mxc_aes_keys_t len)256 void MXC_AES_CopyPORKeyToKeyRegisters(mxc_aes_keys_t len)
257 {
258     // Make the key location readable/writable
259     MXC_FLC_UnlockInfoBlock(KEY_ADDR);
260 
261     // Copy the values to the key register
262     switch (len) {
263     case MXC_AES_128BITS:
264         memcpy(MXC_AESKEYS, (uint8_t *)KEY_ADDR, 16);
265         break;
266     case MXC_AES_192BITS:
267         memcpy(MXC_AESKEYS, (uint8_t *)KEY_ADDR, 24);
268         break;
269     case MXC_AES_256BITS:
270         memcpy(MXC_AESKEYS, (uint8_t *)KEY_ADDR, 32);
271         break;
272     }
273 
274     // Lock the key region from reads/writes
275     MXC_FLC_LockInfoBlock(KEY_ADDR);
276 }
277 
MXC_AES_HasPORKey(void)278 int MXC_AES_HasPORKey(void)
279 {
280     int res;
281 
282     // Make the key location readable/writable
283     MXC_FLC_UnlockInfoBlock(FMV_ADDR);
284 
285     // Look for the magic value.
286     res = memcmp((uint8_t *)FMV_ADDR, (uint8_t *)fmv, 8);
287 
288     // Lock the key region from reads/writes
289     MXC_FLC_LockInfoBlock(FMV_ADDR);
290 
291     return !res;
292 }
293