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