|
150 | 150 | #endif |
151 | 151 | #endif |
152 | 152 |
|
| 153 | +#if !defined(NO_AES) && !defined(WC_NO_AES) |
| 154 | + #include <wolfssl/wolfcrypt/aes.h> |
| 155 | +#endif |
| 156 | + |
153 | 157 | /* prevent multiple mutex initializations */ |
154 | 158 | static volatile int initRefCount = 0; |
155 | 159 |
|
156 | 160 | #if defined(__aarch64__) && defined(WOLFSSL_ARMASM_BARRIER_DETECT) |
157 | 161 | int aarch64_use_sb = 0; |
158 | 162 | #endif |
159 | 163 |
|
| 164 | +#ifdef WOLFCRYPT_WARMUP |
| 165 | +static int wolfCrypt_Warmup(void) |
| 166 | +{ |
| 167 | + int ret = 0; |
| 168 | + WC_RNG rng; |
| 169 | + byte dummy; |
| 170 | +#if !defined(NO_AES) && !defined(WC_NO_AES) && defined(HAVE_AESGCM) |
| 171 | + Aes aes; |
| 172 | + unsigned char key16[16]; |
| 173 | + unsigned char out[16]; |
| 174 | + unsigned char in[16]; |
| 175 | + unsigned char iv[12]; |
| 176 | + int devId; |
| 177 | +#endif |
| 178 | + |
| 179 | +#if defined(DEBUG_WOLFSSL_MALLOC_VERBOSE) |
| 180 | + WOLFSSL_MSG("Warming up RNG"); |
| 181 | +#endif |
| 182 | + ret = wc_InitRng(&rng); |
| 183 | + if (ret == 0) { |
| 184 | + /* forces Hash_DRBG/SHA */ |
| 185 | + ret = wc_RNG_GenerateBlock(&rng, &dummy, 1); |
| 186 | + if (ret != 0) { |
| 187 | + WOLFSSL_MSG("wolfCrypt_Init wc_RNG_GenerateBlock failed"); |
| 188 | + } |
| 189 | + } |
| 190 | + if (ret != 0) { |
| 191 | + WOLFSSL_MSG("wolfCrypt_Init RNG warmup failed"); |
| 192 | + } |
| 193 | + ret = wc_FreeRng(&rng); |
| 194 | + if (ret != 0) { |
| 195 | + WOLFSSL_MSG("wolfCrypt_Init wc_FreeRng failed"); |
| 196 | + } |
| 197 | + |
| 198 | +#if !defined(NO_AES) && !defined(WC_NO_AES) && defined(HAVE_AESGCM) |
| 199 | +#if defined(DEBUG_WOLFSSL_MALLOC_VERBOSE) |
| 200 | + WOLFSSL_MSG("Warming up AES"); |
| 201 | +#endif |
| 202 | + memset(key16, 0, sizeof(key16)); |
| 203 | + memset(iv, 0, sizeof(iv)); |
| 204 | + memset(in, 0, sizeof(in)); |
| 205 | + devId = INVALID_DEVID; |
| 206 | + |
| 207 | + ret = wc_AesInit(&aes, NULL, devId); |
| 208 | + if (ret == 0) { |
| 209 | + /* Set an ECB key (no IV). This avoids pulling in GCM/GHASH. */ |
| 210 | + ret = wc_AesSetKey(&aes, key16, (word32)sizeof(key16), NULL, |
| 211 | + AES_ENCRYPTION); |
| 212 | + } |
| 213 | + if (ret == 0) { |
| 214 | +#ifdef WOLFSSL_AES_DIRECT |
| 215 | + /* Single direct block encrypt to exercise the core/driver. */ |
| 216 | + ret = wc_AesEncryptDirect(&aes, out, in); |
| 217 | +#elif !defined(NO_AES_CBC) |
| 218 | + /* One-block CBC (tiny; no padding; does not pull GCM). */ |
| 219 | + ret = wc_AesSetIV(&aes, iv); |
| 220 | + if (ret == 0) { |
| 221 | + ret = wc_AesCbcEncrypt(&aes, out, in, (word32)sizeof(in)); |
| 222 | + } |
| 223 | +#elif defined(HAVE_AES_CTR) || defined(WOLFSSL_AES_COUNTER) |
| 224 | + /* As another lightweight option, CTR one-block. */ |
| 225 | + ret = wc_AesSetIV(&aes, iv); |
| 226 | + if (ret == 0) { |
| 227 | + ret = wc_AesCtrEncrypt(&aes, out, in, (word32)sizeof(in)); |
| 228 | + } |
| 229 | +#else |
| 230 | + /* No small mode available; setting the key already did most of the warmup. */ |
| 231 | + ret = 0; |
| 232 | +#endif |
| 233 | + } |
| 234 | + if (ret != 0) { |
| 235 | + WOLFSSL_MSG("AES warmup failed during wolfCrypt_Init"); |
| 236 | + } |
| 237 | + wc_AesFree(&aes); |
| 238 | +#endif /* !NO_AES && !WC_NO_AES && HAVE_AESGCM */ |
| 239 | + |
| 240 | + return ret; |
| 241 | +} |
| 242 | +#endif /* WOLFCRYPT_WARMUP */ |
| 243 | + |
160 | 244 | /* Used to initialize state for wolfcrypt |
161 | 245 | return 0 on success |
162 | 246 | */ |
163 | 247 | WOLFSSL_ABI |
164 | 248 | int wolfCrypt_Init(void) |
165 | 249 | { |
166 | 250 | int ret = 0; |
| 251 | + |
167 | 252 | if (initRefCount == 0) { |
168 | 253 | WOLFSSL_ENTER("wolfCrypt_Init"); |
169 | 254 |
|
| 255 | + #ifdef WOLFCRYPT_WARMUP |
| 256 | + /* Warm up the hardware to allocate any heap & semaphore early */ |
| 257 | + ret = wolfCrypt_Warmup(); |
| 258 | + #endif |
| 259 | + |
| 260 | + #if defined(DEBUG_WOLFSSL_MALLOC_VERBOSE) |
| 261 | + WOLFSSL_MSG("Warming up RNG"); |
| 262 | + #endif |
| 263 | + |
170 | 264 | #if defined(__aarch64__) && defined(WOLFSSL_ARMASM_BARRIER_DETECT) |
171 | 265 | aarch64_use_sb = IS_AARCH64_SB(cpuid_get_flags()); |
172 | 266 | #endif |
@@ -444,11 +538,13 @@ int wolfCrypt_Init(void) |
444 | 538 | return ret; |
445 | 539 | } |
446 | 540 | #endif |
447 | | - } |
| 541 | + |
| 542 | + } /* (initRefCount == 0) */ |
| 543 | + |
448 | 544 | initRefCount++; |
449 | 545 |
|
450 | 546 | return ret; |
451 | | -} |
| 547 | +} /* wolfCrypt_Init */ |
452 | 548 |
|
453 | 549 | #if defined(WOLFSSL_TRACK_MEMORY_VERBOSE) && !defined(WOLFSSL_STATIC_MEMORY) |
454 | 550 | long wolfCrypt_heap_peakAllocs_checkpoint(void) { |
|
0 commit comments