diff -up openssl-1.0.1e/crypto/bn/bn_rand.c.fips-reqs openssl-1.0.1e/crypto/bn/bn_rand.c --- openssl-1.0.1e/crypto/bn/bn_rand.c.fips-reqs 2013-02-11 16:02:47.000000000 +0100 +++ openssl-1.0.1e/crypto/bn/bn_rand.c 2014-02-13 16:50:34.280893285 +0100 @@ -138,9 +138,12 @@ static int bnrand(int pseudorand, BIGNUM goto err; } - /* make a random number and set the top and bottom bits */ - time(&tim); - RAND_add(&tim,sizeof(tim),0.0); + if (!FIPS_mode()) /* in FIPS mode the RNG is always properly seeded or the module fails */ + { + /* make a random number and set the top and bottom bits */ + time(&tim); + RAND_add(&tim,sizeof(tim),0.0); + } if (pseudorand) { 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-12-18 12:17:09.748636614 +0100 +++ openssl-1.0.1e/crypto/dh/dh_gen.c 2013-12-18 12:17:09.798637687 +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-12-18 12:17:09.748636614 +0100 +++ openssl-1.0.1e/crypto/dh/dh.h 2013-12-18 12:17:09.798637687 +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-18 12:17:09.799637708 +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() && dh->q != NULL) + { + 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-12-18 12:17:09.749636636 +0100 +++ openssl-1.0.1e/crypto/dsa/dsa_gen.c 2013-12-18 12:17:09.799637708 +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-12-18 12:17:09.749636636 +0100 +++ openssl-1.0.1e/crypto/dsa/dsa.h 2013-12-18 12:17:09.799637708 +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-18 12:17:09.797637665 +0100 +++ openssl-1.0.1e/crypto/dsa/dsa_key.c 2013-12-18 12:17:09.799637708 +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_dh_selftest.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_dh_selftest.c --- openssl-1.0.1e/crypto/fips/fips_dh_selftest.c.fips-reqs 2013-12-18 17:06:36.575114314 +0100 +++ openssl-1.0.1e/crypto/fips/fips_dh_selftest.c 2013-12-18 17:26:14.409036334 +0100 @@ -0,0 +1,162 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * Copyright (c) 2013 Red Hat, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +static const unsigned char dh_test_2048_p[] = { + 0xAE,0xEC,0xEE,0x22,0xFA,0x3A,0xA5,0x22,0xC0,0xDE,0x0F,0x09, + 0x7E,0x17,0xC0,0x05,0xF9,0xF1,0xE7,0xC6,0x87,0x14,0x6D,0x11, + 0xE7,0xAE,0xED,0x2F,0x72,0x59,0xC5,0xA9,0x9B,0xB8,0x02,0xA5, + 0xF3,0x69,0x70,0xD6,0xDD,0x90,0xF9,0x19,0x79,0xBE,0x60,0x8F, + 0x25,0x92,0x30,0x1C,0x51,0x51,0x38,0x26,0x82,0x25,0xE6,0xFC, + 0xED,0x65,0x96,0x8F,0x57,0xE5,0x53,0x8B,0x38,0x63,0xC7,0xCE, + 0xBC,0x1B,0x4D,0x18,0x2A,0x5B,0x04,0x3F,0x6A,0x3C,0x94,0x39, + 0xAE,0x36,0xD6,0x5E,0x0F,0xA2,0xCC,0xD0,0xD4,0xD5,0xC6,0x1E, + 0xF6,0xA0,0xF5,0x89,0x4E,0xB4,0x0B,0xA4,0xB3,0x2B,0x3D,0xE2, + 0x4E,0xE1,0x49,0x25,0x99,0x5F,0x32,0x16,0x33,0x32,0x1B,0x7A, + 0xA5,0x5C,0x6B,0x34,0x0D,0x39,0x99,0xDC,0xF0,0x76,0xE5,0x5A, + 0xD4,0x71,0x00,0xED,0x5A,0x73,0xFB,0xC8,0x01,0xAD,0x99,0xCF, + 0x99,0x52,0x7C,0x9C,0x64,0xC6,0x76,0x40,0x57,0xAF,0x59,0xD7, + 0x38,0x0B,0x40,0xDE,0x33,0x0D,0xB8,0x76,0xEC,0xA9,0xD8,0x73, + 0xF8,0xEF,0x26,0x66,0x06,0x27,0xDD,0x7C,0xA4,0x10,0x9C,0xA6, + 0xAA,0xF9,0x53,0x62,0x73,0x1D,0xBA,0x1C,0xF1,0x67,0xF4,0x35, + 0xED,0x6F,0x37,0x92,0xE8,0x4F,0x6C,0xBA,0x52,0x6E,0xA1,0xED, + 0xDA,0x9F,0x85,0x11,0x82,0x52,0x62,0x08,0x44,0xF1,0x30,0x03, + 0xC3,0x38,0x2C,0x79,0xBD,0xD4,0x43,0x45,0xEE,0x8E,0x50,0xFC, + 0x29,0x46,0x9A,0xFE,0x54,0x1A,0x19,0x8F,0x4B,0x84,0x08,0xDE, + 0x20,0x62,0x73,0xCC,0xDD,0x7E,0xF0,0xEF,0xA2,0xFD,0x86,0x58, + 0x4B,0xD8,0x37,0xEB +}; + +static const unsigned char dh_test_2048_g[] = { + 0x02 +}; + +static const unsigned char dh_test_2048_pub_key[] = { + 0xA0,0x39,0x11,0x77,0x9A,0xC1,0x30,0x1F,0xBE,0x48,0xA7,0xAA, + 0xA0,0x84,0x54,0x64,0xAD,0x1B,0x70,0xFA,0x13,0x55,0x63,0xD2, + 0x1F,0x62,0x32,0x93,0x8E,0xC9,0x3E,0x09,0xA7,0x64,0xE4,0x12, + 0x6E,0x1B,0xF2,0x92,0x3B,0xB9,0xCB,0x56,0xEA,0x07,0x88,0xB5, + 0xA6,0xBC,0x16,0x1F,0x27,0xFE,0xD8,0xAA,0x40,0xB2,0xB0,0x2D, + 0x37,0x76,0xA6,0xA4,0x82,0x2C,0x0E,0x22,0x64,0x9D,0xCB,0xD1, + 0x00,0xB7,0x89,0x14,0x72,0x4E,0xBE,0x48,0x41,0xF8,0xB2,0x51, + 0x11,0x09,0x4B,0x22,0x01,0x23,0x39,0x96,0xE0,0x15,0xD7,0x9F, + 0x60,0xD1,0xB7,0xAE,0xFE,0x5F,0xDB,0xE7,0x03,0x17,0x97,0xA6, + 0x16,0x74,0xBD,0x53,0x81,0x19,0xC5,0x47,0x5E,0xCE,0x8D,0xED, + 0x45,0x5D,0x3C,0x00,0xA0,0x0A,0x68,0x6A,0xE0,0x8E,0x06,0x46, + 0x6F,0xD7,0xF9,0xDF,0x31,0x7E,0x77,0x44,0x0D,0x98,0xE0,0xCA, + 0x98,0x09,0x52,0x04,0x90,0xEA,0x6D,0xF4,0x30,0x69,0x8F,0xB1, + 0x9B,0xC1,0x43,0xDB,0xD5,0x8D,0xC8,0x8E,0xB6,0x0B,0x05,0xBE, + 0x0E,0xC5,0x99,0xC8,0x6E,0x4E,0xF3,0xCB,0xC3,0x5E,0x9B,0x53, + 0xF7,0x06,0x1C,0x4F,0xC7,0xB8,0x6E,0x30,0x18,0xCA,0x9B,0xB9, + 0xBC,0x5F,0x17,0x72,0x29,0x5A,0xE5,0xD9,0x96,0xB7,0x0B,0xF3, + 0x2D,0x8C,0xF1,0xE1,0x0E,0x0D,0x74,0xD5,0x9D,0xF0,0x06,0xA9, + 0xB4,0x95,0x63,0x76,0x46,0x55,0x48,0x82,0x39,0x90,0xEF,0x56, + 0x75,0x34,0xB8,0x34,0xC3,0x18,0x6E,0x1E,0xAD,0xE3,0x48,0x7E, + 0x93,0x2C,0x23,0xE7,0xF8,0x90,0x73,0xB1,0x77,0x80,0x67,0xA9, + 0x36,0x9E,0xDA,0xD2 +}; + +static const unsigned char dh_test_2048_priv_key[] = { + 0x0C,0x4B,0x30,0x89,0xD1,0xB8,0x62,0xCB,0x3C,0x43,0x64,0x91, + 0xF0,0x91,0x54,0x70,0xC5,0x27,0x96,0xE3,0xAC,0xBE,0xE8,0x00, + 0xEC,0x55,0xF6,0xCC +}; + +int FIPS_selftest_dh() + { + DH *dh = NULL; + int ret = 0; + void *pub_key = NULL; + int len; + + dh = DH_new(); + + if(dh == NULL) + goto err; + + fips_load_key_component(dh, p, dh_test_2048); + fips_load_key_component(dh, g, dh_test_2048); + /* note that the private key is much shorter than normally used + * but still g ** priv_key > p + */ + fips_load_key_component(dh, priv_key, dh_test_2048); + + if (DH_generate_key(dh) <= 0) + goto err; + + len = BN_num_bytes(dh->pub_key); + if ((pub_key = OPENSSL_malloc(len)) == NULL) + goto err; + BN_bn2bin(dh->pub_key, pub_key); + + if (len != sizeof(dh_test_2048_pub_key) || + memcmp(pub_key, dh_test_2048_pub_key, len) != 0) + goto err; + + ret = 1; + + err: + if (dh) + DH_free(dh); + + OPENSSL_free(pub_key); + return ret; + } +#endif 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-12-18 12:17:09.757636808 +0100 +++ openssl-1.0.1e/crypto/fips/fips_drbg_rand.c 2013-12-18 18:53:33.263711297 +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; } @@ -124,35 +126,51 @@ static int fips_drbg_status(void) { DRBG_CTX *dctx = &ossl_dctx; int rv; - CRYPTO_r_lock(CRYPTO_LOCK_RAND); + int locked; + locked = private_RAND_lock(1); rv = dctx->status == DRBG_STATUS_READY ? 1 : 0; - CRYPTO_r_unlock(CRYPTO_LOCK_RAND); + if (locked) + private_RAND_lock(0); return rv; } static void fips_drbg_cleanup(void) { DRBG_CTX *dctx = &ossl_dctx; - CRYPTO_w_lock(CRYPTO_LOCK_RAND); + int locked; + locked = private_RAND_lock(1); FIPS_drbg_uninstantiate(dctx); - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + if (locked) + private_RAND_lock(0); } static int fips_drbg_seed(const void *seed, int seedlen) { DRBG_CTX *dctx = &ossl_dctx; + int locked; + int ret = 1; + + locked = private_RAND_lock(1); if (dctx->rand_seed_cb) - return dctx->rand_seed_cb(dctx, seed, seedlen); - return 1; + ret = dctx->rand_seed_cb(dctx, seed, seedlen); + if (locked) + private_RAND_lock(0); + return ret; } static int fips_drbg_add(const void *seed, int seedlen, double add_entropy) { DRBG_CTX *dctx = &ossl_dctx; + int locked; + int ret = 1; + + locked = private_RAND_lock(1); if (dctx->rand_add_cb) - return dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); - return 1; + ret = dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); + if (locked) + private_RAND_lock(0); + return ret; } static const RAND_METHOD rand_drbg_meth = diff -up openssl-1.0.1e/crypto/fips/fips.h.fips-reqs openssl-1.0.1e/crypto/fips/fips.h --- openssl-1.0.1e/crypto/fips/fips.h.fips-reqs 2013-12-18 12:17:09.000000000 +0100 +++ openssl-1.0.1e/crypto/fips/fips.h 2013-12-18 17:13:00.928586689 +0100 @@ -96,6 +96,7 @@ void FIPS_corrupt_dsa_keygen(void); int FIPS_selftest_dsa(void); int FIPS_selftest_ecdsa(void); int FIPS_selftest_ecdh(void); +int FIPS_selftest_dh(void); void FIPS_corrupt_rng(void); void FIPS_rng_stick(void); void FIPS_x931_stick(int onoff); diff -up openssl-1.0.1e/crypto/fips/fips_post.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_post.c --- openssl-1.0.1e/crypto/fips/fips_post.c.fips-reqs 2013-12-18 12:17:09.000000000 +0100 +++ openssl-1.0.1e/crypto/fips/fips_post.c 2013-12-18 17:12:26.721832716 +0100 @@ -99,6 +99,8 @@ int FIPS_selftest(void) rv = 0; if (!FIPS_selftest_dsa()) rv = 0; + if (!FIPS_selftest_dh()) + rv = 0; if (!FIPS_selftest_ecdh()) rv = 0; return rv; 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-12-18 12:17:09.761636893 +0100 +++ openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c 2013-12-18 12:17:09.799637708 +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/fips/Makefile.fips-reqs openssl-1.0.1e/crypto/fips/Makefile --- openssl-1.0.1e/crypto/fips/Makefile.fips-reqs 2013-12-18 12:17:20.000000000 +0100 +++ openssl-1.0.1e/crypto/fips/Makefile 2013-12-18 17:14:20.348337362 +0100 @@ -24,13 +24,15 @@ LIBSRC=fips_aes_selftest.c fips_des_self fips_rsa_selftest.c fips_sha_selftest.c fips.c fips_dsa_selftest.c fips_rand.c \ fips_rsa_x931g.c fips_post.c fips_drbg_ctr.c fips_drbg_hash.c fips_drbg_hmac.c \ fips_drbg_lib.c fips_drbg_rand.c fips_drbg_selftest.c fips_rand_lib.c \ - fips_cmac_selftest.c fips_ecdh_selftest.c fips_ecdsa_selftest.c fips_enc.c fips_md.c + fips_cmac_selftest.c fips_ecdh_selftest.c fips_ecdsa_selftest.c fips_enc.c fips_md.c \ + fips_dh_selftest.c LIBOBJ=fips_aes_selftest.o fips_des_selftest.o fips_hmac_selftest.o fips_rand_selftest.o \ fips_rsa_selftest.o fips_sha_selftest.o fips.o fips_dsa_selftest.o fips_rand.o \ fips_rsa_x931g.o fips_post.o fips_drbg_ctr.o fips_drbg_hash.o fips_drbg_hmac.o \ fips_drbg_lib.o fips_drbg_rand.o fips_drbg_selftest.o fips_rand_lib.o \ - fips_cmac_selftest.o fips_ecdh_selftest.o fips_ecdsa_selftest.o fips_enc.o fips_md.o + fips_cmac_selftest.o fips_ecdh_selftest.o fips_ecdsa_selftest.o fips_enc.o fips_md.o \ + fips_dh_selftest.o LIBCRYPTO=-L.. -lcrypto 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-12-18 12:17:09.800637730 +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-12-18 12:17:09.764636958 +0100 +++ openssl-1.0.1e/crypto/rand/rand.h 2013-12-18 12:17:09.800637730 +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-12-18 12:17:09.507631447 +0100 +++ openssl-1.0.1e/crypto/rand/rand_lcl.h 2013-12-18 12:17:09.800637730 +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-12-18 18:16:45.625850730 +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,16 @@ static int drbg_rand_add(DRBG_CTX *ctx, double entropy) { RAND_SSLeay()->add(in, inlen, entropy); + if (FIPS_rand_status()) + 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); + if (FIPS_rand_status()) + 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-12-18 12:17:09.764636958 +0100 +++ openssl-1.0.1e/crypto/rsa/rsa_gen.c 2013-12-19 17:40:58.483154314 +0100 @@ -1,5 +1,6 @@ /* crypto/rsa/rsa_gen.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * Copyright (C) 2013 Red Hat, Inc. * All rights reserved. * * This package is an SSL implementation written @@ -165,6 +166,222 @@ int RSA_generate_key_ex(RSA *rsa, int bi return rsa_builtin_keygen(rsa, bits, e_value, cb); } +#ifdef OPENSSL_FIPS +static int FIPS_rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) + { + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; + BIGNUM local_r0, local_d, local_p; + BIGNUM *pr0, *d, *p; + BN_CTX *ctx = NULL; + int ok = -1; + int i; + int n = 0; + int test = 0; + int pbits = bits/2; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (bits != 2048 && bits != 3072) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_INVALID_KEY_LENGTH); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) goto err; + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + + if (r3 == NULL) goto err; + + /* We need the RSA components non-NULL */ + if (!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; + if (!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; + if (!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; + if (!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; + if (!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; + if (!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; + if (!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; + if (!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; + + if (!BN_set_word(r0, RSA_F4)) goto err; + if (BN_cmp(e_value, r0) < 0 || BN_num_bits(e_value) > 256) + { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_BAD_E_VALUE); + goto err; + } + + /* prepare approximate minimum p and q */ + if (!BN_set_word(r0, 0xB504F334)) goto err; + if (!BN_lshift(r0, r0, pbits - 32)) goto err; + + /* prepare minimum p and q difference */ + if (!BN_one(r3)) goto err; + if (!BN_lshift(r3, r3, pbits - 100)) goto err; + + BN_copy(rsa->e, e_value); + + if (!BN_is_zero(rsa->p) && !BN_is_zero(rsa->q)) + test = 1; + + /* generate p and q */ + for (i = 0; i < 5 * pbits; i++) + { + ploop: + if (!test) + if (!BN_rand(rsa->p, pbits, 0, 1)) goto err; + if (BN_cmp(rsa->p, r0) < 0) + { + if (test) goto err; + goto ploop; + } + + if (!BN_sub(r2, rsa->p, BN_value_one())) goto err; + if (!BN_gcd(r1, r2, rsa->e, ctx)) goto err; + if (BN_is_one(r1)) + { + int r; + r = BN_is_prime_fasttest_ex(rsa->p, pbits>1024?4:5, ctx, 0, cb); + if (r == -1 || (test && r <= 0)) goto err; + if (r > 0) break; + } + + if(!BN_GENCB_call(cb, 2, n++)) + goto err; + } + + if(!BN_GENCB_call(cb, 3, 0)) + goto err; + + if(i >= 5*pbits) + /* prime not found */ + goto err; + + for (i = 0; i < 5 * pbits; i++) + { + qloop: + if (!test) + if (!BN_rand(rsa->q, pbits, 0, 1)) goto err; + if (BN_cmp(rsa->q, r0) < 0) + { + if (test) goto err; + goto qloop; + } + if (!BN_sub(r2, rsa->q, rsa->p)) goto err; + if (BN_ucmp(r2, r3) <= 0) + { + if (test) goto err; + goto qloop; + } + + if (!BN_sub(r2, rsa->q, BN_value_one())) goto err; + if (!BN_gcd(r1, r2, rsa->e, ctx)) goto err; + if (BN_is_one(r1)) + { + int r; + r = BN_is_prime_fasttest_ex(rsa->q, pbits>1024?4:5, ctx, 0, cb); + if (r == -1 || (test && r <= 0)) goto err; + if (r > 0) break; + } + + if(!BN_GENCB_call(cb, 2, n++)) + goto err; + } + + if(!BN_GENCB_call(cb, 3, 1)) + goto err; + + if(i >= 5*pbits) + /* prime not found */ + goto err; + + if (test) + { + /* do not try to calculate the remaining key values */ + BN_clear(rsa->n); + ok = 1; + goto err; + } + + if (BN_cmp(rsa->p,rsa->q) < 0) + { + tmp=rsa->p; + rsa->p=rsa->q; + rsa->q=tmp; + } + + /* calculate n */ + if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; + + /* calculate d */ + if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ + if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ + if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + pr0 = &local_r0; + BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); + } + else + pr0 = r0; + if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ + + /* set up d for correct BN_FLG_CONSTTIME flag */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + + /* calculate d mod (p-1) */ + if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; + + /* calculate d mod (q-1) */ + if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; + + /* calculate inverse of q mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + } + else + p = rsa->p; + if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; + + if (fips_rsa_pairwise_fail) + BN_add_word(rsa->n, 1); + + if(!fips_check_rsa(rsa)) + goto err; + + ok=1; +err: + if (ok == -1) + { + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); + ok = 0; + } + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ok; + } +#endif + static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; @@ -176,17 +393,7 @@ static int rsa_builtin_keygen(RSA *rsa, #ifdef OPENSSL_FIPS if (FIPS_module_mode()) { - if(FIPS_selftest_failed()) - { - FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED); - return 0; - } - - if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) - { - FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT); - return 0; - } + return FIPS_rsa_builtin_keygen(rsa, bits, e_value, cb); } #endif @@ -301,17 +508,6 @@ static int rsa_builtin_keygen(RSA *rsa, p = rsa->p; if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; -#ifdef OPENSSL_FIPS - if (FIPS_module_mode()) - { - if (fips_rsa_pairwise_fail) - BN_add_word(rsa->n, 1); - - if(!fips_check_rsa(rsa)) - goto err; - } -#endif - ok=1; err: if (ok == -1) 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-12-18 12:17:09.801637751 +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) {