diff -Naur unbound-1.4.17-orig/config.h.in unbound-1.4.17/config.h.in --- unbound-1.4.17-orig/config.h.in 2012-02-13 05:42:22.000000000 -0500 +++ unbound-1.4.17/config.h.in 2012-07-03 11:08:53.440318529 -0400 @@ -106,6 +106,9 @@ /* Define to 1 if you have the `fcntl' function. */ #undef HAVE_FCNTL +/* Define to 1 if you have the `FIPS_mode' function. */ +#undef HAVE_FIPS_MODE + /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK diff -Naur unbound-1.4.17-orig/configure unbound-1.4.17/configure --- unbound-1.4.17-orig/configure 2012-05-24 04:37:55.000000000 -0400 +++ unbound-1.4.17/configure 2012-07-03 11:08:53.445318575 -0400 @@ -16376,7 +16376,7 @@ done -for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 +for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff -Naur unbound-1.4.17-orig/configure.ac unbound-1.4.17/configure.ac --- unbound-1.4.17-orig/configure.ac 2012-05-15 10:50:21.000000000 -0400 +++ unbound-1.4.17/configure.ac 2012-07-03 11:08:53.447318592 -0400 @@ -515,7 +515,7 @@ ACX_LIB_SSL AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT]) -AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512]) +AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode]) AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free], [], [], [ AC_INCLUDES_DEFAULT #ifdef HAVE_OPENSSL_ERR_H diff -Naur unbound-1.4.17-orig/util/random.c unbound-1.4.17/util/random.c --- unbound-1.4.17-orig/util/random.c 2012-05-09 05:13:57.000000000 -0400 +++ unbound-1.4.17/util/random.c 2012-07-03 11:08:53.440318529 -0400 @@ -140,6 +140,16 @@ return; } } +#ifdef HAVE_FIPS_MODE + if(FIPS_mode()) { + /* RC4 is not allowed, get some trustworthy randomness */ + /* double certainty here, this routine should not be + * called in FIPS_mode */ + memset(rand_buf, 0, sizeof(rand_buf)); + s->rc4_ready = REKEY_BYTES; + return; + } +#endif /* FIPS_MODE */ RC4_set_key(&s->rc4, SEED_SIZE, (unsigned char*)rand_buf); /* @@ -164,6 +174,9 @@ return NULL; } ub_systemseed(seed); +#ifdef HAVE_FIPS_MODE + if(!FIPS_mode()) +#endif ub_arc4random_stir(s, from); return s; } @@ -172,6 +185,20 @@ ub_random(struct ub_randstate* s) { unsigned int r = 0; +#ifdef HAVE_FIPS_MODE + if(FIPS_mode()) { + /* RC4 is not allowed, get some trustworthy randomness */ + /* we use pseudo bytes: it tries to return secure randomness + * but returns 'something' if that fails. We need something + * else if it fails, because we cannot block here */ + if(RAND_pseudo_bytes((unsigned char*)&r, (int)sizeof(r)) + == -1) { + log_err("FIPSmode, no arc4random but RAND failed " + "(error %ld)", ERR_get_error()); + } + return (long int)((r) % (((unsigned)MAX_VALUE + 1))); + } +#endif /* FIPS_MODE */ if (s->rc4_ready <= 0) { ub_arc4random_stir(s, NULL); } diff -Naur unbound-1.4.17-orig/validator/val_sigcrypt.c unbound-1.4.17/validator/val_sigcrypt.c --- unbound-1.4.17-orig/validator/val_sigcrypt.c 2012-02-16 05:08:07.000000000 -0500 +++ unbound-1.4.17/validator/val_sigcrypt.c 2012-07-03 11:15:31.724850996 -0400 @@ -417,11 +417,16 @@ dnskey_algo_id_is_supported(int id) { switch(id) { + case LDNS_RSAMD5: +#ifdef HAVE_FIPS_MODE + return !FIPS_mode(); +#else + return 1; +#endif case LDNS_DSA: case LDNS_DSA_NSEC3: case LDNS_RSASHA1: case LDNS_RSASHA1_NSEC3: - case LDNS_RSAMD5: #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) case LDNS_RSASHA256: #endif