diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 7e61cb972..3edb7ca24 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -461,4 +461,15 @@ int __must_check crypto_mod_exp(const u8 *base, size_t base_len, int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data, size_t data_len); +/** + * crypto_get_random - Generate cryptographically strong pseudy-random bytes + * @buf: Buffer for data + * @len: Number of bytes to generate + * Returns: 0 on success, -1 on failure + * + * If the PRNG does not have enough entropy to ensure unpredictable byte + * sequence, this functions must return -1. + */ +int crypto_get_random(void *buf, size_t len); + #endif /* CRYPTO_H */ diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index ae0a001fa..b49ab1242 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "common.h" #include "wpabuf.h" @@ -738,3 +739,11 @@ int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, { return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); } + + +int crypto_get_random(void *buf, size_t len) +{ + if (RAND_bytes(buf, len) != 1) + return -1; + return 0; +} diff --git a/src/crypto/random.c b/src/crypto/random.c index d85c3e66e..053740e9b 100644 --- a/src/crypto/random.c +++ b/src/crypto/random.c @@ -29,6 +29,7 @@ #include "utils/common.h" #include "utils/eloop.h" +#include "crypto/crypto.h" #include "sha1.h" #include "random.h" @@ -177,6 +178,27 @@ int random_get_bytes(void *buf, size_t len) *bytes++ ^= tmp[i]; left -= siz; } + +#ifdef CONFIG_FIPS + /* Mix in additional entropy from the crypto module */ + left = len; + while (left) { + size_t siz, i; + u8 tmp[EXTRACT_LEN]; + if (crypto_get_random(tmp, sizeof(tmp)) < 0) { + wpa_printf(MSG_ERROR, "random: No entropy available " + "for generating strong random bytes"); + return -1; + } + wpa_hexdump_key(MSG_EXCESSIVE, "random from crypto module", + tmp, sizeof(tmp)); + siz = left > EXTRACT_LEN ? EXTRACT_LEN : left; + for (i = 0; i < siz; i++) + *bytes++ ^= tmp[i]; + left -= siz; + } +#endif /* CONFIG_FIPS */ + wpa_hexdump_key(MSG_EXCESSIVE, "mixed random", buf, len); if (entropy < len) diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index 7ed7fc0a3..25d262dca 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -68,6 +68,10 @@ ifdef CONFIG_DRIVER_NL80211 INCLUDES += external/libnl-headers endif +ifdef CONFIG_FIPS +CONFIG_NO_RANDOM_POOL= +endif + OBJS = config.c OBJS += notify.c OBJS += bss.c diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 8ea615016..7f581dff8 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -55,6 +55,10 @@ $(DESTDIR)$(BINDIR)/%: % install: $(addprefix $(DESTDIR)$(BINDIR)/,$(BINALL)) $(MAKE) -C ../src install +ifdef CONFIG_FIPS +CONFIG_NO_RANDOM_POOL= +endif + OBJS = config.o OBJS += notify.o OBJS += bss.o @@ -1325,6 +1329,9 @@ endif ifdef CONFIG_FIPS CFLAGS += -DCONFIG_FIPS +ifneq ($(CONFIG_TLS), openssl) +$(error CONFIG_FIPS=y requires CONFIG_TLS=openssl) +endif endif OBJS += $(SHA1OBJS) $(DESOBJS)