FIPS: Mix in OpenSSL RAND_bytes() into random_get_bytes()
authorJouni Malinen <j@w1.fi>
Thu, 16 Aug 2012 18:49:41 +0000 (21:49 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 16 Aug 2012 18:49:41 +0000 (21:49 +0300)
Make sure that the OpenSSL DRBG gets used when generating
random numbers in FIPS mode.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/crypto/crypto.h
src/crypto/crypto_openssl.c
src/crypto/random.c
wpa_supplicant/Android.mk
wpa_supplicant/Makefile

index 7e61cb9..3edb7ca 100644 (file)
@@ -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 */
index ae0a001..b49ab12 100644 (file)
@@ -15,6 +15,7 @@
 #include <openssl/evp.h>
 #include <openssl/dh.h>
 #include <openssl/hmac.h>
+#include <openssl/rand.h>
 
 #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;
+}
index d85c3e6..053740e 100644 (file)
@@ -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)
index 7ed7fc0..25d262d 100644 (file)
@@ -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
index 8ea6150..7f581df 100644 (file)
@@ -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)