1 /**************************************************************************//**
2 * @file keystore.c
3 * @version V3.00
4 * @brief Key store driver source file
5 *
6 * @copyright SPDX-License-Identifier: Apache-2.0
7 * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10 /** @addtogroup Standard_Driver Standard Driver
11 @{
12 */
13
14 /** @addtogroup KS_Driver Key Store Driver
15 @{
16 */
17
18
19 /** @addtogroup KS_EXPORTED_FUNCTIONS Key Store Exported Functions
20 @{
21 */
22
23 /**
24 * @brief Initial key store
25 * @return None
26 * @details This function is used to initial the key store.
27 * It is necessary to be called before using other APIs of Key Store.
28 */
KS_Open(void)29 void KS_Open(void)
30 {
31 if((KS->STS & KS_STS_INITDONE_Msk) == 0)
32 {
33 /* Waiting for busy */
34 while(KS->STS & KS_STS_BUSY_Msk) {}
35
36 /* Start Key Store Initial */
37 KS->CTL = KS_CTL_INIT_Msk | KS_CTL_START_Msk;
38
39 /* Waiting for initilization */
40 while((KS->STS & KS_STS_INITDONE_Msk) == 0);
41
42 }
43
44 /* Waiting busy to make sure KS is ready. */
45 while(KS->STS & KS_STS_BUSY_Msk);
46
47 }
48
49
50 /**
51 * @brief Read key from key store
52 * @param[in] eType The memory type. It could be:
53 \ref KS_SRAM
54 \ref KS_FLASH
55 \ref KS_OTP
56 * @param[in] i32KeyIdx The key index to read
57 * @param[out] au32Key The buffer to store the key
58 * @param[in] u32WordCnt The word (32-bit) count of the key buffer size
59 * @retval 0 Successful
60 * @retval -1 Fail
61 * @details This function is used to read the key.
62 */
63
KS_Read(KS_MEM_Type eType,int32_t i32KeyIdx,uint32_t au32Key[],uint32_t u32WordCnt)64 int32_t KS_Read(KS_MEM_Type eType, int32_t i32KeyIdx, uint32_t au32Key[], uint32_t u32WordCnt)
65 {
66 int32_t i32Cnt;
67 uint32_t u32Cont;
68 int32_t offset, i, cnt;
69
70 /* Just return when key store is in busy */
71 if(KS->STS & KS_STS_BUSY_Msk)
72 return -1;
73
74 /* Specify the key address */
75 KS->METADATA = ((uint32_t)eType << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
76
77 /* Clear error flag */
78 KS->STS = KS_STS_EIF_Msk;
79 offset = 0;
80 u32Cont = 0;
81 i32Cnt = (int32_t)u32WordCnt;
82 do
83 {
84 /* Clear Status */
85 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
86
87 /* Trigger to read the key */
88 KS->CTL = u32Cont | KS_OP_READ | KS_CTL_START_Msk | (KS->CTL & (KS_CTL_SILENT_Msk | KS_CTL_SCMB_Msk));
89 /* Waiting for key store processing */
90 while(KS->STS & KS_STS_BUSY_Msk);
91
92 /* Read the key to key buffer */
93 cnt = i32Cnt;
94 if(cnt > 8)
95 cnt = 8;
96 for(i = 0; i < cnt; i++)
97 {
98 au32Key[offset + i] = KS->KEY[i];
99 //printf("R[%d]:0x%08x\n", i, au32Key[offset+i]);
100 }
101
102 u32Cont = KS_CTL_CONT_Msk;
103 i32Cnt -= 8;
104 offset += 8;
105 }
106 while(i32Cnt > 0);
107
108 /* Check error flag */
109 if(KS->STS & KS_STS_EIF_Msk)
110 return -1;
111
112
113 return 0;
114 }
115
116 /**
117 * @brief Get the word count of the specified Metadata key length
118 * @param[in] u32Meta The metadata define of the key length. It could be
119 \ref KS_META_128
120 \ref KS_META_163
121 \ref KS_META_192
122 \ref KS_META_224
123 \ref KS_META_233
124 \ref KS_META_255
125 \ref KS_META_256
126 \ref KS_META_283
127 \ref KS_META_384
128 \ref KS_META_409
129 \ref KS_META_512
130 \ref KS_META_521
131 \ref KS_META_571
132 \ref KS_META_1024
133 \ref KS_META_2048
134 \ref KS_META_4096
135 * @return The word (32-bit) count of the key
136 * @details This function is used to get word counts of the specified metadata key length.
137 * It could be used to know how may words needs to allocate for the key.
138 */
139
KS_GetKeyWordCnt(uint32_t u32Meta)140 uint32_t KS_GetKeyWordCnt(uint32_t u32Meta)
141 {
142 const uint16_t au8CntTbl[21] = { 4, 6, 6, 7, 8, 8, 8, 9, 12, 13, 16, 17, 18, 0, 0, 0, 32, 48, 64, 96, 128 };
143 return au8CntTbl[((u32Meta & KS_METADATA_SIZE_Msk) >> KS_METADATA_SIZE_Pos)];
144 }
145
146 /**
147 * @brief Write key to key store
148 * @param[in] eType The memory type. It could be:
149 \ref KS_SRAM
150 \ref KS_FLASH
151 * @param[in] u32Meta The metadata of the key. It could be the combine of
152 \ref KS_META_AES
153 \ref KS_META_HMAC
154 \ref KS_META_RSA_EXP
155 \ref KS_META_RSA_MID
156 \ref KS_META_ECC
157 \ref KS_META_CPU
158 \ref KS_META_128
159 \ref KS_META_163
160 \ref KS_META_192
161 \ref KS_META_224
162 \ref KS_META_233
163 \ref KS_META_255
164 \ref KS_META_256
165 \ref KS_META_283
166 \ref KS_META_384
167 \ref KS_META_409
168 \ref KS_META_512
169 \ref KS_META_521
170 \ref KS_META_571
171 \ref KS_META_1024
172 \ref KS_META_2048
173 \ref KS_META_4096
174 \ref KS_META_BOOT
175 \ref KS_META_READABLE
176 \ref KS_META_PRIV
177 \ref KS_META_NONPRIV
178 \ref KS_META_SECURE
179 \ref KS_META_NONSECUR
180
181 * @param[out] au32Key The buffer to store the key
182 * @param[in] u32WordCnt The word (32-bit) count of the key buffer size
183 * @return Index of the key. Failed when index < 0.
184 * @details This function is used to write a key to key store.
185 */
186
KS_Write(KS_MEM_Type eType,uint32_t u32Meta,uint32_t au32Key[])187 int32_t KS_Write(KS_MEM_Type eType, uint32_t u32Meta, uint32_t au32Key[])
188 {
189 int32_t i32Cnt;
190 uint32_t u32Cont;
191 int32_t offset, i, cnt;
192
193
194 /* Just return when key store is in busy */
195 if(KS->STS & KS_STS_BUSY_Msk)
196 return -1;
197
198 /* Specify the key address */
199 KS->METADATA = (eType << KS_METADATA_DST_Pos) | u32Meta;
200
201 /* Get size index */
202 i32Cnt = (int32_t)KS_GetKeyWordCnt(u32Meta);
203
204 /* Invalid key length */
205 if(i32Cnt == 0)
206 return -1;
207
208 /* OTP only support maximum 256 bits */
209 if((eType == KS_OTP) && (i32Cnt > 8))
210 return -1;
211
212 /* Clear error flag */
213 KS->STS = KS_STS_EIF_Msk;
214 offset = 0;
215 u32Cont = 0;
216 do
217 {
218 /* Prepare the key to write */
219 cnt = i32Cnt;
220 if(cnt > 8)
221 cnt = 8;
222 for(i = 0; i < cnt; i++)
223 {
224 KS->KEY[i] = au32Key[offset + i];
225 }
226
227 /* Clear Status */
228 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
229
230 /* Write the key */
231 KS->CTL = u32Cont | KS_OP_WRITE | KS_CTL_START_Msk | (KS->CTL & (KS_CTL_SILENT_Msk | KS_CTL_SCMB_Msk));
232
233 u32Cont = KS_CTL_CONT_Msk;
234 i32Cnt -= 8;
235 offset += 8;
236
237 /* Waiting for key store processing */
238 while(KS->STS & KS_STS_BUSY_Msk);
239
240 }
241 while(i32Cnt > 0);
242
243 /* Check error flag */
244 if(KS->STS & KS_STS_EIF_Msk)
245 {
246 //printf("KS_Write. EIF!\n");
247 return -1;
248 }
249
250 return KS_TOKEYIDX(KS->METADATA);
251 }
252
253 /**
254 * @brief Erase a key from key store
255 * @param[in] i32KeyIdx The key index to read
256 * @retval 0 Successful
257 * @retval -1 Fail
258 * @details This function is used to erase a key from SRAM of key store.
259 */
KS_EraseKey(int32_t i32KeyIdx)260 int32_t KS_EraseKey(int32_t i32KeyIdx)
261 {
262 /* Just return when key store is in busy */
263 if(KS->STS & KS_STS_BUSY_Msk)
264 return -1;
265
266 /* Clear error flag */
267 KS->STS = KS_STS_EIF_Msk;
268
269 /* Specify the key address */
270 KS->METADATA = (KS_SRAM << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
271
272 /* Clear Status */
273 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
274
275 /* Erase the key */
276 KS->CTL = KS_OP_ERASE | KS_CTL_START_Msk | (KS->CTL & (KS_CTL_SILENT_Msk | KS_CTL_SCMB_Msk));
277
278 /* Waiting for processing */
279 while(KS->STS & KS_STS_BUSY_Msk);
280
281 /* Check error flag */
282 if(KS->STS & KS_STS_EIF_Msk)
283 return -1;
284
285 return 0;
286
287 }
288
289
290 /**
291 * @brief Erase all keys from key store
292 * @param[in] eType The memory type. It could be:
293 \ref KS_SRAM
294 \ref KS_FLASH
295 \ref KS_OTP
296 * @param[in] i32KeyIdx The key index to read
297 * @retval 0 Successful
298 * @retval -1 Fail
299 * @details This function is used to erase all keys in SRAM or Flash of key store.
300 */
KS_EraseAll(KS_MEM_Type eType)301 int32_t KS_EraseAll(KS_MEM_Type eType)
302 {
303 /* Just return when key store is in busy */
304 if(KS->STS & KS_STS_BUSY_Msk)
305 return -1;
306
307 /* Clear error flag */
308 KS->STS = KS_STS_EIF_Msk;
309
310 /* Specify the key address */
311 KS->METADATA = (eType << KS_METADATA_DST_Pos);
312
313 /* Clear Status */
314 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
315
316 /* Erase the key */
317 KS->CTL = KS_OP_ERASE_ALL | KS_CTL_START_Msk | (KS->CTL & (KS_CTL_SILENT_Msk | KS_CTL_SCMB_Msk));
318
319 /* Waiting for processing */
320 while(KS->STS & KS_STS_BUSY_Msk);
321
322 /* Check error flag */
323 if(KS->STS & KS_STS_EIF_Msk)
324 return -1;
325
326 return 0;
327
328 }
329
330
331
332 /**
333 * @brief Revoke a key in key store
334 * @param[in] eType The memory type. It could be:
335 \ref KS_SRAM
336 \ref KS_FLASH
337 \ref KS_OTP
338 * @param[in] i32KeyIdx The key index to read
339 * @retval 0 Successful
340 * @retval -1 Fail
341 * @details This function is used to revoke a key in key store.
342 */
KS_RevokeKey(KS_MEM_Type eType,int32_t i32KeyIdx)343 int32_t KS_RevokeKey(KS_MEM_Type eType, int32_t i32KeyIdx)
344 {
345 /* Just return when key store is in busy */
346 if(KS->STS & KS_STS_BUSY_Msk)
347 return -1;
348
349 /* Clear error flag */
350 KS->STS = KS_STS_EIF_Msk;
351
352 /* Specify the key address */
353 KS->METADATA = (eType << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
354
355 /* Clear Status */
356 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
357
358 /* Erase the key */
359 KS->CTL = KS_OP_REVOKE | KS_CTL_START_Msk | (KS->CTL & (KS_CTL_SILENT_Msk | KS_CTL_SCMB_Msk));
360
361 /* Waiting for processing */
362 while(KS->STS & KS_STS_BUSY_Msk);
363
364 /* Check error flag */
365 if(KS->STS & KS_STS_EIF_Msk)
366 return -1;
367
368 return 0;
369
370 }
371
372
373 /**
374 * @brief Get remain size of specified Key Store memory
375 * @param[in] eType The memory type. It could be:
376 \ref KS_SRAM
377 \ref KS_FLASH
378 * @retval remain size of specified Key Store memory
379 * @details This function is used to get remain size of Key Store.
380 */
KS_GetRemainSize(KS_MEM_Type mem)381 uint32_t KS_GetRemainSize(KS_MEM_Type mem)
382 {
383 uint32_t u32Reg;
384 uint32_t u32SramRemain, u32FlashRemain;
385
386 u32Reg = KS->REMAIN;
387 //printf("KS Remain 0x%08x\n", u32Reg);
388 //printf("SRAM remain %lu bytes, Flash remain %lu bytes\n",(u32Reg&KS_REMAIN_RRMNG_Msk) >> KS_REMAIN_RRMNG_Pos, (u32Reg&KS_REMAIN_FRMNG_Msk) >> KS_REMAIN_FRMNG_Pos);
389 u32SramRemain = (u32Reg & KS_REMAIN_RRMNG_Msk) >> KS_REMAIN_RRMNG_Pos;
390 u32FlashRemain = (u32Reg & KS_REMAIN_FRMNG_Msk) >> KS_REMAIN_FRMNG_Pos;
391
392 if(mem == KS_SRAM)
393 return u32SramRemain;
394 else
395 return u32FlashRemain;
396 }
397
398
399
400 /**
401 * @brief Get remain key count of specified Key Store memory
402 * @param[in] eType The memory type. It could be:
403 \ref KS_SRAM
404 \ref KS_FLASH
405 * @retval Remain key count in the specified key store memory
406 * @details This function is used to get remain key count in specified key store memory.
407 */
KS_GetRemainKeyCount(KS_MEM_Type mem)408 uint32_t KS_GetRemainKeyCount(KS_MEM_Type mem)
409 {
410 uint32_t u32Reg;
411 uint32_t u32SramRemain, u32FlashRemain;
412
413 u32Reg = KS->REMKCNT;
414 u32SramRemain = (u32Reg & KS_REMKCNT_RRMKCNT_Msk) >> KS_REMKCNT_RRMKCNT_Pos;
415 u32FlashRemain = (u32Reg & KS_REMKCNT_FRMKCNT_Msk) >> KS_REMKCNT_FRMKCNT_Pos;
416
417 if(mem == KS_SRAM)
418 return u32SramRemain;
419 else
420 return u32FlashRemain;
421 }
422
423
424
425 /**
426 * @brief Write OTP key to key store
427 * @param[in] i32KeyIdx The OTP key index to store the key. It could be 0~7.
428 OTP key index 0 is default for ROTPK.
429 * @param[in] u32Meta The metadata of the key. It could be the combine of
430 \ref KS_META_AES
431 \ref KS_META_HMAC
432 \ref KS_META_RSA_EXP
433 \ref KS_META_RSA_MID
434 \ref KS_META_ECC
435 \ref KS_META_CPU
436 \ref KS_META_128
437 \ref KS_META_163
438 \ref KS_META_192
439 \ref KS_META_224
440 \ref KS_META_233
441 \ref KS_META_255
442 \ref KS_META_256
443 \ref KS_META_BOOT
444 \ref KS_META_READABLE
445 \ref KS_META_PRIV
446 \ref KS_META_NONPRIV
447 \ref KS_META_SECURE
448 \ref KS_META_NONSECUR
449
450 * @param[out] au32Key The buffer to store the key
451 * @param[in] u32WordCnt The word (32-bit) count of the key buffer size
452 * @retval 0 Successful
453 * @retval -1 Fail
454 * @details This function is used to write a key to OTP key store.
455 */
KS_WriteOTP(int32_t i32KeyIdx,uint32_t u32Meta,uint32_t au32Key[])456 int32_t KS_WriteOTP(int32_t i32KeyIdx, uint32_t u32Meta, uint32_t au32Key[])
457 {
458 const uint16_t au8CntTbl[7] = {4, 6, 6, 7, 8, 8, 8};
459 int32_t i32Cnt;
460 uint32_t u32Cont;
461 int32_t offset, i, cnt, sidx;
462
463
464 /* Just return when key store is in busy */
465 if(KS->STS & KS_STS_BUSY_Msk)
466 return -1;
467
468 /* Specify the key address */
469 KS->METADATA = ((uint32_t)KS_OTP << KS_METADATA_DST_Pos) | u32Meta | KS_TOMETAKEY(i32KeyIdx);
470
471 /* Get size index */
472 sidx = (u32Meta >> KS_METADATA_SIZE_Pos) & 0xful;
473
474 /* OTP only support maximum 256 bits */
475 if(sidx >= 7)
476 return -1;
477
478 i32Cnt = au8CntTbl[sidx];
479
480 /* Clear error flag */
481 KS->STS = KS_STS_EIF_Msk;
482 offset = 0;
483 u32Cont = 0;
484 do
485 {
486 /* Prepare the key to write */
487 cnt = i32Cnt;
488 if(cnt > 8)
489 cnt = 8;
490 for(i = 0; i < cnt; i++)
491 {
492 KS->KEY[i] = au32Key[offset + i];
493 }
494
495 /* Clear Status */
496 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
497
498 /* Write the key */
499 KS->CTL = u32Cont | KS_OP_WRITE | KS_CTL_START_Msk | (KS->CTL & (KS_CTL_SILENT_Msk | KS_CTL_SCMB_Msk));
500
501 u32Cont = KS_CTL_CONT_Msk;
502 i32Cnt -= 8;
503 offset += 8;
504
505 /* Waiting for key store processing */
506 while(KS->STS & KS_STS_BUSY_Msk);
507
508 }
509 while(i32Cnt > 0);
510
511 /* Check error flag */
512 if(KS->STS & KS_STS_EIF_Msk)
513 {
514 //printf("KS_WriteOTP. EIF!\n");
515 return -1;
516 }
517
518 return i32KeyIdx;
519 }
520
521
522 /**
523 * @brief Trigger to inverse the date in KS_SRAM.
524 * @retval 1 The data in KS SRAM is inverted.
525 * @retval 0 The data in KS SRAM is non-inverted.
526 * @retval -1 Fail to invert the date in KS SRAM.
527 * @details This function is used to trigger anti-remanence procedure by inverse the data in SRAM.
528 * This won't change the reading key.
529 */
530
KS_ToggleSRAM(void)531 int32_t KS_ToggleSRAM(void)
532 {
533 /* Just return when key store is in busy */
534 if(KS->STS & KS_STS_BUSY_Msk)
535 return -1;
536
537
538 /* Specify the key address */
539 KS->METADATA = ((uint32_t)KS_SRAM << KS_METADATA_DST_Pos);
540
541 /* Clear error flag */
542 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
543 /* Trigger to do anti-remanence procedure */
544 KS->CTL = KS_OP_REMAN | KS_CTL_START_Msk;
545
546 /* Waiting for key store processing */
547 while(KS->STS & KS_STS_BUSY_Msk);
548
549 /* Check error flag */
550 if(KS->STS & KS_STS_EIF_Msk)
551 return -1;
552
553 return ((KS->STS & KS_STS_RAMINV_Msk) > 0);
554 }
555
556
557 /**@}*/ /* end of group KS_EXPORTED_FUNCTIONS */
558
559 /**@}*/ /* end of group KS_Driver */
560
561 /**@}*/ /* end of group Standard_Driver */
562