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