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