1 /**************************************************************************//**
2  * @file     crypto.c
3  * @version  V3.00
4  * @brief  Cryptographic Accelerator 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 
10 #include <stdio.h>
11 #include <string.h>
12 #include "NuMicro.h"
13 
14 #define ENABLE_DEBUG    0
15 
16 #if ENABLE_DEBUG
17 #define CRPT_DBGMSG   printf
18 #else
19 #define CRPT_DBGMSG(...)   do { } while (0)       /* disable debug */
20 #endif
21 
22 #if defined(__ICCARM__)
23 # pragma diag_suppress=Pm073, Pm143        /* Misra C rule 14.7 */
24 #endif
25 
26 
27 /** @addtogroup Standard_Driver Standard Driver
28   @{
29 */
30 
31 /** @addtogroup CRYPTO_Driver CRYPTO Driver
32   @{
33 */
34 
35 
36 /** @addtogroup CRYPTO_EXPORTED_FUNCTIONS CRYPTO Exported Functions
37   @{
38 */
39 
40 /* // @cond HIDDEN_SYMBOLS */
41 
42 /* // @endcond HIDDEN_SYMBOLS */
43 
44 /**
45   * @brief  Open PRNG function
46   * @param[in]  crpt         The pointer of CRPT module
47   * @param[in]  u32KeySize   it is PRNG key size, including:
48   *         - \ref PRNG_KEY_SIZE_128
49   *         - \ref PRNG_KEY_SIZE_163
50   *         - \ref PRNG_KEY_SIZE_192
51   *         - \ref PRNG_KEY_SIZE_224
52   *         - \ref PRNG_KEY_SIZE_233
53   *         - \ref PRNG_KEY_SIZE_255
54   *         - \ref PRNG_KEY_SIZE_256
55   * @param[in]  u32SeedReload is PRNG seed reload or not, including:
56   *         - \ref PRNG_SEED_CONT
57   *         - \ref PRNG_SEED_RELOAD
58   * @param[in]  u32Seed  The new seed. Only valid when u32SeedReload is PRNG_SEED_RELOAD.
59   * @return None
60   */
PRNG_Open(CRPT_T * crpt,uint32_t u32KeySize,uint32_t u32SeedReload,uint32_t u32Seed)61 void PRNG_Open(CRPT_T *crpt, uint32_t u32KeySize, uint32_t u32SeedReload, uint32_t u32Seed)
62 {
63     if(u32SeedReload)
64     {
65         crpt->PRNG_SEED = u32Seed;
66     }
67 
68     crpt->PRNG_CTL = (u32KeySize << CRPT_PRNG_CTL_KEYSZ_Pos) |
69                      (u32SeedReload << CRPT_PRNG_CTL_SEEDRLD_Pos) | PRNG_CTL_SEEDSRC_SEEDREG;
70 }
71 
72 /**
73   * @brief  Start to generate one PRNG key.
74   * @param[in]  crpt         The pointer of CRPT module
75   * @retval  0 Generate PRNG key success.
76   * @retval -1 Generate PRNG key time-out.
77   */
PRNG_Start(CRPT_T * crpt)78 int32_t PRNG_Start(CRPT_T *crpt)
79 {
80 	  int32_t i32TimeOutCnt = SystemCoreClock;
81     crpt->PRNG_CTL |= CRPT_PRNG_CTL_START_Msk;
82 
83     /* Waiting for PRNG Busy */
84     while(crpt->PRNG_CTL & CRPT_PRNG_CTL_BUSY_Msk)
85     {
86         if( i32TimeOutCnt-- <= 0)
87         {
88             return -1;
89         }
90     }
91     return 0;
92 }
93 
94 /**
95   * @brief  Read the PRNG key.
96   * @param[in]   crpt         The pointer of CRPT module
97   * @param[out]  u32RandKey  The key buffer to store newly generated PRNG key.
98   * @return None
99   */
PRNG_Read(CRPT_T * crpt,uint32_t u32RandKey[])100 void PRNG_Read(CRPT_T *crpt, uint32_t u32RandKey[])
101 {
102     uint32_t  i, wcnt;
103     uint32_t au32WcntTbl[7] = {4, 6, 6, 7, 8, 8, 8};
104 
105     wcnt = ((crpt->PRNG_CTL & CRPT_PRNG_CTL_KEYSZ_Msk) >> CRPT_PRNG_CTL_KEYSZ_Pos);
106     if( wcnt > 6 ) return;
107     else wcnt = au32WcntTbl[wcnt];
108 
109     for(i = 0U; i < wcnt; i++)
110     {
111         u32RandKey[i] = crpt->PRNG_KEY[i];
112     }
113 
114     crpt->PRNG_CTL &= ~CRPT_PRNG_CTL_SEEDRLD_Msk;
115 }
116 
117 
118 /**
119   * @brief  Open AES encrypt/decrypt function.
120   * @param[in]  crpt         The pointer of CRPT module
121   * @param[in]  u32Channel   AES channel. Must be 0~3.
122   * @param[in]  u32EncDec    1: AES encode;  0: AES decode
123   * @param[in]  u32OpMode    AES operation mode, including:
124   *         - \ref AES_MODE_ECB
125   *         - \ref AES_MODE_CBC
126   *         - \ref AES_MODE_CFB
127   *         - \ref AES_MODE_OFB
128   *         - \ref AES_MODE_CTR
129   *         - \ref AES_MODE_CBC_CS1
130   *         - \ref AES_MODE_CBC_CS2
131   *         - \ref AES_MODE_CBC_CS3
132   * @param[in]  u32KeySize is AES key size, including:
133   *         - \ref AES_KEY_SIZE_128
134   *         - \ref AES_KEY_SIZE_192
135   *         - \ref AES_KEY_SIZE_256
136   * @param[in]  u32SwapType is AES input/output data swap control, including:
137   *         - \ref AES_NO_SWAP
138   *         - \ref AES_OUT_SWAP
139   *         - \ref AES_IN_SWAP
140   *         - \ref AES_IN_OUT_SWAP
141   * @return None
142   */
AES_Open(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32EncDec,uint32_t u32OpMode,uint32_t u32KeySize,uint32_t u32SwapType)143 void AES_Open(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32EncDec,
144               uint32_t u32OpMode, uint32_t u32KeySize, uint32_t u32SwapType)
145 {
146     (void)u32Channel;
147 
148     crpt->AES_CTL = (u32EncDec << CRPT_AES_CTL_ENCRPT_Pos) |
149                     (u32OpMode << CRPT_AES_CTL_OPMODE_Pos) |
150                     (u32KeySize << CRPT_AES_CTL_KEYSZ_Pos) |
151                     (u32SwapType << CRPT_AES_CTL_OUTSWAP_Pos);
152 
153 }
154 
155 /**
156   * @brief  Start AES encrypt/decrypt
157   * @param[in]  crpt        The pointer of CRPT module
158   * @param[in]  u32Channel  AES channel. Must be 0~3.
159   * @param[in]  u32DMAMode  AES DMA control, including:
160   *         - \ref CRYPTO_DMA_ONE_SHOT   One shot AES encrypt/decrypt.
161   *         - \ref CRYPTO_DMA_CONTINUE   Continuous AES encrypt/decrypt.
162   *         - \ref CRYPTO_DMA_LAST       Last AES encrypt/decrypt of a series of AES_Start.
163   * @return None
164   */
AES_Start(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32DMAMode)165 void AES_Start(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32DMAMode)
166 {
167     (void)u32Channel;
168 
169     crpt->AES_CTL |= CRPT_AES_CTL_START_Msk | (u32DMAMode << CRPT_AES_CTL_DMALAST_Pos);
170 }
171 
172 /**
173   * @brief  Set AES keys
174   * @param[in]  crpt        The pointer of CRPT module
175   * @param[in]  u32Channel  AES channel. Must be 0~3.
176   * @param[in]  au32Keys    An word array contains AES keys.
177   * @param[in]  u32KeySize is AES key size, including:
178   *         - \ref AES_KEY_SIZE_128
179   *         - \ref AES_KEY_SIZE_192
180   *         - \ref AES_KEY_SIZE_256
181   * @return None
182   */
AES_SetKey(CRPT_T * crpt,uint32_t u32Channel,uint32_t au32Keys[],uint32_t u32KeySize)183 void AES_SetKey(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32Keys[], uint32_t u32KeySize)
184 {
185     uint32_t  i, wcnt, key_reg_addr;
186 
187     (void) u32Channel;
188 
189     key_reg_addr = (uint32_t)&crpt->AES_KEY[0];
190     wcnt = 4UL + u32KeySize * 2UL;
191 
192     for(i = 0U; i < wcnt; i++)
193     {
194         outpw(key_reg_addr, au32Keys[i]);
195         key_reg_addr += 4UL;
196     }
197 }
198 
199 /**
200   * @brief  Set AES initial vectors
201   * @param[in]  crpt        The pointer of CRPT module
202   * @param[in]  u32Channel  AES channel. Must be 0~3.
203   * @param[in]  au32IV      A four entry word array contains AES initial vectors.
204   * @return None
205   */
AES_SetInitVect(CRPT_T * crpt,uint32_t u32Channel,uint32_t au32IV[])206 void AES_SetInitVect(CRPT_T *crpt, uint32_t u32Channel, uint32_t au32IV[])
207 {
208     uint32_t  i, key_reg_addr;
209 
210     (void) u32Channel;
211 
212     key_reg_addr = (uint32_t)&crpt->AES_IV[0];
213 
214     for(i = 0U; i < 4U; i++)
215     {
216         outpw(key_reg_addr, au32IV[i]);
217         key_reg_addr += 4UL;
218     }
219 }
220 
221 /**
222   * @brief  Set AES DMA transfer configuration.
223   * @param[in]  crpt         The pointer of CRPT module
224   * @param[in]  u32Channel   AES channel. Must be 0~3.
225   * @param[in]  u32SrcAddr   AES DMA source address
226   * @param[in]  u32DstAddr   AES DMA destination address
227   * @param[in]  u32TransCnt  AES DMA transfer byte count
228   * @return None
229   */
AES_SetDMATransfer(CRPT_T * crpt,uint32_t u32Channel,uint32_t u32SrcAddr,uint32_t u32DstAddr,uint32_t u32TransCnt)230 void AES_SetDMATransfer(CRPT_T *crpt, uint32_t u32Channel, uint32_t u32SrcAddr,
231                         uint32_t u32DstAddr, uint32_t u32TransCnt)
232 {
233     (void) u32Channel;
234 
235     crpt->AES_SADDR = u32SrcAddr;
236     crpt->AES_DADDR = u32DstAddr;
237     crpt->AES_CNT   = u32TransCnt;
238 
239 }
240 
241 
242 /**@}*/ /* end of group CRYPTO_EXPORTED_FUNCTIONS */
243 
244 /**@}*/ /* end of group CRYPTO_Driver */
245 
246 /**@}*/ /* end of group Standard_Driver */
247