18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Random number generator 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This random number generator is used to provide additional entropy to the 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * one provided by the operating system (os_get_random()) for session key 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * generation. The os_get_random() output is expected to be secure and the 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * implementation here is expected to provide only limited protection against 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cases where os_get_random() cannot provide strong randomness. This 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * implementation shall not be assumed to be secure as the sole source of 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * randomness. The random_get_bytes() function mixes in randomness from 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * os_get_random() and as such, calls to os_get_random() can be replaced with 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * calls to random_get_bytes() without reducing security. 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The design here follows partially the design used in the Linux 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * drivers/char/random.c, but the implementation here is simpler and not as 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * strong. This is a compromise to reduce duplicated CPU effort and to avoid 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * extra code/memory size. As pointed out above, os_get_random() needs to be 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * guaranteed to be secure for any of the security assumptions to hold. 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <fcntl.h> 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 3261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "crypto/crypto.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sha1.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "random.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define POOL_WORDS 32 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define POOL_WORDS_MASK (POOL_WORDS - 1) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define POOL_TAP1 26 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define POOL_TAP2 20 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define POOL_TAP3 14 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define POOL_TAP4 7 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define POOL_TAP5 1 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EXTRACT_LEN 16 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MIN_READY_MARK 2 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u32 pool[POOL_WORDS]; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int input_rotate = 0; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int pool_pos = 0; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 dummy_key[20]; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic size_t dummy_key_avail = 0; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int random_fd = -1; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int own_pool_ready = 0; 5575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#define RANDOM_ENTROPY_SIZE 20 5675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic char *random_entropy_file = NULL; 5775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int random_entropy_file_read = 0; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MIN_COLLECT_ENTROPY 1000 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int entropy = 0; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic unsigned int total_collected = 0; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void random_write_entropy(void); 6575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 6675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u32 __ROL32(u32 x, u32 y) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 69d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt if (y == 0) 70d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt return x; 71d2986c2e737a8441ff5a791b6b56c1c8322ef3c9Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (x << (y & 31)) | (x >> (32 - (y & 31))); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void random_mix_pool(const void *buf, size_t len) 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static const u32 twist[8] = { 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = buf; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 w; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random_mix_pool", buf, len); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (len--) { 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w = __ROL32(*pos++, input_rotate & 31); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt input_rotate += pool_pos ? 7 : 14; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pool_pos = (pool_pos - 1) & POOL_WORDS_MASK; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[pool_pos]; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP1) & POOL_WORDS_MASK]; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP2) & POOL_WORDS_MASK]; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP3) & POOL_WORDS_MASK]; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP4) & POOL_WORDS_MASK]; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP5) & POOL_WORDS_MASK]; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pool[pool_pos] = (w >> 3) ^ twist[w & 7]; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void random_extract(u8 *out) 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[SHA1_MAC_LEN]; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 *hash_ptr; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 buf[POOL_WORDS / 2]; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* First, add hash back to pool to make backtracking more difficult. */ 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) pool, 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(pool), hash); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_mix_pool(hash, sizeof(hash)); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Hash half the pool to extra data */ 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < POOL_WORDS / 2; i++) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = pool[(pool_pos - i) & POOL_WORDS_MASK]; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) buf, 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf), hash); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fold the hash to further reduce any potential output pattern. 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Though, compromise this to reduce CPU use for the most common output 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * length (32) and return 16 bytes from instead of only half. 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_ptr = (u32 *) hash; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_ptr[0] ^= hash_ptr[4]; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(out, hash, EXTRACT_LEN); 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid random_add_randomness(const void *buf, size_t len) 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time t; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static unsigned int count = 0; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entropy > MIN_COLLECT_ENTROPY && (count & 0x3ff) != 0) { 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No need to add more entropy at this point, so save CPU and 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * skip the update. 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, "Add randomness: count=%u entropy=%u", 14304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt count, entropy); 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&t); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random pool", 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) pool, sizeof(pool)); 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_mix_pool(&t, sizeof(t)); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_mix_pool(buf, len); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random pool", 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) pool, sizeof(pool)); 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entropy++; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt total_collected++; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint random_get_bytes(void *buf, size_t len) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *bytes = buf; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Get randomness: len=%u entropy=%u", 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) len, entropy); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start with assumed strong randomness from OS */ 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_get_random(buf, len); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random from os_get_random", 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Mix in additional entropy extracted from the internal pool */ 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (left) { 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t siz, i; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 tmp[EXTRACT_LEN]; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_extract(tmp); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random from internal pool", 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp, sizeof(tmp)); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt siz = left > EXTRACT_LEN ? EXTRACT_LEN : left; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < siz; i++) 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *bytes++ ^= tmp[i]; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= siz; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_FIPS 18661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Mix in additional entropy from the crypto module */ 187d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt bytes = buf; 18861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt left = len; 18961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (left) { 19061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t siz, i; 19161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 tmp[EXTRACT_LEN]; 19261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (crypto_get_random(tmp, sizeof(tmp)) < 0) { 19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "random: No entropy available " 19461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for generating strong random bytes"); 19561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 19661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random from crypto module", 19861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp, sizeof(tmp)); 19961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt siz = left > EXTRACT_LEN ? EXTRACT_LEN : left; 20061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < siz; i++) 20161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *bytes++ ^= tmp[i]; 20261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt left -= siz; 20361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 20461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_FIPS */ 20561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "mixed random", buf, len); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entropy < len) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entropy = 0; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entropy -= len; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint random_pool_ready(void) 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int fd; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssize_t res; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure that there is reasonable entropy available before allowing 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * some key derivation operations to proceed. 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dummy_key_avail == sizeof(dummy_key)) 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Already initialized - good to continue */ 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Try to fetch some more data from the kernel high quality 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * /dev/random. There may not be enough data available at this point, 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so use non-blocking read to avoid blocking the application 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * completely. 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fd = open("/dev/random", O_RDONLY | O_NONBLOCK); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fd < 0) { 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s", 240fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt strerror(errno)); 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = read(fd, dummy_key + dummy_key_avail, 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dummy_key) - dummy_key_avail); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: " 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", strerror(errno)); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = 0; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from " 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "/dev/random", (unsigned) res, 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) (sizeof(dummy_key) - dummy_key_avail)); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dummy_key_avail += res; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(fd); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (dummy_key_avail == sizeof(dummy_key)) { 25875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (own_pool_ready < MIN_READY_MARK) 25975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen own_pool_ready = MIN_READY_MARK; 26075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_write_entropy(); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 26275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "random: Only %u/%u bytes of strong " 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "random data available from /dev/random", 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) dummy_key_avail, (unsigned) sizeof(dummy_key)); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (own_pool_ready >= MIN_READY_MARK || 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt total_collected + 10 * own_pool_ready > MIN_COLLECT_ENTROPY) { 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "random: Allow operation to proceed " 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "based on internal entropy"); 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "random: Not enough entropy pool available for " 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "secure operations"); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* __linux__ */ 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: could do similar checks on non-Linux platforms */ 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid random_mark_pool_ready(void) 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt own_pool_ready++; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "random: Mark internal entropy pool to be " 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ready (count=%u/%u)", own_pool_ready, MIN_READY_MARK); 29075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_write_entropy(); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void random_close_fd(void) 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_fd >= 0) { 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_read_sock(random_fd); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt close(random_fd); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_fd = -1; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void random_read_fd(int sock, void *eloop_ctx, void *sock_ctx) 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssize_t res; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dummy_key_avail == sizeof(dummy_key)) { 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_close_fd(); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = read(sock, dummy_key + dummy_key_avail, 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dummy_key) - dummy_key_avail); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: " 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", strerror(errno)); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from /dev/random", 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) res, 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned) (sizeof(dummy_key) - dummy_key_avail)); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dummy_key_avail += res; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (dummy_key_avail == sizeof(dummy_key)) { 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_close_fd(); 33075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (own_pool_ready < MIN_READY_MARK) 33175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen own_pool_ready = MIN_READY_MARK; 33275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_write_entropy(); 33375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void random_read_entropy(void) 34075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 34175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen char *buf; 34275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen size_t len; 34375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!random_entropy_file) 34575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 34675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 34775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen buf = os_readfile(random_entropy_file, &len); 34875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (buf == NULL) 34975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; /* entropy file not yet available */ 35075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 35175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (len != 1 + RANDOM_ENTROPY_SIZE) { 35275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "random: Invalid entropy file %s", 35375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file); 35475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_free(buf); 35575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 35675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 35775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 35875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen own_pool_ready = (u8) buf[0]; 35975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_add_randomness(buf + 1, RANDOM_ENTROPY_SIZE); 36075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file_read = 1; 36175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_free(buf); 36275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "random: Added entropy from %s " 36375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "(own_pool_ready=%u)", 36475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file, own_pool_ready); 36575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 36675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 36775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 36875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void random_write_entropy(void) 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 37075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen char buf[RANDOM_ENTROPY_SIZE]; 37175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen FILE *f; 37275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen u8 opr; 3731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int fail = 0; 37475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 37575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (!random_entropy_file) 37675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 37775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (random_get_bytes(buf, RANDOM_ENTROPY_SIZE) < 0) 3791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 38075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 38175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen f = fopen(random_entropy_file, "wb"); 38275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (f == NULL) { 3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "random: Could not open entropy file %s " 3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "for writing", random_entropy_file); 38575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 38675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 38775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 38875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen opr = own_pool_ready > 0xff ? 0xff : own_pool_ready; 3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (fwrite(&opr, 1, 1, f) != 1 || 3901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fwrite(buf, RANDOM_ENTROPY_SIZE, 1, f) != 1) 3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fail = 1; 39275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen fclose(f); 3931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (fail) { 3941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "random: Could not write entropy data " 3951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "to %s", random_entropy_file); 3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 39875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 39975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "random: Updated entropy file %s " 40075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "(own_pool_ready=%u)", 40175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file, own_pool_ready); 40275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 40375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 40475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 40575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid random_init(const char *entropy_file) 40675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 40775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_free(random_entropy_file); 40875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (entropy_file) 40975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file = os_strdup(entropy_file); 41075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen else 41175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file = NULL; 41275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_read_entropy(); 41375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_fd >= 0) 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_fd = open("/dev/random", O_RDONLY | O_NONBLOCK); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (random_fd < 0) { 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s", 421fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt strerror(errno)); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "random: Trying to read entropy from " 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "/dev/random"); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(random_fd, random_read_fd, NULL, NULL); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 42975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 43075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_write_entropy(); 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid random_deinit(void) 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_close_fd(); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 43975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_write_entropy(); 44075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_free(random_entropy_file); 44175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file = NULL; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 443