diff -up openssl-1.0.1e/crypto/bn/bn.h.fips-reqs openssl-1.0.1e/crypto/bn/bn.h --- openssl-1.0.1e/crypto/bn/bn.h.fips-reqs 2013-11-26 14:36:35.000000000 +0100 +++ openssl-1.0.1e/crypto/bn/bn.h 2013-12-13 11:58:58.623821669 +0100 @@ -386,9 +386,11 @@ int BN_GENCB_call(BN_GENCB *cb, int a, i * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; * original paper: Damgaard, Landrock, Pomerance: Average case error estimates * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ -#define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \ - (b) >= 850 ? 3 : \ - (b) >= 650 ? 4 : \ +/* FIPS 186-4 specifies error rate given the security strength of the + * resulting RSA key bit size. So the error rate is 2^-112 or 2^-128 for + * 1024 and 1536 bit keys. + */ +#define BN_prime_checks_for_size(b) ((b) >= 1300 ? 4 : \ (b) >= 550 ? 5 : \ (b) >= 450 ? 6 : \ (b) >= 400 ? 7 : \ diff -up openssl-1.0.1e/crypto/dh/dh_gen.c.fips-reqs openssl-1.0.1e/crypto/dh/dh_gen.c --- openssl-1.0.1e/crypto/dh/dh_gen.c.fips-reqs 2013-11-26 14:36:35.000000000 +0100 +++ openssl-1.0.1e/crypto/dh/dh_gen.c 2013-12-11 16:50:54.181130000 +0100 @@ -125,7 +125,7 @@ static int dh_builtin_genparams(DH *ret, return 0; } - if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN)) { DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); goto err; diff -up openssl-1.0.1e/crypto/dh/dh.h.fips-reqs openssl-1.0.1e/crypto/dh/dh.h --- openssl-1.0.1e/crypto/dh/dh.h.fips-reqs 2013-11-26 14:36:35.000000000 +0100 +++ openssl-1.0.1e/crypto/dh/dh.h 2013-12-11 16:51:18.345675737 +0100 @@ -78,6 +78,7 @@ #endif #define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 +#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN 2048 #define DH_FLAG_CACHE_MONT_P 0x01 #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH diff -up openssl-1.0.1e/crypto/dh/dh_check.c.fips-reqs openssl-1.0.1e/crypto/dh/dh_check.c --- openssl-1.0.1e/crypto/dh/dh_check.c.fips-reqs 2013-02-11 16:26:04.000000000 +0100 +++ openssl-1.0.1e/crypto/dh/dh_check.c 2013-12-11 18:02:26.759075219 +0100 @@ -134,7 +134,33 @@ int DH_check_pub_key(const DH *dh, const BN_sub_word(q,1); if (BN_cmp(pub_key,q)>=0) *ret|=DH_CHECK_PUBKEY_TOO_LARGE; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + BN_CTX *ctx = NULL; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (BN_mod_exp_mont(q, pub_key, dh->q, dh->p, ctx, NULL) <= 0) + { + BN_CTX_free(ctx); + goto err; + } + if (!BN_is_one(q)) + { + /* it would be more correct to add new return flag + * for this test, but we do not want to do it + * so just error out + */ + BN_CTX_free(ctx); + goto err; + } + + BN_CTX_free(ctx); + } +#endif ok = 1; err: if (q != NULL) BN_free(q); diff -up openssl-1.0.1e/crypto/dsa/dsa_gen.c.fips-reqs openssl-1.0.1e/crypto/dsa/dsa_gen.c --- openssl-1.0.1e/crypto/dsa/dsa_gen.c.fips-reqs 2013-11-26 14:36:35.000000000 +0100 +++ openssl-1.0.1e/crypto/dsa/dsa_gen.c 2013-12-11 16:47:25.882425812 +0100 @@ -159,7 +159,6 @@ int dsa_builtin_paramgen(DSA *ret, size_ } if (FIPS_module_mode() && - (bits != 1024 || qbits != 160) && (bits != 2048 || qbits != 224) && (bits != 2048 || qbits != 256) && (bits != 3072 || qbits != 256)) diff -up openssl-1.0.1e/crypto/dsa/dsa.h.fips-reqs openssl-1.0.1e/crypto/dsa/dsa.h --- openssl-1.0.1e/crypto/dsa/dsa.h.fips-reqs 2013-11-26 14:36:35.000000000 +0100 +++ openssl-1.0.1e/crypto/dsa/dsa.h 2013-12-13 11:53:04.637827187 +0100 @@ -89,6 +89,7 @@ #endif #define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 +#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS_GEN 2048 #define DSA_FLAG_CACHE_MONT_P 0x01 #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA @@ -254,9 +255,9 @@ int DSAparams_print_fp(FILE *fp, const D int DSA_print_fp(FILE *bp, const DSA *x, int off); #endif -#define DSS_prime_checks 50 -/* Primality test according to FIPS PUB 186[-1], Appendix 2.1: - * 50 rounds of Rabin-Miller */ +#define DSS_prime_checks 64 +/* Primality test according to FIPS PUB 186[-4], Appendix 2.1: + * 64 rounds of Rabin-Miller */ #define DSA_is_prime(n, callback, cb_arg) \ BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) diff -up openssl-1.0.1e/crypto/dsa/dsa_key.c.fips-reqs openssl-1.0.1e/crypto/dsa/dsa_key.c --- openssl-1.0.1e/crypto/dsa/dsa_key.c.fips-reqs 2013-12-11 16:34:58.000000000 +0100 +++ openssl-1.0.1e/crypto/dsa/dsa_key.c 2013-12-11 16:47:57.815146894 +0100 @@ -127,7 +127,7 @@ static int dsa_builtin_keygen(DSA *dsa) #ifdef OPENSSL_FIPS if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) - && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS_GEN)) { DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); goto err; 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-26 14:36:35.551708593 +0100 +++ openssl-1.0.1e/crypto/fips/fips_drbg_rand.c 2013-11-26 14:36:35.601709689 +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-26 14:36:35.555708680 +0100 +++ openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c 2013-11-26 14:36:35.601709689 +0100 @@ -340,6 +340,42 @@ static const unsigned char kat_RSA_X931_ 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3 }; +static int fips_rsa_encrypt_test(RSA *rsa, const unsigned char *plaintext, int ptlen) + { + unsigned char *ctbuf = NULL, *ptbuf = NULL; + int ret = 0; + int len; + + ctbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!ctbuf) + goto err; + + len = RSA_public_encrypt(ptlen, plaintext, ctbuf, rsa, RSA_PKCS1_PADDING); + if (len <= 0) + goto err; + /* Check ciphertext doesn't match plaintext */ + if (len >= ptlen && !memcmp(plaintext, ctbuf, ptlen)) + goto err; + + ptbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!ptbuf) + goto err; + + len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); + if (len != ptlen) + goto err; + if (memcmp(ptbuf, plaintext, len)) + goto err; + + ret = 1; + + err: + if (ctbuf) + OPENSSL_free(ctbuf); + if (ptbuf) + OPENSSL_free(ptbuf); + return ret; + } int FIPS_selftest_rsa() { @@ -353,7 +389,7 @@ int FIPS_selftest_rsa() if ((pk=EVP_PKEY_new()) == NULL) goto err; - EVP_PKEY_assign_RSA(pk, key); + EVP_PKEY_set1_RSA(pk, key); if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, kat_RSA_SHA1, sizeof(kat_RSA_SHA1), @@ -430,13 +466,15 @@ int FIPS_selftest_rsa() "RSA SHA512 X931")) goto err; + if (!fips_rsa_encrypt_test(key, kat_tbs, sizeof(kat_tbs) - 1)) + goto err; ret = 1; err: if (pk) EVP_PKEY_free(pk); - else if (key) + if (key) RSA_free(key); return ret; } 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-26 14:36:35.601709689 +0100 @@ -898,6 +898,10 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT # endif #endif + ctx->totlen += len; + if (ctx->totlen>(U64(1)<<36) || (sizeof(len)==8 && ctx->totlenmres */ #endif @@ -1200,6 +1204,10 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_C # endif #endif + ctx->totlen += len; + if (ctx->totlen>(U64(1)<<36) || (sizeof(len)==8 && ctx->totlen((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-26 14:36:35.558708746 +0100 +++ openssl-1.0.1e/crypto/rand/rand.h 2013-11-26 14:36:35.602709711 +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-26 14:36:35.239701748 +0100 +++ openssl-1.0.1e/crypto/rand/rand_lcl.h 2013-11-26 14:36:35.602709711 +0100 @@ -112,7 +112,7 @@ #ifndef HEADER_RAND_LCL_H #define HEADER_RAND_LCL_H -#define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ +#define ENTROPY_NEEDED 48 /* require 384 bits = 48 bytes of randomness */ #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-26 14:36:35.602709711 +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 /* 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); + 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); + FIPS_drbg_reseed(ctx, NULL, 0); return 1; } diff -up openssl-1.0.1e/crypto/rsa/rsa_gen.c.fips-reqs openssl-1.0.1e/crypto/rsa/rsa_gen.c --- openssl-1.0.1e/crypto/rsa/rsa_gen.c.fips-reqs 2013-11-26 14:36:35.000000000 +0100 +++ openssl-1.0.1e/crypto/rsa/rsa_gen.c 2013-12-11 16:45:18.661552527 +0100 @@ -182,7 +182,7 @@ static int rsa_builtin_keygen(RSA *rsa, return 0; } - if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS_GEN) { FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT); return 0; diff -up openssl-1.0.1e/crypto/rsa/rsa.h.fips-reqs openssl-1.0.1e/crypto/rsa/rsa.h --- openssl-1.0.1e/crypto/rsa/rsa.h.fips-reqs 2013-11-26 14:36:35.000000000 +0100 +++ openssl-1.0.1e/crypto/rsa/rsa.h 2013-12-11 16:45:05.937265150 +0100 @@ -166,6 +166,8 @@ struct rsa_st #define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 +#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS_GEN 2048 + #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 #endif diff -up openssl-1.0.1e/ssl/t1_enc.c.fips-reqs openssl-1.0.1e/ssl/t1_enc.c --- openssl-1.0.1e/ssl/t1_enc.c.fips-reqs 2013-02-11 16:26:04.000000000 +0100 +++ openssl-1.0.1e/ssl/t1_enc.c 2013-11-26 14:36:35.603709733 +0100 @@ -291,6 +291,27 @@ static int tls1_PRF(long digest_mask, err: return ret; } + +int private_tls1_PRF(long digest_mask, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + const void *seed4, int seed4_len, + const void *seed5, int seed5_len, + const unsigned char *sec, int slen, + unsigned char *out1, + unsigned char *out2, int olen) + { + return tls1_PRF(digest_mask, + seed1, seed1_len, + seed2, seed2_len, + seed3, seed3_len, + seed4, seed4_len, + seed5, seed5_len, + sec, slen, + out1, out2, olen); + } + static int tls1_generate_key_block(SSL *s, unsigned char *km, unsigned char *tmp, int num) {