From ad237d19e6e27391028428e945cfe6775490845e Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Nov 19 2013 13:52:30 +0000 Subject: fix locking and reseeding problems with FIPS drbg --- diff --git a/openssl-1.0.1e-new-fips-reqs.patch b/openssl-1.0.1e-new-fips-reqs.patch index b4b9a1a..cdc042b 100644 --- a/openssl-1.0.1e-new-fips-reqs.patch +++ b/openssl-1.0.1e-new-fips-reqs.patch @@ -1,6 +1,57 @@ +diff -up openssl-1.0.1e/crypto/fips/fips_drbg_rand.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_drbg_rand.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_rand.c.fips-reqs 2013-11-15 16:54:49.000000000 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_rand.c 2013-11-19 14:48:38.935251819 +0100 +@@ -77,7 +77,8 @@ static int fips_drbg_bytes(unsigned char + int rv = 0; + unsigned char *adin = NULL; + size_t adinlen = 0; +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ int locked; ++ locked = private_RAND_lock(1); + do + { + size_t rcnt; +@@ -109,7 +110,8 @@ static int fips_drbg_bytes(unsigned char + while (count); + rv = 1; + err: +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + return rv; + } + +@@ -141,8 +143,13 @@ static void fips_drbg_cleanup(void) + static int fips_drbg_seed(const void *seed, int seedlen) + { + DRBG_CTX *dctx = &ossl_dctx; ++ int locked; ++ ++ locked = private_RAND_lock(1); + if (dctx->rand_seed_cb) + return dctx->rand_seed_cb(dctx, seed, seedlen); ++ if (locked) ++ private_RAND_lock(0); + return 1; + } + +@@ -150,8 +157,13 @@ static int fips_drbg_add(const void *see + double add_entropy) + { + DRBG_CTX *dctx = &ossl_dctx; ++ int locked; ++ ++ locked = private_RAND_lock(1); + if (dctx->rand_add_cb) + return dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); ++ if (locked) ++ private_RAND_lock(0); + return 1; + } + diff -up openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c ---- openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c.fips-reqs 2013-11-15 16:38:18.378484894 +0100 -+++ openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c 2013-11-15 16:54:19.584570380 +0100 +--- openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c.fips-reqs 2013-11-15 16:54:49.390224209 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c 2013-11-15 16:54:49.427225021 +0100 @@ -340,6 +340,42 @@ static const unsigned char kat_RSA_X931_ 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3 }; @@ -72,7 +123,7 @@ diff -up openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c.fips-reqs openssl-1.0.1e } diff -up openssl-1.0.1e/crypto/modes/gcm128.c.fips-reqs openssl-1.0.1e/crypto/modes/gcm128.c --- openssl-1.0.1e/crypto/modes/gcm128.c.fips-reqs 2013-02-11 16:26:04.000000000 +0100 -+++ openssl-1.0.1e/crypto/modes/gcm128.c 2013-11-15 16:38:18.417485749 +0100 ++++ openssl-1.0.1e/crypto/modes/gcm128.c 2013-11-15 16:54:49.427225021 +0100 @@ -898,6 +898,10 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT # endif #endif @@ -96,8 +147,8 @@ diff -up openssl-1.0.1e/crypto/modes/gcm128.c.fips-reqs openssl-1.0.1e/crypto/mo if (mlen>((U64(1)<<36)-32) || (sizeof(len)==8 && mlen 0); + +- if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + + EVP_MD_CTX_init(&m); + for (i=0; i 0) + { +@@ -515,10 +494,11 @@ static int ssleay_rand_bytes(unsigned ch + MD_Init(&m); + MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); + MD_Update(&m,local_md,MD_DIGEST_LENGTH); +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ locked = private_RAND_lock(1); + MD_Update(&m,md,MD_DIGEST_LENGTH); + MD_Final(&m,md); +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + + EVP_MD_CTX_cleanup(&m); + if (ok) +@@ -548,32 +528,10 @@ static int ssleay_rand_pseudo_bytes(unsi + + static int ssleay_rand_status(void) + { +- CRYPTO_THREADID cur; + int ret; +- int do_not_lock; ++ int locked; + +- CRYPTO_THREADID_current(&cur); +- /* check if we already have the lock +- * (could happen if a RAND_poll() implementation calls RAND_status()) */ +- if (crypto_lock_rand) +- { +- CRYPTO_r_lock(CRYPTO_LOCK_RAND2); +- do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); +- CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); +- } +- else +- do_not_lock = 0; +- +- if (!do_not_lock) +- { +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); +- +- /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ +- CRYPTO_w_lock(CRYPTO_LOCK_RAND2); +- CRYPTO_THREADID_cpy(&locking_threadid, &cur); +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); +- crypto_lock_rand = 1; +- } ++ locked = private_RAND_lock(1); + + if (!initialized) + { +@@ -583,13 +541,8 @@ static int ssleay_rand_status(void) + + ret = entropy >= ENTROPY_NEEDED; + +- if (!do_not_lock) +- { +- /* before unlocking, we must clear 'crypto_lock_rand' */ +- crypto_lock_rand = 0; +- +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); +- } ++ if (locked) ++ private_RAND_lock(0); + + return ret; + } +diff -up openssl-1.0.1e/crypto/rand/rand.h.fips-reqs openssl-1.0.1e/crypto/rand/rand.h +--- openssl-1.0.1e/crypto/rand/rand.h.fips-reqs 2013-11-19 14:32:25.182891113 +0100 ++++ openssl-1.0.1e/crypto/rand/rand.h 2013-11-19 14:32:03.546416472 +0100 +@@ -124,6 +124,8 @@ void RAND_set_fips_drbg_type(int type, i + int RAND_init_fips(void); + #endif + ++int private_RAND_lock(int lock); ++ + /* BEGIN ERROR CODES */ + /* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. diff -up openssl-1.0.1e/crypto/rand/rand_lcl.h.fips-reqs openssl-1.0.1e/crypto/rand/rand_lcl.h ---- openssl-1.0.1e/crypto/rand/rand_lcl.h.fips-reqs 2013-11-15 16:38:18.110479014 +0100 -+++ openssl-1.0.1e/crypto/rand/rand_lcl.h 2013-11-15 16:38:18.417485749 +0100 +--- openssl-1.0.1e/crypto/rand/rand_lcl.h.fips-reqs 2013-11-15 16:54:49.122218330 +0100 ++++ openssl-1.0.1e/crypto/rand/rand_lcl.h 2013-11-15 16:54:49.427225021 +0100 @@ -112,7 +112,7 @@ #ifndef HEADER_RAND_LCL_H #define HEADER_RAND_LCL_H @@ -120,27 +358,61 @@ diff -up openssl-1.0.1e/crypto/rand/rand_lcl.h.fips-reqs openssl-1.0.1e/crypto/r #if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) diff -up openssl-1.0.1e/crypto/rand/rand_lib.c.fips-reqs openssl-1.0.1e/crypto/rand/rand_lib.c --- openssl-1.0.1e/crypto/rand/rand_lib.c.fips-reqs 2013-02-11 16:26:04.000000000 +0100 -+++ openssl-1.0.1e/crypto/rand/rand_lib.c 2013-11-15 16:38:18.417485749 +0100 -@@ -68,6 +68,7 @@ ++++ openssl-1.0.1e/crypto/rand/rand_lib.c 2013-11-19 14:44:22.422624833 +0100 +@@ -181,6 +181,41 @@ int RAND_status(void) + return 0; + } + ++int private_RAND_lock(int lock) ++ { ++ static int crypto_lock_rand; ++ static CRYPTO_THREADID locking_threadid; ++ int do_lock; ++ ++ if (!lock) ++ { ++ crypto_lock_rand = 0; ++ CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ return 0; ++ } ++ ++ /* check if we already have the lock */ ++ if (crypto_lock_rand) ++ { ++ CRYPTO_THREADID cur; ++ CRYPTO_THREADID_current(&cur); ++ CRYPTO_r_lock(CRYPTO_LOCK_RAND2); ++ do_lock = !!CRYPTO_THREADID_cmp(&locking_threadid, &cur); ++ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); ++ } ++ else ++ do_lock = 1; ++ if (do_lock) ++ { ++ CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ crypto_lock_rand = 1; ++ CRYPTO_w_lock(CRYPTO_LOCK_RAND2); ++ CRYPTO_THREADID_current(&locking_threadid); ++ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); ++ } ++ return do_lock; ++ } ++ #ifdef OPENSSL_FIPS - #include - #include -+#include "../fips/fips_rand_lcl.h" - #endif - #ifndef OPENSSL_NO_ENGINE -@@ -239,12 +240,14 @@ static int drbg_rand_add(DRBG_CTX *ctx, + /* FIPS DRBG initialisation code. This sets up the DRBG for use by the +@@ -239,12 +274,14 @@ static int drbg_rand_add(DRBG_CTX *ctx, double entropy) { RAND_SSLeay()->add(in, inlen, entropy); -+ ctx->status = DRBG_STATUS_RESEED; ++ FIPS_drbg_reseed(ctx, NULL, 0); return 1; } static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) { RAND_SSLeay()->seed(in, inlen); -+ ctx->status = DRBG_STATUS_RESEED; ++ FIPS_drbg_reseed(ctx, NULL, 0); return 1; } diff --git a/openssl.spec b/openssl.spec index 36aada5..3490af4 100644 --- a/openssl.spec +++ b/openssl.spec @@ -21,7 +21,7 @@ Summary: Utilities from the general purpose cryptography library with TLS implementation Name: openssl Version: 1.0.1e -Release: 33%{?dist} +Release: 34%{?dist} Epoch: 1 # We have to remove certain patented algorithms from the openssl source # tarball with the hobble-openssl script which is included below. @@ -462,6 +462,9 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.* %postun libs -p /sbin/ldconfig %changelog +* Tue Nov 19 2013 Tomáš Mráz 1.0.1e-34 +- fix locking and reseeding problems with FIPS drbg + * Fri Nov 15 2013 Tomáš Mráz 1.0.1e-33 - additional changes required for FIPS validation