random.h (9157B)
1 /* random.h 2 * 3 * Copyright (C) 2006-2025 wolfSSL Inc. 4 * 5 * This file is part of wolfSSL. 6 * 7 * wolfSSL is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * wolfSSL is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 20 */ 21 22 /*! 23 \file wolfssl/wolfcrypt/random.h 24 */ 25 26 27 28 #ifndef WOLF_CRYPT_RANDOM_H 29 #define WOLF_CRYPT_RANDOM_H 30 31 #include <wolfssl/wolfcrypt/types.h> 32 33 #if FIPS_VERSION3_GE(2,0,0) 34 #include <wolfssl/wolfcrypt/fips.h> 35 #endif /* HAVE_FIPS_VERSION >= 2 */ 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 #if FIPS_VERSION3_GE(6,0,0) 42 extern const unsigned int wolfCrypt_FIPS_drbg_ro_sanity[2]; 43 WOLFSSL_LOCAL int wolfCrypt_FIPS_DRBG_sanity(void); 44 #endif 45 46 /* Maximum generate block length */ 47 #ifndef RNG_MAX_BLOCK_LEN 48 #ifdef HAVE_INTEL_QA 49 #define RNG_MAX_BLOCK_LEN (0xFFFFl) 50 #else 51 #define RNG_MAX_BLOCK_LEN (0x10000l) 52 #endif 53 #endif 54 55 /* Size of the BRBG seed */ 56 #ifndef DRBG_SEED_LEN 57 #define DRBG_SEED_LEN (440/8) 58 #endif 59 60 61 #if !defined(CUSTOM_RAND_TYPE) 62 /* To maintain compatibility the default is byte */ 63 #define CUSTOM_RAND_TYPE byte 64 #endif 65 66 /* make sure Hash DRBG is enabled, unless WC_NO_HASHDRBG is defined 67 or CUSTOM_RAND_GENERATE_BLOCK is defined */ 68 #if !defined(WC_NO_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) 69 #undef HAVE_HASHDRBG 70 #define HAVE_HASHDRBG 71 #ifndef WC_RESEED_INTERVAL 72 #define WC_RESEED_INTERVAL (1000000) 73 #endif 74 #endif 75 76 77 /* avoid redefinition of structs */ 78 #if !defined(HAVE_FIPS) || \ 79 (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) 80 81 /* RNG supports the following sources (in order): 82 * 1. CUSTOM_RAND_GENERATE_BLOCK: Defines name of function as RNG source and 83 * bypasses the options below. 84 * 2. HAVE_INTEL_RDRAND: Uses the Intel RDRAND if supported by CPU. 85 * 3. HAVE_HASHDRBG (requires SHA256 enabled): Uses SHA256 based P-RNG 86 * seeded via wc_GenerateSeed. This is the default source. 87 */ 88 89 /* Seed source can be overridden by defining one of these: 90 CUSTOM_RAND_GENERATE_SEED 91 CUSTOM_RAND_GENERATE_SEED_OS 92 CUSTOM_RAND_GENERATE */ 93 94 95 #if defined(CUSTOM_RAND_GENERATE_BLOCK) 96 /* To use define the following: 97 * #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc 98 * extern int myRngFunc(byte* output, word32 sz); 99 */ 100 #if defined(CUSTOM_RAND_GENERATE_BLOCK) && defined(WOLFSSL_KCAPI) 101 #undef CUSTOM_RAND_GENERATE_BLOCK 102 #define CUSTOM_RAND_GENERATE_BLOCK wc_hwrng_generate_block 103 WOLFSSL_LOCAL int wc_hwrng_generate_block(byte *output, word32 sz); 104 #endif 105 #elif defined(HAVE_HASHDRBG) 106 #ifdef NO_SHA256 107 #error "Hash DRBG requires SHA-256." 108 #endif /* NO_SHA256 */ 109 #include <wolfssl/wolfcrypt/sha256.h> 110 #elif defined(HAVE_WNR) 111 /* allow whitewood as direct RNG source using wc_GenerateSeed directly */ 112 #elif defined(HAVE_INTEL_RDRAND) 113 /* Intel RDRAND or RDSEED */ 114 #elif defined(WOLF_CRYPTO_CB) 115 /* Requires registered Crypto Callback to service RNG, with devId set */ 116 #elif !defined(WC_NO_RNG) 117 #error No RNG source defined! 118 #endif 119 120 #ifdef HAVE_WNR 121 #include <wnr.h> 122 #endif 123 124 #ifdef WOLFSSL_ASYNC_CRYPT 125 #include <wolfssl/wolfcrypt/async.h> 126 #endif 127 128 129 #if defined(USE_WINDOWS_API) 130 #if defined(_WIN64) 131 typedef unsigned __int64 ProviderHandle; 132 /* type HCRYPTPROV, avoid #include <windows.h> */ 133 #else 134 typedef unsigned long ProviderHandle; 135 #endif 136 137 #ifdef WIN_REUSE_CRYPT_HANDLE 138 /* called from wolfCrypt_Init() and wolfCrypt_Cleanup() */ 139 WOLFSSL_LOCAL int wc_WinCryptHandleInit(void); 140 WOLFSSL_LOCAL void wc_WinCryptHandleCleanup(void); 141 #endif 142 #endif 143 144 #ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */ 145 typedef struct OS_Seed OS_Seed; 146 typedef struct WC_RNG WC_RNG; 147 #ifdef WC_RNG_SEED_CB 148 typedef int (*wc_RngSeed_Cb)(OS_Seed* os, byte* seed, word32 sz); 149 #endif 150 #define WC_RNG_TYPE_DEFINED 151 #endif 152 153 /* OS specific seeder */ 154 struct OS_Seed { 155 #if defined(USE_WINDOWS_API) 156 ProviderHandle handle; 157 #else 158 int fd; 159 #endif 160 #if defined(WOLF_CRYPTO_CB) 161 int devId; 162 #endif 163 }; 164 165 #ifdef HAVE_HASHDRBG 166 struct DRBG_internal { 167 #ifdef WORD64_AVAILABLE 168 word64 reseedCtr; 169 #else 170 word32 reseedCtr; 171 #endif 172 byte V[DRBG_SEED_LEN]; 173 byte C[DRBG_SEED_LEN]; 174 void* heap; 175 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) 176 int devId; 177 #endif 178 #ifdef WOLFSSL_SMALL_STACK_CACHE 179 wc_Sha256 sha256; 180 #endif 181 }; 182 #endif 183 184 /* RNG context */ 185 struct WC_RNG { 186 struct OS_Seed seed; 187 void* heap; 188 #ifdef HAVE_HASHDRBG 189 /* Hash-based Deterministic Random Bit Generator */ 190 struct DRBG* drbg; 191 #if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY) 192 struct DRBG_internal drbg_data; 193 #endif 194 byte status; 195 #endif 196 #if defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) 197 pid_t pid; 198 #endif 199 #ifdef WOLFSSL_ASYNC_CRYPT 200 WC_ASYNC_DEV asyncDev; 201 #endif 202 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) 203 int devId; 204 #endif 205 }; 206 207 #endif /* NO FIPS or have FIPS v2*/ 208 209 /* NO_OLD_RNGNAME removes RNG struct name to prevent possible type conflicts, 210 * can't be used with CTaoCrypt FIPS */ 211 #if !defined(NO_OLD_RNGNAME) && !defined(HAVE_FIPS) 212 #define RNG WC_RNG 213 #endif 214 215 WOLFSSL_API int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz); 216 217 218 #ifdef HAVE_WNR 219 /* Whitewood netRandom client library */ 220 WOLFSSL_API int wc_InitNetRandom(const char*, wnr_hmac_key, int); 221 WOLFSSL_API int wc_FreeNetRandom(void); 222 #endif /* HAVE_WNR */ 223 224 225 WOLFSSL_ABI WOLFSSL_API WC_RNG* wc_rng_new(byte* nonce, word32 nonceSz, 226 void* heap); 227 WOLFSSL_API int wc_rng_new_ex(WC_RNG **rng, byte* nonce, word32 nonceSz, 228 void* heap, int devId); 229 WOLFSSL_ABI WOLFSSL_API void wc_rng_free(WC_RNG* rng); 230 231 232 #ifndef WC_NO_RNG 233 WOLFSSL_ABI WOLFSSL_API int wc_InitRng(WC_RNG* rng); 234 WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId); 235 WOLFSSL_API int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz); 236 WOLFSSL_API int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, 237 void* heap, int devId); 238 WOLFSSL_ABI WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG* rng, byte* b, word32 sz); 239 WOLFSSL_API int wc_RNG_GenerateByte(WC_RNG* rng, byte* b); 240 WOLFSSL_API int wc_FreeRng(WC_RNG* rng); 241 #else 242 #include <wolfssl/wolfcrypt/error-crypt.h> 243 #define wc_InitRng(rng) NOT_COMPILED_IN 244 #define wc_InitRng_ex(rng, h, d) NOT_COMPILED_IN 245 #define wc_InitRngNonce(rng, n, s) NOT_COMPILED_IN 246 #define wc_InitRngNonce_ex(rng, n, s, h, d) NOT_COMPILED_IN 247 #if defined(__ghs__) || defined(WC_NO_RNG_SIMPLE) 248 /* some older compilers do not like macro function in expression */ 249 #define wc_RNG_GenerateBlock(rng, b, s) NOT_COMPILED_IN 250 #else 251 #define wc_RNG_GenerateBlock(rng, b, s) ({(void)rng; (void)b; (void)s; NOT_COMPILED_IN;}) 252 #endif 253 #define wc_RNG_GenerateByte(rng, b) NOT_COMPILED_IN 254 #define wc_FreeRng(rng) (void)NOT_COMPILED_IN 255 #endif 256 257 #ifdef WC_RNG_SEED_CB 258 WOLFSSL_API int wc_SetSeed_Cb(wc_RngSeed_Cb cb); 259 #endif 260 261 #ifdef HAVE_HASHDRBG 262 WOLFSSL_API int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, 263 word32 entropySz); 264 WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz); 265 WOLFSSL_API int wc_RNG_HealthTest(int reseed, 266 const byte* entropyA, word32 entropyASz, 267 const byte* entropyB, word32 entropyBSz, 268 byte* output, word32 outputSz); 269 WOLFSSL_API int wc_RNG_HealthTest_ex(int reseed, 270 const byte* nonce, word32 nonceSz, 271 const byte* entropyA, word32 entropyASz, 272 const byte* entropyB, word32 entropyBSz, 273 byte* output, word32 outputSz, 274 void* heap, int devId); 275 #endif /* HAVE_HASHDRBG */ 276 277 #ifdef HAVE_ENTROPY_MEMUSE 278 /* Maximum entropy bits that can be produced. */ 279 #define MAX_ENTROPY_BITS 256 280 281 /* For generating data for assessment. */ 282 WOLFSSL_API int wc_Entropy_GetRawEntropy(unsigned char* raw, int cnt); 283 WOLFSSL_API int wc_Entropy_Get(int bits, unsigned char* entropy, word32 len); 284 WOLFSSL_API int wc_Entropy_OnDemandTest(void); 285 286 WOLFSSL_LOCAL int Entropy_Init(void); 287 WOLFSSL_LOCAL void Entropy_Final(void); 288 #endif 289 290 #ifdef __cplusplus 291 } /* extern "C" */ 292 #endif 293 294 #endif /* WOLF_CRYPT_RANDOM_H */ 295