From ccb7f79a321d91cd2826bb9e65aacc8382a18518a1d7e4369a49a0083e141812 Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Thu, 6 Mar 2014 18:29:26 +0000 Subject: [PATCH] Accepting request 224423 from Base:System additional changes required for FIPS validation( from Fedora repo); Add patch file: openssl-1.0.1e-new-fips-reqs.patch (forwarded request 224375 from shawn2012) OBS-URL: https://build.opensuse.org/request/show/224423 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/openssl?expand=0&rev=108 --- openssl-1.0.1e-new-fips-reqs.patch | 1113 ++++++++++++++++++++++++++++ openssl.changes | 6 + openssl.spec | 2 + 3 files changed, 1121 insertions(+) create mode 100644 openssl-1.0.1e-new-fips-reqs.patch diff --git a/openssl-1.0.1e-new-fips-reqs.patch b/openssl-1.0.1e-new-fips-reqs.patch new file mode 100644 index 0000000..ed2955f --- /dev/null +++ b/openssl-1.0.1e-new-fips-reqs.patch @@ -0,0 +1,1113 @@ +Index: openssl-1.0.1f/crypto/bn/bn_rand.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/bn/bn_rand.c ++++ openssl-1.0.1f/crypto/bn/bn_rand.c +@@ -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) + { +Index: openssl-1.0.1f/crypto/dh/dh_gen.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/dh/dh_gen.c ++++ openssl-1.0.1f/crypto/dh/dh_gen.c +@@ -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; +Index: openssl-1.0.1f/crypto/dh/dh.h +=================================================================== +--- openssl-1.0.1f.orig/crypto/dh/dh.h ++++ openssl-1.0.1f/crypto/dh/dh.h +@@ -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 +Index: openssl-1.0.1f/crypto/dh/dh_check.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/dh/dh_check.c ++++ openssl-1.0.1f/crypto/dh/dh_check.c +@@ -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); +Index: openssl-1.0.1f/crypto/dsa/dsa_gen.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/dsa/dsa_gen.c ++++ openssl-1.0.1f/crypto/dsa/dsa_gen.c +@@ -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)) +Index: openssl-1.0.1f/crypto/dsa/dsa.h +=================================================================== +--- openssl-1.0.1f.orig/crypto/dsa/dsa.h ++++ openssl-1.0.1f/crypto/dsa/dsa.h +@@ -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) + +Index: openssl-1.0.1f/crypto/dsa/dsa_key.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/dsa/dsa_key.c ++++ openssl-1.0.1f/crypto/dsa/dsa_key.c +@@ -122,7 +122,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; +Index: openssl-1.0.1f/crypto/fips/fips_dh_selftest.c +=================================================================== +--- /dev/null ++++ openssl-1.0.1f/crypto/fips/fips_dh_selftest.c +@@ -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 +Index: openssl-1.0.1f/crypto/fips/fips_drbg_rand.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/fips/fips_drbg_rand.c ++++ openssl-1.0.1f/crypto/fips/fips_drbg_rand.c +@@ -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 = +Index: openssl-1.0.1f/crypto/fips/fips.h +=================================================================== +--- openssl-1.0.1f.orig/crypto/fips/fips.h ++++ openssl-1.0.1f/crypto/fips/fips.h +@@ -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); +Index: openssl-1.0.1f/crypto/fips/fips_post.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/fips/fips_post.c ++++ openssl-1.0.1f/crypto/fips/fips_post.c +@@ -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; +Index: openssl-1.0.1f/crypto/fips/fips_rsa_selftest.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/fips/fips_rsa_selftest.c ++++ openssl-1.0.1f/crypto/fips/fips_rsa_selftest.c +@@ -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; + } +Index: openssl-1.0.1f/crypto/fips/Makefile +=================================================================== +--- openssl-1.0.1f.orig/crypto/fips/Makefile ++++ openssl-1.0.1f/crypto/fips/Makefile +@@ -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 + +Index: openssl-1.0.1f/crypto/modes/gcm128.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/modes/gcm128.c ++++ openssl-1.0.1f/crypto/modes/gcm128.c +@@ -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 +@@ -1213,6 +1217,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) + { +@@ -524,13 +504,15 @@ static int ssleay_rand_bytes(unsigned ch + #ifdef OPENSSL_FIPS + if (!FIPS_mode()) + #endif +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ locked = private_RAND_lock(1); + MD_Update(&m,md,MD_DIGEST_LENGTH); + MD_Final(&m,md); + #ifdef OPENSSL_FIPS + if (!FIPS_mode()) + #endif +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ ++ if (locked) ++ private_RAND_lock(0); + + EVP_MD_CTX_cleanup(&m); + if (ok) +@@ -560,32 +542,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) + { +@@ -595,13 +555,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) + { diff --git a/openssl.changes b/openssl.changes index 7d8adb0..dd31ec4 100644 --- a/openssl.changes +++ b/openssl.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Mon Mar 3 06:44:52 UTC 2014 - shchang@suse.com + +- additional changes required for FIPS validation( from Fedora repo) + Add patch file: openssl-1.0.1e-new-fips-reqs.patch + ------------------------------------------------------------------- Sat Jan 11 08:42:54 UTC 2014 - shchang@suse.com diff --git a/openssl.spec b/openssl.spec index 7b8804b..4081e1e 100644 --- a/openssl.spec +++ b/openssl.spec @@ -63,6 +63,7 @@ Patch14: 0001-libcrypto-Hide-library-private-symbols.patch Patch15: openssl-1.0.1e-fips.patch Patch16: openssl-1.0.1e-fips-ec.patch Patch17: openssl-1.0.1e-fips-ctor.patch +Patch18: openssl-1.0.1e-new-fips-reqs.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -167,6 +168,7 @@ this package's base documentation. %patch15 -p1 %patch16 -p1 %patch17 -p1 +%patch18 -p1 cp -p %{S:10} . cp -p %{S:11} .