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{ 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (x << (y & 31)) | (x >> (32 - (y & 31))); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void random_mix_pool(const void *buf, size_t len) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static const u32 twist[8] = { 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = buf; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 w; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random_mix_pool", buf, len); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (len--) { 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w = __ROL32(*pos++, input_rotate & 31); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt input_rotate += pool_pos ? 7 : 14; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pool_pos = (pool_pos - 1) & POOL_WORDS_MASK; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[pool_pos]; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP1) & POOL_WORDS_MASK]; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP2) & POOL_WORDS_MASK]; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP3) & POOL_WORDS_MASK]; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP4) & POOL_WORDS_MASK]; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt w ^= pool[(pool_pos + POOL_TAP5) & POOL_WORDS_MASK]; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pool[pool_pos] = (w >> 3) ^ twist[w & 7]; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void random_extract(u8 *out) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 hash[SHA1_MAC_LEN]; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 *hash_ptr; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 buf[POOL_WORDS / 2]; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* First, add hash back to pool to make backtracking more difficult. */ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) pool, 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(pool), hash); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_mix_pool(hash, sizeof(hash)); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Hash half the pool to extra data */ 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < POOL_WORDS / 2; i++) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = pool[(pool_pos - i) & POOL_WORDS_MASK]; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_sha1(dummy_key, sizeof(dummy_key), (const u8 *) buf, 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf), hash); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fold the hash to further reduce any potential output pattern. 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Though, compromise this to reduce CPU use for the most common output 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * length (32) and return 16 bytes from instead of only half. 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_ptr = (u32 *) hash; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_ptr[0] ^= hash_ptr[4]; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(out, hash, EXTRACT_LEN); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid random_add_randomness(const void *buf, size_t len) 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time t; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static unsigned int count = 0; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entropy > MIN_COLLECT_ENTROPY && (count & 0x3ff) != 0) { 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No need to add more entropy at this point, so save CPU and 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * skip the update. 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, "Add randomness: count=%u entropy=%u", 14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt count, entropy); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&t); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random pool", 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) pool, sizeof(pool)); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_mix_pool(&t, sizeof(t)); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_mix_pool(buf, len); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random pool", 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) pool, sizeof(pool)); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entropy++; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt total_collected++; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint random_get_bytes(void *buf, size_t len) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *bytes = buf; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Get randomness: len=%u entropy=%u", 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) len, entropy); 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start with assumed strong randomness from OS */ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_get_random(buf, len); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random from os_get_random", 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, len); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Mix in additional entropy extracted from the internal pool */ 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (left) { 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t siz, i; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 tmp[EXTRACT_LEN]; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_extract(tmp); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random from internal pool", 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp, sizeof(tmp)); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt siz = left > EXTRACT_LEN ? EXTRACT_LEN : left; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < siz; i++) 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *bytes++ ^= tmp[i]; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= siz; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_FIPS 18361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Mix in additional entropy from the crypto module */ 18461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt left = len; 18561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (left) { 18661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t siz, i; 18761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 tmp[EXTRACT_LEN]; 18861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (crypto_get_random(tmp, sizeof(tmp)) < 0) { 18961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "random: No entropy available " 19061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for generating strong random bytes"); 19161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 19261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "random from crypto module", 19461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tmp, sizeof(tmp)); 19561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt siz = left > EXTRACT_LEN ? EXTRACT_LEN : left; 19661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < siz; i++) 19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *bytes++ ^= tmp[i]; 19861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt left -= siz; 19961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 20061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_FIPS */ 20161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_EXCESSIVE, "mixed random", buf, len); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entropy < len) 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entropy = 0; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entropy -= len; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint random_pool_ready(void) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int fd; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssize_t res; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure that there is reasonable entropy available before allowing 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * some key derivation operations to proceed. 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dummy_key_avail == sizeof(dummy_key)) 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; /* Already initialized - good to continue */ 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Try to fetch some more data from the kernel high quality 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * /dev/random. There may not be enough data available at this point, 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so use non-blocking read to avoid blocking the application 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * completely. 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fd = open("/dev/random", O_RDONLY | O_NONBLOCK); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (fd < 0) { 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int error = errno; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("open(/dev/random)"); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s", 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(error)); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 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#ifndef CONFIG_NO_STDOUT_DEBUG 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int error = errno; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("open(/dev/random)"); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s", 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(error)); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "random: Trying to read entropy from " 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "/dev/random"); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_read_sock(random_fd, random_read_fd, NULL, NULL); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 43375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 43475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_write_entropy(); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid random_deinit(void) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__ 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_close_fd(); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */ 44375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_write_entropy(); 44475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_free(random_entropy_file); 44575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_entropy_file = NULL; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 447