1 /* random.h 2 * 3 * Copyright (C) 2006-2021 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 2 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 defined(HAVE_FIPS) && \ 34 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 35 #include <wolfssl/wolfcrypt/fips.h> 36 #endif /* HAVE_FIPS_VERSION >= 2 */ 37 38 /* included for fips @wc_fips */ 39 #if defined(HAVE_FIPS) && \ 40 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) 41 #include <cyassl/ctaocrypt/random.h> 42 #endif 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 /* Maximum generate block length */ 49 #ifndef RNG_MAX_BLOCK_LEN 50 #ifdef HAVE_INTEL_QA 51 #define RNG_MAX_BLOCK_LEN (0xFFFFl) 52 #else 53 #define RNG_MAX_BLOCK_LEN (0x10000l) 54 #endif 55 #endif 56 57 /* Size of the BRBG seed */ 58 #ifndef DRBG_SEED_LEN 59 #define DRBG_SEED_LEN (440/8) 60 #endif 61 62 63 #if !defined(CUSTOM_RAND_TYPE) 64 /* To maintain compatibility the default is byte */ 65 #define CUSTOM_RAND_TYPE byte 66 #endif 67 68 /* make sure Hash DRBG is enabled, unless WC_NO_HASHDRBG is defined 69 or CUSTOM_RAND_GENERATE_BLOCK is defined */ 70 #if !defined(WC_NO_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) 71 #undef HAVE_HASHDRBG 72 #define HAVE_HASHDRBG 73 #ifndef WC_RESEED_INTERVAL 74 #define WC_RESEED_INTERVAL (1000000) 75 #endif 76 #endif 77 78 79 /* avoid redefinition of structs */ 80 #if !defined(HAVE_FIPS) || \ 81 (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)) 82 83 /* RNG supports the following sources (in order): 84 * 1. CUSTOM_RAND_GENERATE_BLOCK: Defines name of function as RNG source and 85 * bypasses the options below. 86 * 2. HAVE_INTEL_RDRAND: Uses the Intel RDRAND if supported by CPU. 87 * 3. HAVE_HASHDRBG (requires SHA256 enabled): Uses SHA256 based P-RNG 88 * seeded via wc_GenerateSeed. This is the default source. 89 */ 90 91 /* Seed source can be overridden by defining one of these: 92 CUSTOM_RAND_GENERATE_SEED 93 CUSTOM_RAND_GENERATE_SEED_OS 94 CUSTOM_RAND_GENERATE */ 95 96 97 #if defined(CUSTOM_RAND_GENERATE_BLOCK) 98 /* To use define the following: 99 * #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc 100 * extern int myRngFunc(byte* output, word32 sz); 101 */ 102 #elif defined(HAVE_HASHDRBG) 103 #ifdef NO_SHA256 104 #error "Hash DRBG requires SHA-256." 105 #endif /* NO_SHA256 */ 106 #include <wolfssl/wolfcrypt/sha256.h> 107 #elif defined(HAVE_WNR) 108 /* allow whitewood as direct RNG source using wc_GenerateSeed directly */ 109 #elif defined(HAVE_INTEL_RDRAND) 110 /* Intel RDRAND or RDSEED */ 111 #elif !defined(WC_NO_RNG) 112 #error No RNG source defined! 113 #endif 114 115 #ifdef HAVE_WNR 116 #include <wnr.h> 117 #endif 118 119 #ifdef WOLFSSL_ASYNC_CRYPT 120 #include <wolfssl/wolfcrypt/async.h> 121 #endif 122 123 124 #if defined(USE_WINDOWS_API) 125 #if defined(_WIN64) 126 typedef unsigned __int64 ProviderHandle; 127 /* type HCRYPTPROV, avoid #include <windows.h> */ 128 #else 129 typedef unsigned long ProviderHandle; 130 #endif 131 #endif 132 133 #ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */ 134 typedef struct OS_Seed OS_Seed; 135 typedef struct WC_RNG WC_RNG; 136 #ifdef WC_RNG_SEED_CB 137 typedef int (*wc_RngSeed_Cb)(OS_Seed* os, byte* seed, word32 sz); 138 #endif 139 #define WC_RNG_TYPE_DEFINED 140 #endif 141 142 /* OS specific seeder */ 143 struct OS_Seed { 144 #if defined(USE_WINDOWS_API) 145 ProviderHandle handle; 146 #else 147 int fd; 148 #endif 149 #if defined(WOLF_CRYPTO_CB) 150 int devId; 151 #endif 152 }; 153 154 #ifdef HAVE_HASHDRBG 155 struct DRBG_internal { 156 word32 reseedCtr; 157 word32 lastBlock; 158 byte V[DRBG_SEED_LEN]; 159 byte C[DRBG_SEED_LEN]; 160 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) 161 void* heap; 162 int devId; 163 #endif 164 byte matchCount; 165 #ifdef WOLFSSL_SMALL_STACK_CACHE 166 wc_Sha256 sha256; 167 #endif 168 }; 169 #endif 170 171 /* RNG context */ 172 struct WC_RNG { 173 struct OS_Seed seed; 174 void* heap; 175 #ifdef HAVE_HASHDRBG 176 /* Hash-based Deterministic Random Bit Generator */ 177 struct DRBG* drbg; 178 #if defined(WOLFSSL_NO_MALLOC) && !defined(WOLFSSL_STATIC_MEMORY) 179 struct DRBG_internal drbg_data; 180 #endif 181 byte status; 182 #endif 183 #ifdef WOLFSSL_ASYNC_CRYPT 184 WC_ASYNC_DEV asyncDev; 185 #endif 186 #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) 187 int devId; 188 #endif 189 }; 190 191 #endif /* NO FIPS or have FIPS v2*/ 192 193 /* NO_OLD_RNGNAME removes RNG struct name to prevent possible type conflicts, 194 * can't be used with CTaoCrypt FIPS */ 195 #if !defined(NO_OLD_RNGNAME) && !defined(HAVE_FIPS) 196 #define RNG WC_RNG 197 #endif 198 199 WOLFSSL_API int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz); 200 201 202 #ifdef HAVE_WNR 203 /* Whitewood netRandom client library */ 204 WOLFSSL_API int wc_InitNetRandom(const char*, wnr_hmac_key, int); 205 WOLFSSL_API int wc_FreeNetRandom(void); 206 #endif /* HAVE_WNR */ 207 208 209 WOLFSSL_ABI WOLFSSL_API WC_RNG* wc_rng_new(byte*, word32, void*); 210 WOLFSSL_ABI WOLFSSL_API void wc_rng_free(WC_RNG*); 211 212 213 #ifndef WC_NO_RNG 214 WOLFSSL_API int wc_InitRng(WC_RNG*); 215 WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId); 216 WOLFSSL_API int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz); 217 WOLFSSL_API int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, 218 void* heap, int devId); 219 WOLFSSL_ABI WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz); 220 WOLFSSL_API int wc_RNG_GenerateByte(WC_RNG*, byte*); 221 WOLFSSL_API int wc_FreeRng(WC_RNG*); 222 #else 223 #include <wolfssl/wolfcrypt/error-crypt.h> 224 #define wc_InitRng(rng) NOT_COMPILED_IN 225 #define wc_InitRng_ex(rng, h, d) NOT_COMPILED_IN 226 #define wc_InitRngNonce(rng, n, s) NOT_COMPILED_IN 227 #define wc_InitRngNonce_ex(rng, n, s, h, d) NOT_COMPILED_IN 228 #if defined(__ghs__) || defined(WC_NO_RNG_SIMPLE) 229 /* some older compilers do not like macro function in expression */ 230 #define wc_RNG_GenerateBlock(rng, b, s) NOT_COMPILED_IN 231 #else 232 #define wc_RNG_GenerateBlock(rng, b, s) ({(void)rng; (void)b; (void)s; NOT_COMPILED_IN;}) 233 #endif 234 #define wc_RNG_GenerateByte(rng, b) NOT_COMPILED_IN 235 #define wc_FreeRng(rng) (void)NOT_COMPILED_IN 236 #endif 237 238 #ifdef WC_RNG_SEED_CB 239 WOLFSSL_API int wc_SetSeed_Cb(wc_RngSeed_Cb cb); 240 #endif 241 242 #ifdef HAVE_HASHDRBG 243 WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, 244 word32 entropySz); 245 WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz); 246 WOLFSSL_API int wc_RNG_HealthTest(int reseed, 247 const byte* entropyA, word32 entropyASz, 248 const byte* entropyB, word32 entropyBSz, 249 byte* output, word32 outputSz); 250 WOLFSSL_API int wc_RNG_HealthTest_ex(int reseed, 251 const byte* nonce, word32 nonceSz, 252 const byte* entropyA, word32 entropyASz, 253 const byte* entropyB, word32 entropyBSz, 254 byte* output, word32 outputSz, 255 void* heap, int devId); 256 #endif /* HAVE_HASHDRBG */ 257 258 #ifdef __cplusplus 259 } /* extern "C" */ 260 #endif 261 262 #endif /* WOLF_CRYPT_RANDOM_H */ 263 264