1 /**************************************************************************//**
2 * @file keystore.c
3 * @version V3.01
4 * @brief Key store driver source file
5 *
6 * @copyright SPDX-License-Identifier: Apache-2.0
7 * @copyright Copyright (C) 2022 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 /** @addtogroup KS_EXPORTED_FUNCTIONS Key Store Exported Functions
19 @{
20 */
21
22 /**
23 * @brief Initial key store
24 * @retval 0 Successful
25 * @retval others Fail
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 int32_t KS_Open(void)
30 {
31 uint32_t u32TimeOutCount;
32 uint32_t au32Key[8] = {0};
33
34 CLK->AHBCLK0 |= CLK_AHBCLK0_KSCKEN_Msk;
35
36 /* Key store initial */
37 if((KS->STS & KS_STS_INITDONE_Msk) == 0)
38 {
39 /* Waiting for busy */
40 u32TimeOutCount = KS_TIMEOUT;
41 while(KS->STS & KS_STS_BUSY_Msk)
42 {
43 if(--u32TimeOutCount == 0)
44 {
45 return KS_ERR_TIMEOUT;
46 }
47 }
48
49 /* Start Key Store Initial */
50 KS->CTL = KS_CTL_INIT_Msk | KS_CTL_START_Msk;
51
52 /* Waiting for initilization */
53 u32TimeOutCount = KS_TIMEOUT;
54 while((KS->STS & KS_STS_INITDONE_Msk) == 0)
55 {
56 if(--u32TimeOutCount == 0)
57 {
58 return KS_ERR_TIMEOUT;
59 }
60 }
61 }
62
63 /* Waiting busy to make sure KS is ready. */
64 u32TimeOutCount = KS_TIMEOUT;
65 while(KS->STS & KS_STS_BUSY_Msk)
66 {
67 if(--u32TimeOutCount == 0)
68 {
69 return KS_ERR_TIMEOUT;
70 }
71 }
72
73 /* Create dummy key for KS Flash and KS SRAM */
74 if(KS_Read(KS_FLASH, 0, au32Key, 8) < 0)
75 {
76 if(KS_Write(KS_FLASH, KS_META_CPU | KS_META_READABLE | KS_META_256, au32Key) != 0)
77 {
78 return KS_ERR_INIT;
79 }
80 }
81
82 if(KS_Read(KS_SRAM, 0, au32Key, 8) < 0)
83 {
84 if(KS_Write(KS_SRAM, KS_META_CPU | KS_META_READABLE | KS_META_256, au32Key) != 0)
85 {
86 return KS_ERR_INIT;
87 }
88 }
89
90 return KS_OK;
91 }
92
93
94 /**
95 * @brief Read key from key store
96 * @param[in] eType The memory type. It could be:
97 \ref KS_SRAM
98 \ref KS_FLASH
99 \ref KS_OTP
100 * @param[in] i32KeyIdx The key index to read
101 * @param[out] au32Key The buffer to store the key
102 * @param[in] u32WordCnt The word (32-bit) count of the key buffer size
103 * @retval 0 Successful
104 * @retval -1 Fail
105 * @details This function is used to read the key.
106 */
107
KS_Read(KS_MEM_Type eType,int32_t i32KeyIdx,uint32_t au32Key[],uint32_t u32WordCnt)108 int32_t KS_Read(KS_MEM_Type eType, int32_t i32KeyIdx, uint32_t au32Key[], uint32_t u32WordCnt)
109 {
110 int32_t i32Cnt;
111 uint32_t u32Cont;
112 int32_t offset, i, cnt;
113 uint32_t u32TimeOutCount;
114
115 /* Wait when key store is in busy */
116 if(KS->STS & KS_STS_BUSY_Msk)
117 {
118 /* Waiting for key store processing */
119 u32TimeOutCount = KS_TIMEOUT;
120 while(KS->STS & KS_STS_BUSY_Msk)
121 {
122 if(--u32TimeOutCount == 0)
123 return KS_ERR_TIMEOUT;
124 }
125 }
126
127 /* Specify the key address */
128 KS->METADATA = ((uint32_t)eType << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
129
130 /* Clear error flag */
131 KS->STS = KS_STS_EIF_Msk;
132 offset = 0;
133 u32Cont = 0;
134 i32Cnt = (int32_t)u32WordCnt;
135 do
136 {
137 /* Clear Status */
138 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
139
140 /* Trigger to read the key */
141 KS->CTL = u32Cont | KS_OP_READ | KS_CTL_START_Msk;
142 /* Waiting for key store processing */
143 u32TimeOutCount = KS_TIMEOUT;
144 while(KS->STS & KS_STS_BUSY_Msk)
145 {
146 if(--u32TimeOutCount == 0)
147 return KS_ERR_TIMEOUT;
148 }
149
150 /* Read the key to key buffer */
151 cnt = i32Cnt;
152 if(cnt > 8)
153 cnt = 8;
154 for(i = 0; i < cnt; i++)
155 {
156 au32Key[offset + i] = KS->KEY[i];
157 }
158
159 u32Cont = KS_CTL_CONT_Msk;
160 i32Cnt -= 8;
161 offset += 8;
162 }
163 while(i32Cnt > 0);
164
165 /* Check error flag */
166 if(KS->STS & KS_STS_EIF_Msk)
167 return KS_ERR_FAIL;
168
169
170 return KS_OK;
171 }
172
173 /**
174 * @brief Get the word count of the specified Metadata key length
175 * @param[in] u32Meta The metadata define of the key length. It could be
176 \ref KS_META_128
177 \ref KS_META_163
178 \ref KS_META_192
179 \ref KS_META_224
180 \ref KS_META_233
181 \ref KS_META_255
182 \ref KS_META_256
183 \ref KS_META_283
184 \ref KS_META_384
185 \ref KS_META_409
186 \ref KS_META_512
187 \ref KS_META_521
188 \ref KS_META_571
189 \ref KS_META_1024
190 \ref KS_META_2048
191 \ref KS_META_4096
192 * @return The word (32-bit) count of the key
193 * @details This function is used to get word counts of the specified metadata key length.
194 * It could be used to know how may words needs to allocate for the key.
195 */
196
KS_GetKeyWordCnt(uint32_t u32Meta)197 uint32_t KS_GetKeyWordCnt(uint32_t u32Meta)
198 {
199 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 };
200 return au8CntTbl[((u32Meta & KS_METADATA_SIZE_Msk) >> KS_METADATA_SIZE_Pos)];
201 }
202
203 /**
204 * @brief Write key to key store
205 * @param[in] eType The memory type. It could be:
206 \ref KS_SRAM
207 \ref KS_FLASH
208 * @param[in] u32Meta The metadata of the key. It could be the combine of
209 \ref KS_META_AES
210 \ref KS_META_HMAC
211 \ref KS_META_RSA_EXP
212 \ref KS_META_RSA_MID
213 \ref KS_META_ECC
214 \ref KS_META_CPU
215 \ref KS_META_128
216 \ref KS_META_163
217 \ref KS_META_192
218 \ref KS_META_224
219 \ref KS_META_233
220 \ref KS_META_255
221 \ref KS_META_256
222 \ref KS_META_283
223 \ref KS_META_384
224 \ref KS_META_409
225 \ref KS_META_512
226 \ref KS_META_521
227 \ref KS_META_571
228 \ref KS_META_1024
229 \ref KS_META_2048
230 \ref KS_META_4096
231 \ref KS_META_BOOT
232 \ref KS_META_READABLE
233 \ref KS_META_PRIV
234 \ref KS_META_NONPRIV
235 \ref KS_META_SECURE
236 \ref KS_META_NONSECUR
237
238 * @param[out] au32Key The buffer to store the key
239 * @param[in] u32WordCnt The word (32-bit) count of the key buffer size
240 * @return Index of the key. Failed when index < 0.
241 * @details This function is used to write a key to key store.
242 */
243
KS_Write(KS_MEM_Type eType,uint32_t u32Meta,uint32_t au32Key[])244 int32_t KS_Write(KS_MEM_Type eType, uint32_t u32Meta, uint32_t au32Key[])
245 {
246 int32_t i32Cnt;
247 uint32_t u32Cont;
248 int32_t i, cnt;
249 volatile int32_t offset;
250 uint32_t u32TimeOutCount;
251
252 /* Wait when key store is in busy */
253 if(KS->STS & KS_STS_BUSY_Msk)
254 {
255 /* Waiting for key store processing */
256 u32TimeOutCount = KS_TIMEOUT;
257 while(KS->STS & KS_STS_BUSY_Msk)
258 {
259 if(--u32TimeOutCount == 0)
260 return KS_ERR_TIMEOUT;
261 }
262 }
263
264 /* Specify the key address */
265 KS->METADATA = (eType << KS_METADATA_DST_Pos) | u32Meta;
266
267 /* Get size index */
268 i32Cnt = (int32_t)KS_GetKeyWordCnt(u32Meta);
269
270 /* Invalid key length */
271 if(i32Cnt == 0)
272 return KS_ERR_PARAMETER;
273
274 /* OTP only support maximum 256 bits */
275 if((eType == KS_OTP) && (i32Cnt > 8))
276 return KS_ERR_PARAMETER;
277
278 /* Check size limit of KS FLASH */
279 if(eType == KS_FLASH)
280 {
281 if((int32_t)KS_GetRemainSize(KS_FLASH) - i32Cnt * 4 < 4)
282 return KS_ERR_FAIL;
283 }
284
285 /* Check key count limit of KS SRAM */
286 if(eType == KS_SRAM)
287 {
288 if(KS_GetRemainKeyCount(KS_SRAM) == 1)
289 return KS_ERR_FAIL;
290 }
291
292 /* Clear error flag */
293 KS->STS = KS_STS_EIF_Msk;
294 offset = 0;
295 u32Cont = 0;
296 do
297 {
298 /* Prepare the key to write */
299 cnt = i32Cnt;
300 if(cnt > 8)
301 cnt = 8;
302 for(i = 0; i < cnt; i++)
303 {
304 KS->KEY[i] = au32Key[offset + i];
305 }
306
307 /* Clear Status */
308 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
309
310 /* Write the key */
311 KS->CTL = u32Cont | KS_OP_WRITE | KS_CTL_START_Msk;
312
313 u32Cont = KS_CTL_CONT_Msk;
314 i32Cnt -= 8;
315 offset += 8;
316
317 /* Waiting for key store processing */
318 u32TimeOutCount = KS_TIMEOUT;
319 while(KS->STS & KS_STS_BUSY_Msk)
320 {
321 if(--u32TimeOutCount == 0)
322 return KS_ERR_TIMEOUT;
323 }
324
325 }
326 while(i32Cnt > 0);
327
328 /* Check error flag */
329 if(KS->STS & KS_STS_EIF_Msk)
330 {
331 return KS_ERR_FAIL;
332 }
333
334 return KS_TOKEYIDX(KS->METADATA);
335 }
336
337 /**
338 * @brief Erase a key from key store SRAM
339 * @param[in] i32KeyIdx The key index to read
340 * @retval 0 Successful
341 * @retval -1 Fail
342 * @details This function is used to erase a key from SRAM of key store.
343 */
KS_EraseKey(int32_t i32KeyIdx)344 int32_t KS_EraseKey(int32_t i32KeyIdx)
345 {
346 uint32_t u32TimeOutCount = KS_TIMEOUT;
347
348 /* Wait when key store is in busy */
349 if(KS->STS & KS_STS_BUSY_Msk)
350 {
351 /* Waiting for key store processing */
352 u32TimeOutCount = KS_TIMEOUT;
353 while(KS->STS & KS_STS_BUSY_Msk)
354 {
355 if(--u32TimeOutCount == 0)
356 return KS_ERR_TIMEOUT;
357 }
358 }
359
360 /* Clear error flag */
361 KS->STS = KS_STS_EIF_Msk;
362
363 /* Specify the key address */
364 KS->METADATA = (KS_SRAM << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
365
366 /* Clear Status */
367 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
368
369 /* Erase the key */
370 KS->CTL = KS_OP_ERASE | KS_CTL_START_Msk;
371
372 /* Waiting for processing */
373 while(KS->STS & KS_STS_BUSY_Msk)
374 {
375 if(--u32TimeOutCount == 0)
376 return KS_ERR_TIMEOUT;
377 }
378
379 /* Check error flag */
380 if(KS->STS & KS_STS_EIF_Msk)
381 return KS_ERR_FAIL;
382
383 return KS_OK;
384
385 }
386
387
388 /**
389 * @brief Erase a key from key store OTP
390 * @param[in] i32KeyIdx The key index to erase
391 * @retval 0 Successful
392 * @retval -1 Fail
393 * @details This function is used to erase a key from key store OTP.
394 */
KS_EraseOTPKey(int32_t i32KeyIdx)395 int32_t KS_EraseOTPKey(int32_t i32KeyIdx)
396 {
397 uint32_t u32TimeOutCount = KS_TIMEOUT; /* 1 second time-out */
398
399 /* Wait when key store is in busy */
400 if(KS->STS & KS_STS_BUSY_Msk)
401 {
402 /* Waiting for key store processing */
403 u32TimeOutCount = KS_TIMEOUT;
404 while(KS->STS & KS_STS_BUSY_Msk)
405 {
406 if(--u32TimeOutCount == 0)
407 return KS_ERR_TIMEOUT;
408 }
409 }
410
411 /* Clear error flag */
412 KS->STS = KS_STS_EIF_Msk;
413
414 /* Specify the key address */
415 KS->METADATA = ((uint32_t)KS_OTP << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
416
417 /* Clear Status */
418 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
419
420 /* Erase the key */
421 KS->CTL = KS_OP_ERASE | KS_CTL_START_Msk;
422
423 /* Waiting for processing */
424 while(KS->STS & KS_STS_BUSY_Msk)
425 {
426 if(--u32TimeOutCount == 0)
427 return KS_ERR_TIMEOUT;
428 }
429
430 /* Check error flag */
431 if(KS->STS & KS_STS_EIF_Msk)
432 return KS_ERR_FAIL;
433
434 return KS_OK;
435
436 }
437
438
439
440 /**
441 * @brief Lock the OTP key
442 * @param[in] i32KeyIdx The key index to lock
443 * @retval 0 Successful
444 * @retval -1 Fail
445 * @details This function is used to lock a key of KS OTP.
446 */
KS_LockOTPKey(int32_t i32KeyIdx)447 int32_t KS_LockOTPKey(int32_t i32KeyIdx)
448 {
449 uint32_t u32TimeOutCount = KS_TIMEOUT;
450
451 /* Wait when key store is in busy */
452 if(KS->STS & KS_STS_BUSY_Msk)
453 {
454 /* Waiting for key store processing */
455 u32TimeOutCount = KS_TIMEOUT;
456 while(KS->STS & KS_STS_BUSY_Msk)
457 {
458 if(--u32TimeOutCount == 0)
459 return KS_ERR_TIMEOUT;
460 }
461 }
462
463 /* Clear error flag */
464 KS->STS = KS_STS_EIF_Msk;
465
466 /* Specify the key address */
467 KS->METADATA = ((uint32_t)KS_OTP << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
468
469 /* Clear Status */
470 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
471
472 /* Erase the key */
473 KS->CTL = KS_OP_LOCK | KS_CTL_START_Msk;
474
475 /* Waiting for processing */
476 while(KS->STS & KS_STS_BUSY_Msk)
477 {
478 if(--u32TimeOutCount == 0)
479 return KS_ERR_TIMEOUT;
480 }
481
482 /* Check error flag */
483 if(KS->STS & KS_STS_EIF_Msk)
484 return KS_ERR_FAIL;
485
486 return KS_OK;
487
488 }
489
490 /**
491 * @brief Erase all keys from key store
492 * @param[in] eType The memory type. It could be:
493 \ref KS_SRAM
494 \ref KS_FLASH
495 \ref KS_OTP
496 * @param[in] i32KeyIdx The key index to read
497 * @retval 0 Successful
498 * @retval -1 Fail
499 * @details This function is used to erase all keys in SRAM or Flash of key store.
500 */
KS_EraseAll(KS_MEM_Type eType)501 int32_t KS_EraseAll(KS_MEM_Type eType)
502 {
503 uint32_t au32Key[8] = { 0 };
504 uint32_t u32TimeOutCount = KS_TIMEOUT;
505
506 /* Wait when key store is in busy */
507 if(KS->STS & KS_STS_BUSY_Msk)
508 {
509 /* Waiting for key store processing */
510 u32TimeOutCount = KS_TIMEOUT;
511 while(KS->STS & KS_STS_BUSY_Msk)
512 {
513 if(--u32TimeOutCount == 0)
514 return KS_ERR_TIMEOUT;
515 }
516 }
517
518 /* Clear error flag */
519 KS->STS = KS_STS_EIF_Msk;
520
521 /* Specify the key address */
522 KS->METADATA = (eType << KS_METADATA_DST_Pos);
523
524 /* Clear Status */
525 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
526
527 /* Erase the key */
528 KS->CTL = KS_OP_ERASE_ALL | KS_CTL_START_Msk;
529
530 /* Waiting for processing */
531 while(KS->STS & KS_STS_BUSY_Msk)
532 {
533 if(--u32TimeOutCount == 0)
534 return KS_ERR_TIMEOUT;
535 }
536
537 /* Check error flag */
538 if(KS->STS & KS_STS_EIF_Msk)
539 return KS_ERR_FAIL;
540
541 /* Create dummy key for KS Flash and KS SRAM */
542 if(KS_Read(KS_FLASH, 0, au32Key, 8) < 0)
543 {
544 if(KS_Write(KS_FLASH, KS_META_CPU | KS_META_READABLE | KS_META_256, au32Key) != 0)
545 {
546 return KS_ERR_FAIL;
547 }
548 }
549
550 if(KS_Read(KS_SRAM, 0, au32Key, 8) < 0)
551 {
552 if(KS_Write(KS_SRAM, KS_META_CPU | KS_META_READABLE | KS_META_256, au32Key) != 0)
553 {
554 return KS_ERR_FAIL;
555 }
556 }
557
558 return KS_OK;
559
560 }
561
562
563
564 /**
565 * @brief Revoke a key in key store
566 * @param[in] eType The memory type. It could be:
567 \ref KS_SRAM
568 \ref KS_FLASH
569 \ref KS_OTP
570 * @param[in] i32KeyIdx The key index to read
571 * @retval 0 Successful
572 * @retval -1 Fail
573 * @details This function is used to revoke a key in key store.
574 */
KS_RevokeKey(KS_MEM_Type eType,int32_t i32KeyIdx)575 int32_t KS_RevokeKey(KS_MEM_Type eType, int32_t i32KeyIdx)
576 {
577 uint32_t u32TimeOutCount = KS_TIMEOUT;
578
579 /* Wait when key store is in busy */
580 if(KS->STS & KS_STS_BUSY_Msk)
581 {
582 /* Waiting for key store processing */
583 u32TimeOutCount = KS_TIMEOUT;
584 while(KS->STS & KS_STS_BUSY_Msk)
585 {
586 if(--u32TimeOutCount == 0)
587 return KS_ERR_TIMEOUT;
588 }
589 }
590
591 /* Clear error flag */
592 KS->STS = KS_STS_EIF_Msk;
593
594 /* Specify the key address */
595 KS->METADATA = (eType << KS_METADATA_DST_Pos) | KS_TOMETAKEY(i32KeyIdx);
596
597 /* Clear Status */
598 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
599
600 /* Erase the key */
601 KS->CTL = KS_OP_REVOKE | KS_CTL_START_Msk;
602
603 /* Waiting for processing */
604 while(KS->STS & KS_STS_BUSY_Msk)
605 {
606 if(--u32TimeOutCount == 0)
607 return KS_ERR_TIMEOUT;
608 }
609
610 /* Check error flag */
611 if(KS->STS & KS_STS_EIF_Msk)
612 return KS_ERR_FAIL;
613
614 return KS_OK;
615
616 }
617
618
619 /**
620 * @brief Get remain size of specified Key Store memory
621 * @param[in] eType The memory type. It could be:
622 \ref KS_SRAM
623 \ref KS_FLASH
624 * @retval remain size of specified Key Store memory
625 * @details This function is used to get remain size of Key Store.
626 */
KS_GetRemainSize(KS_MEM_Type mem)627 uint32_t KS_GetRemainSize(KS_MEM_Type mem)
628 {
629 uint32_t u32Reg;
630 uint32_t u32SramRemain, u32FlashRemain;
631
632 u32Reg = KS->REMAIN;
633 //printf("KS Remain 0x%08x\n", u32Reg);
634 //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);
635 u32SramRemain = (u32Reg & KS_REMAIN_RRMNG_Msk) >> KS_REMAIN_RRMNG_Pos;
636 u32FlashRemain = (u32Reg & KS_REMAIN_FRMNG_Msk) >> KS_REMAIN_FRMNG_Pos;
637
638 if(mem == KS_SRAM)
639 return u32SramRemain;
640 else
641 return u32FlashRemain;
642 }
643
644
645
646 /**
647 * @brief Get remain key count of specified Key Store memory
648 * @param[in] eType The memory type. It could be:
649 \ref KS_SRAM
650 \ref KS_FLASH
651 * @retval Remain key count in the specified key store memory
652 * @details This function is used to get remain key count in specified key store memory.
653 */
KS_GetRemainKeyCount(KS_MEM_Type mem)654 uint32_t KS_GetRemainKeyCount(KS_MEM_Type mem)
655 {
656 uint32_t u32Reg;
657 uint32_t u32SramRemain, u32FlashRemain;
658
659 u32Reg = KS->REMKCNT;
660 u32SramRemain = (u32Reg & KS_REMKCNT_RRMKCNT_Msk) >> KS_REMKCNT_RRMKCNT_Pos;
661 u32FlashRemain = (u32Reg & KS_REMKCNT_FRMKCNT_Msk) >> KS_REMKCNT_FRMKCNT_Pos;
662
663 if(mem == KS_SRAM)
664 return u32SramRemain;
665 else
666 return u32FlashRemain;
667 }
668
669
670
671 /**
672 * @brief Write OTP key to key store
673 * @param[in] i32KeyIdx The OTP key index to store the key. It could be 0~7.
674 OTP key index 0 is default for ROTPK.
675 * @param[in] u32Meta The metadata of the key. It could be the combine of
676 \ref KS_META_AES
677 \ref KS_META_HMAC
678 \ref KS_META_RSA_EXP
679 \ref KS_META_RSA_MID
680 \ref KS_META_ECC
681 \ref KS_META_CPU
682 \ref KS_META_128
683 \ref KS_META_163
684 \ref KS_META_192
685 \ref KS_META_224
686 \ref KS_META_233
687 \ref KS_META_255
688 \ref KS_META_256
689 \ref KS_META_BOOT
690 \ref KS_META_READABLE
691 \ref KS_META_PRIV
692 \ref KS_META_NONPRIV
693 \ref KS_META_SECURE
694 \ref KS_META_NONSECUR
695
696 * @param[out] au32Key The buffer to store the key
697 * @param[in] u32WordCnt The word (32-bit) count of the key buffer size
698 * @retval 0 Successful
699 * @retval -1 Fail
700 * @details This function is used to write a key to OTP key store.
701 */
KS_WriteOTP(int32_t i32KeyIdx,uint32_t u32Meta,uint32_t au32Key[])702 int32_t KS_WriteOTP(int32_t i32KeyIdx, uint32_t u32Meta, uint32_t au32Key[])
703 {
704 const uint16_t au8CntTbl[7] = {4, 6, 6, 7, 8, 8, 8};
705 int32_t i32Cnt;
706 uint32_t u32Cont;
707 int32_t offset, i, cnt, sidx;
708 uint32_t u32TimeOutCount;
709
710 /* Wait when key store is in busy */
711 if(KS->STS & KS_STS_BUSY_Msk)
712 {
713 /* Waiting for key store processing */
714 u32TimeOutCount = KS_TIMEOUT;
715 while(KS->STS & KS_STS_BUSY_Msk)
716 {
717 if(--u32TimeOutCount == 0)
718 return KS_ERR_TIMEOUT;
719 }
720 }
721
722 /* Specify the key address */
723 KS->METADATA = ((uint32_t)KS_OTP << KS_METADATA_DST_Pos) | u32Meta | KS_TOMETAKEY(i32KeyIdx);
724
725 /* Get size index */
726 sidx = (u32Meta >> KS_METADATA_SIZE_Pos) & 0xful;
727
728 /* OTP only support maximum 256 bits */
729 if(sidx >= 7)
730 return KS_ERR_PARAMETER;
731
732 i32Cnt = au8CntTbl[sidx];
733
734 /* Clear error flag */
735 KS->STS = KS_STS_EIF_Msk;
736 offset = 0;
737 u32Cont = 0;
738 do
739 {
740 /* Prepare the key to write */
741 cnt = i32Cnt;
742 if(cnt > 8)
743 cnt = 8;
744 for(i = 0; i < cnt; i++)
745 {
746 KS->KEY[i] = au32Key[offset + i];
747 }
748
749 /* Clear Status */
750 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
751
752 /* Write the key */
753 KS->CTL = u32Cont | KS_OP_WRITE | KS_CTL_START_Msk;
754
755 u32Cont = KS_CTL_CONT_Msk;
756 i32Cnt -= 8;
757 offset += 8;
758
759 /* Waiting for key store processing */
760 u32TimeOutCount = KS_TIMEOUT;
761 while(KS->STS & KS_STS_BUSY_Msk)
762 {
763 if(--u32TimeOutCount == 0)
764 return KS_ERR_TIMEOUT;
765 }
766
767 }
768 while(i32Cnt > 0);
769
770 /* Check error flag */
771 if(KS->STS & KS_STS_EIF_Msk)
772 {
773 return KS_ERR_FAIL;
774 }
775
776 return i32KeyIdx;
777 }
778
779
780 /**
781 * @brief Trigger to inverse the date in KS_SRAM.
782 * @retval 1 The data in KS SRAM is inverted.
783 * @retval 0 The data in KS SRAM is non-inverted.
784 * @retval -1 Fail to invert the date in KS SRAM.
785 * @details This function is used to trigger anti-remanence procedure by inverse the data in SRAM.
786 * This won't change the reading key.
787 */
788
KS_ToggleSRAM(void)789 int32_t KS_ToggleSRAM(void)
790 {
791 uint32_t u32TimeOutCount = KS_TIMEOUT;
792
793 /* Wait when key store is in busy */
794 if(KS->STS & KS_STS_BUSY_Msk)
795 {
796 /* Waiting for key store processing */
797 u32TimeOutCount = KS_TIMEOUT;
798 while(KS->STS & KS_STS_BUSY_Msk)
799 {
800 if(--u32TimeOutCount == 0)
801 return KS_ERR_TIMEOUT;
802 }
803 }
804
805
806 /* Specify the key address */
807 KS->METADATA = ((uint32_t)KS_SRAM << KS_METADATA_DST_Pos);
808
809 /* Clear error flag */
810 KS->STS = KS_STS_EIF_Msk | KS_STS_IF_Msk;
811 /* Trigger to do anti-remanence procedure */
812 KS->CTL = KS_OP_REMAN | KS_CTL_START_Msk;
813
814 /* Waiting for key store processing */
815 while(KS->STS & KS_STS_BUSY_Msk)
816 {
817 if(--u32TimeOutCount == 0)
818 return KS_ERR_TIMEOUT;
819 }
820
821 /* Check error flag */
822 if(KS->STS & KS_STS_EIF_Msk)
823 return KS_ERR_FAIL;
824
825 return ((KS->STS & KS_STS_RAMINV_Msk) > 0);
826 }
827
828
829 /**@}*/ /* end of group KS_EXPORTED_FUNCTIONS */
830
831 /**@}*/ /* end of group KS_Driver */
832
833 /**@}*/ /* end of group Standard_Driver */
834