From 1f19ac14f96ae02be864198a68421f8b1df88be0 Mon Sep 17 00:00:00 2001 From: Tom Callaway Date: Oct 15 2013 01:08:35 +0000 Subject: resolve bugzilla 319901 (phew! only took 6 years & 9 days) --- diff --git a/hobble-openssl b/hobble-openssl index 4ca7eab..3b78335 100755 --- a/hobble-openssl +++ b/hobble-openssl @@ -7,39 +7,30 @@ set -e # MDC-2: 4,908,861 13/03/2007 - expired, we do not remove it but do not enable it anyway # IDEA: 5,214,703 07/01/2012 - expired, we do not remove it anymore # RC5: 5,724,428 01/11/2015 -# EC: ????????? ??/??/2020 # SRP: ????????? ??/??/20?? # Remove assembler portions of IDEA, MDC2, and RC5. (find crypto/rc5/asm -type f | xargs -r rm -fv) -# RC5, EC, SRP. -for a in rc5 ec ecdh ecdsa srp; do +# RC5, SRP. +for a in rc5 srp; do for c in `find crypto/$a -name "*.c" -a \! -name "*test*" -type f` ; do echo Destroying $c > $c done done -for c in `find crypto/evp -name "*_rc5.c" -o -name "*_ecdsa.c"`; do - echo Destroying $c - > $c -done - -for c in `find crypto/bn -name "*gf2m.c"`; do +for c in `find crypto/evp -name "*_rc5.c"`; do echo Destroying $c > $c done for h in `find crypto ssl apps test -name "*.h"` ; do - echo Removing RC5, SRP and EC references from $h + echo Removing RC5, SRP references from $h cat $h | \ awk 'BEGIN {ech=1;} \ /^#[ \t]*ifndef.*NO_SRP/ {ech--; next;} \ /^#[ \t]*ifndef.*NO_RC5/ {ech--; next;} \ - /^#[ \t]*ifndef.*NO_EC/ {ech--; next;} \ - /^#[ \t]*ifndef.*NO_ECDH/ {ech--; next;} \ - /^#[ \t]*ifndef.*NO_ECDSA/ {ech--; next;} \ /^#[ \t]*if/ {if(ech < 1) ech--;} \ {if(ech>0) {;print $0};} \ /^#[ \t]*endif/ {if(ech < 1) ech++;}' > $h.hobbled && \ diff --git a/openssl-1.0.1e-fips-ec.patch b/openssl-1.0.1e-fips-ec.patch new file mode 100644 index 0000000..e635dde --- /dev/null +++ b/openssl-1.0.1e-fips-ec.patch @@ -0,0 +1,2052 @@ +diff -up openssl-1.0.1e/crypto/ec/ec2_smpl.c.fips-ec openssl-1.0.1e/crypto/ec/ec2_smpl.c +--- openssl-1.0.1e/crypto/ec/ec2_smpl.c.fips-ec 2013-10-15 01:10:57.472546753 +0100 ++++ openssl-1.0.1e/crypto/ec/ec2_smpl.c 2013-10-15 01:11:10.346529011 +0100 +@@ -80,9 +80,6 @@ + + const EC_METHOD *EC_GF2m_simple_method(void) + { +-#ifdef OPENSSL_FIPS +- return fips_ec_gf2m_simple_method(); +-#else + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_characteristic_two_field, +@@ -126,7 +123,6 @@ const EC_METHOD *EC_GF2m_simple_method(v + 0 /* field_set_to_one */ }; + + return &ret; +-#endif + } + + +diff -up openssl-1.0.1e/crypto/ec/ec_key.c.fips-ec openssl-1.0.1e/crypto/ec/ec_key.c +--- openssl-1.0.1e/crypto/ec/ec_key.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ec/ec_key.c 2013-10-15 01:08:06.046783148 +0100 +@@ -64,9 +64,6 @@ + #include + #include "ec_lcl.h" + #include +-#ifdef OPENSSL_FIPS +-#include +-#endif + + EC_KEY *EC_KEY_new(void) + { +@@ -234,6 +231,39 @@ int EC_KEY_up_ref(EC_KEY *r) + return ((i > 1) ? 1 : 0); + } + ++#ifdef OPENSSL_FIPS ++ ++#include ++#include ++#include ++ ++static int fips_check_ec(EC_KEY *key) ++ { ++ EVP_PKEY *pk; ++ unsigned char tbs[] = "ECDSA Pairwise Check Data"; ++ int ret = 0; ++ ++ if ((pk=EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_set1_EC_KEY(pk, key); ++ ++ if (fips_pkey_signature_test(pk, tbs, 0, NULL, 0, NULL, 0, NULL)) ++ ret = 1; ++ ++ err: ++ if (ret == 0) ++ { ++ FIPSerr(FIPS_F_FIPS_CHECK_EC,FIPS_R_PAIRWISE_TEST_FAILED); ++ fips_set_selftest_fail(); ++ } ++ if (pk) ++ EVP_PKEY_free(pk); ++ return ret; ++ } ++ ++#endif ++ + int EC_KEY_generate_key(EC_KEY *eckey) + { + int ok = 0; +@@ -242,8 +272,11 @@ int EC_KEY_generate_key(EC_KEY *eckey) + EC_POINT *pub_key = NULL; + + #ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ec_key_generate_key(eckey); ++ if(FIPS_selftest_failed()) ++ { ++ FIPSerr(FIPS_F_EC_KEY_GENERATE_KEY,FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } + #endif + + if (!eckey || !eckey->group) +@@ -287,6 +320,15 @@ int EC_KEY_generate_key(EC_KEY *eckey) + eckey->priv_key = priv_key; + eckey->pub_key = pub_key; + ++#ifdef OPENSSL_FIPS ++ if(!fips_check_ec(eckey)) ++ { ++ eckey->priv_key = NULL; ++ eckey->pub_key = NULL; ++ goto err; ++ } ++#endif ++ + ok=1; + + err: +@@ -429,10 +471,12 @@ int EC_KEY_set_public_key_affine_coordin + tx, ty, ctx)) + goto err; + } +- /* Check if retrieved coordinates match originals: if not values +- * are out of range. ++ /* Check if retrieved coordinates match originals and are less than ++ * field order: if not values are out of range. + */ +- if (BN_cmp(x, tx) || BN_cmp(y, ty)) ++ if (BN_cmp(x, tx) || BN_cmp(y, ty) ++ || (BN_cmp(x, &key->group->field) >= 0) ++ || (BN_cmp(y, &key->group->field) >= 0)) + { + ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, + EC_R_COORDINATES_OUT_OF_RANGE); +diff -up openssl-1.0.1e/crypto/ec/ecp_mont.c.fips-ec openssl-1.0.1e/crypto/ec/ecp_mont.c +--- openssl-1.0.1e/crypto/ec/ecp_mont.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ec/ecp_mont.c 2013-10-15 01:08:06.047783146 +0100 +@@ -63,18 +63,11 @@ + + #include + +-#ifdef OPENSSL_FIPS +-#include +-#endif +- + #include "ec_lcl.h" + + + const EC_METHOD *EC_GFp_mont_method(void) + { +-#ifdef OPENSSL_FIPS +- return fips_ec_gfp_mont_method(); +-#else + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, +@@ -115,7 +108,6 @@ const EC_METHOD *EC_GFp_mont_method(void + ec_GFp_mont_field_set_to_one }; + + return &ret; +-#endif + } + + +diff -up openssl-1.0.1e/crypto/ec/ecp_nist.c.fips-ec openssl-1.0.1e/crypto/ec/ecp_nist.c +--- openssl-1.0.1e/crypto/ec/ecp_nist.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ec/ecp_nist.c 2013-10-15 01:08:06.047783146 +0100 +@@ -67,15 +67,8 @@ + #include + #include "ec_lcl.h" + +-#ifdef OPENSSL_FIPS +-#include +-#endif +- + const EC_METHOD *EC_GFp_nist_method(void) + { +-#ifdef OPENSSL_FIPS +- return fips_ec_gfp_nist_method(); +-#else + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, +@@ -116,7 +109,6 @@ const EC_METHOD *EC_GFp_nist_method(void + 0 /* field_set_to_one */ }; + + return &ret; +-#endif + } + + int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) +diff -up openssl-1.0.1e/crypto/ec/ecp_smpl.c.fips-ec openssl-1.0.1e/crypto/ec/ecp_smpl.c +--- openssl-1.0.1e/crypto/ec/ecp_smpl.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ec/ecp_smpl.c 2013-10-15 01:08:06.047783146 +0100 +@@ -65,17 +65,10 @@ + #include + #include + +-#ifdef OPENSSL_FIPS +-#include +-#endif +- + #include "ec_lcl.h" + + const EC_METHOD *EC_GFp_simple_method(void) + { +-#ifdef OPENSSL_FIPS +- return fips_ec_gfp_simple_method(); +-#else + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, +@@ -116,7 +109,6 @@ const EC_METHOD *EC_GFp_simple_method(vo + 0 /* field_set_to_one */ }; + + return &ret; +-#endif + } + + +diff -up openssl-1.0.1e/crypto/ecdh/ecdh.h.fips-ec openssl-1.0.1e/crypto/ecdh/ecdh.h +--- openssl-1.0.1e/crypto/ecdh/ecdh.h.fips-ec 2013-10-15 01:08:05.748783559 +0100 ++++ openssl-1.0.1e/crypto/ecdh/ecdh.h 2013-10-15 01:08:06.046783148 +0100 +@@ -85,6 +85,8 @@ + extern "C" { + #endif + ++#define EC_FLAG_COFACTOR_ECDH 0x1000 ++ + const ECDH_METHOD *ECDH_OpenSSL(void); + + void ECDH_set_default_method(const ECDH_METHOD *); +diff -up openssl-1.0.1e/crypto/ecdh/ecdhtest.c.fips-ec openssl-1.0.1e/crypto/ecdh/ecdhtest.c +--- openssl-1.0.1e/crypto/ecdh/ecdhtest.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ecdh/ecdhtest.c 2013-10-15 01:08:06.046783148 +0100 +@@ -323,11 +323,15 @@ int main(int argc, char *argv[]) + if ((ctx=BN_CTX_new()) == NULL) goto err; + + /* NIST PRIME CURVES TESTS */ ++#if 0 + if (!test_ecdh_curve(NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) goto err; + if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) goto err; ++#endif + if (!test_ecdh_curve(NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) goto err; + if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err; ++#if 0 + if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err; ++#endif + #ifndef OPENSSL_NO_EC2M + /* NIST BINARY CURVES TESTS */ + if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) goto err; +diff -up openssl-1.0.1e/crypto/ecdh/ech_lib.c.fips-ec openssl-1.0.1e/crypto/ecdh/ech_lib.c +--- openssl-1.0.1e/crypto/ecdh/ech_lib.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ecdh/ech_lib.c 2013-10-15 01:08:06.046783148 +0100 +@@ -94,14 +94,7 @@ const ECDH_METHOD *ECDH_get_default_meth + { + if(!default_ECDH_method) + { +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ecdh_openssl(); +- else +- return ECDH_OpenSSL(); +-#else + default_ECDH_method = ECDH_OpenSSL(); +-#endif + } + return default_ECDH_method; + } +diff -up openssl-1.0.1e/crypto/ecdh/ech_ossl.c.fips-ec openssl-1.0.1e/crypto/ecdh/ech_ossl.c +--- openssl-1.0.1e/crypto/ecdh/ech_ossl.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ecdh/ech_ossl.c 2013-10-15 01:08:06.046783148 +0100 +@@ -79,6 +79,10 @@ + #include + #include + ++#ifdef OPENSSL_FIPS ++#include ++#endif ++ + static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); +@@ -90,7 +94,7 @@ static ECDH_METHOD openssl_ecdh_meth = { + NULL, /* init */ + NULL, /* finish */ + #endif +- 0, /* flags */ ++ ECDH_FLAG_FIPS_METHOD, /* flags */ + NULL /* app_data */ + }; + +@@ -118,6 +122,14 @@ static int ecdh_compute_key(void *out, s + size_t buflen, len; + unsigned char *buf=NULL; + ++#ifdef OPENSSL_FIPS ++ if(FIPS_selftest_failed()) ++ { ++ FIPSerr(FIPS_F_ECDH_COMPUTE_KEY,FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++#endif ++ + if (outlen > INT_MAX) + { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); /* sort of, anyway */ +@@ -137,6 +149,18 @@ static int ecdh_compute_key(void *out, s + } + + group = EC_KEY_get0_group(ecdh); ++ ++ if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) ++ { ++ if (!EC_GROUP_get_cofactor(group, x, ctx) || ++ !BN_mul(x, x, priv_key, ctx)) ++ { ++ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ priv_key = x; ++ } ++ + if ((tmp=EC_POINT_new(group)) == NULL) + { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); +diff -up openssl-1.0.1e/crypto/ecdsa/ecdsatest.c.fips-ec openssl-1.0.1e/crypto/ecdsa/ecdsatest.c +--- openssl-1.0.1e/crypto/ecdsa/ecdsatest.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ecdsa/ecdsatest.c 2013-10-15 01:08:06.046783148 +0100 +@@ -138,11 +138,14 @@ int restore_rand(void) + } + + static int fbytes_counter = 0; +-static const char *numbers[8] = { ++static const char *numbers[10] = { ++ "651056770906015076056810763456358567190100156695615665659", + "651056770906015076056810763456358567190100156695615665659", + "6140507067065001063065065565667405560006161556565665656654", + "8763001015071075675010661307616710783570106710677817767166" + "71676178726717", ++ "8763001015071075675010661307616710783570106710677817767166" ++ "71676178726717", + "7000000175690566466555057817571571075705015757757057795755" + "55657156756655", + "1275552191113212300012030439187146164646146646466749494799", +@@ -157,7 +160,7 @@ int fbytes(unsigned char *buf, int num) + int ret; + BIGNUM *tmp = NULL; + +- if (fbytes_counter >= 8) ++ if (fbytes_counter >= 10) + return 0; + tmp = BN_new(); + if (!tmp) +@@ -550,7 +553,9 @@ int main(void) + RAND_seed(rnd_seed, sizeof(rnd_seed)); + + /* the tests */ ++#if 0 + if (!x9_62_tests(out)) goto err; ++#endif + if (!test_builtin(out)) goto err; + + ret = 0; +diff -up openssl-1.0.1e/crypto/ecdsa/ecs_lib.c.fips-ec openssl-1.0.1e/crypto/ecdsa/ecs_lib.c +--- openssl-1.0.1e/crypto/ecdsa/ecs_lib.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ecdsa/ecs_lib.c 2013-10-15 01:08:06.046783148 +0100 +@@ -81,14 +81,7 @@ const ECDSA_METHOD *ECDSA_get_default_me + { + if(!default_ECDSA_method) + { +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ecdsa_openssl(); +- else +- return ECDSA_OpenSSL(); +-#else + default_ECDSA_method = ECDSA_OpenSSL(); +-#endif + } + return default_ECDSA_method; + } +diff -up openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c.fips-ec openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c +--- openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c 2013-10-15 01:08:06.046783148 +0100 +@@ -60,6 +60,9 @@ + #include + #include + #include ++#ifdef OPENSSL_FIPS ++#include ++#endif + + static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + const BIGNUM *, const BIGNUM *, EC_KEY *eckey); +@@ -77,7 +80,7 @@ static ECDSA_METHOD openssl_ecdsa_meth = + NULL, /* init */ + NULL, /* finish */ + #endif +- 0, /* flags */ ++ ECDSA_FLAG_FIPS_METHOD, /* flags */ + NULL /* app_data */ + }; + +@@ -231,6 +234,14 @@ static ECDSA_SIG *ecdsa_do_sign(const un + ECDSA_DATA *ecdsa; + const BIGNUM *priv_key; + ++#ifdef OPENSSL_FIPS ++ if(FIPS_selftest_failed()) ++ { ++ FIPSerr(FIPS_F_ECDSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED); ++ return NULL; ++ } ++#endif ++ + ecdsa = ecdsa_check(eckey); + group = EC_KEY_get0_group(eckey); + priv_key = EC_KEY_get0_private_key(eckey); +@@ -360,6 +371,14 @@ static int ecdsa_do_verify(const unsigne + const EC_GROUP *group; + const EC_POINT *pub_key; + ++#ifdef OPENSSL_FIPS ++ if(FIPS_selftest_failed()) ++ { ++ FIPSerr(FIPS_F_ECDSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++#endif ++ + /* check input values */ + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || + (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) +diff -up openssl-1.0.1e/crypto/evp/m_ecdsa.c.fips-ec openssl-1.0.1e/crypto/evp/m_ecdsa.c +--- openssl-1.0.1e/crypto/evp/m_ecdsa.c.fips-ec 2013-02-11 15:26:04.000000000 +0000 ++++ openssl-1.0.1e/crypto/evp/m_ecdsa.c 2013-10-15 01:08:06.047783146 +0100 +@@ -116,7 +116,6 @@ + #include + + #ifndef OPENSSL_NO_SHA +-#ifndef OPENSSL_FIPS + + static int init(EVP_MD_CTX *ctx) + { return SHA1_Init(ctx->md_data); } +@@ -132,7 +131,7 @@ static const EVP_MD ecdsa_md= + NID_ecdsa_with_SHA1, + NID_ecdsa_with_SHA1, + SHA_DIGEST_LENGTH, +- EVP_MD_FLAG_PKEY_DIGEST, ++ EVP_MD_FLAG_PKEY_DIGEST|EVP_MD_FLAG_FIPS, + init, + update, + final, +@@ -148,4 +147,3 @@ const EVP_MD *EVP_ecdsa(void) + return(&ecdsa_md); + } + #endif +-#endif +diff -up openssl-1.0.1e/crypto/fips/Makefile.fips-ec openssl-1.0.1e/crypto/fips/Makefile +--- openssl-1.0.1e/crypto/fips/Makefile.fips-ec 2013-10-15 01:08:06.008783200 +0100 ++++ openssl-1.0.1e/crypto/fips/Makefile 2013-10-15 01:08:17.627767168 +0100 +@@ -24,13 +24,13 @@ 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_enc.c fips_md.c ++ fips_cmac_selftest.c fips_ecdh_selftest.c fips_ecdsa_selftest.c fips_enc.c fips_md.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_enc.o fips_md.o ++ fips_cmac_selftest.o fips_ecdh_selftest.o fips_ecdsa_selftest.o fips_enc.o fips_md.o + + LIBCRYPTO=-L.. -lcrypto + +@@ -118,6 +118,21 @@ fips_aes_selftest.o: ../../include/opens + fips_aes_selftest.o: ../../include/openssl/safestack.h + fips_aes_selftest.o: ../../include/openssl/stack.h + fips_aes_selftest.o: ../../include/openssl/symhacks.h fips_aes_selftest.c ++fips_cmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_cmac_selftest.o: ../../include/openssl/cmac.h ++fips_cmac_selftest.o: ../../include/openssl/crypto.h ++fips_cmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h ++fips_cmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h ++fips_cmac_selftest.o: ../../include/openssl/lhash.h ++fips_cmac_selftest.o: ../../include/openssl/obj_mac.h ++fips_cmac_selftest.o: ../../include/openssl/objects.h ++fips_cmac_selftest.o: ../../include/openssl/opensslconf.h ++fips_cmac_selftest.o: ../../include/openssl/opensslv.h ++fips_cmac_selftest.o: ../../include/openssl/ossl_typ.h ++fips_cmac_selftest.o: ../../include/openssl/safestack.h ++fips_cmac_selftest.o: ../../include/openssl/stack.h ++fips_cmac_selftest.o: ../../include/openssl/symhacks.h fips_cmac_selftest.c ++fips_cmac_selftest.o: fips_locl.h + fips_des_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h + fips_des_selftest.o: ../../include/openssl/crypto.h + fips_des_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +@@ -231,6 +246,46 @@ fips_dsa_selftest.o: ../../include/opens + fips_dsa_selftest.o: ../../include/openssl/stack.h + fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c + fips_dsa_selftest.o: fips_locl.h ++fips_ecdh_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_ecdh_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h ++fips_ecdh_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h ++fips_ecdh_selftest.o: ../../include/openssl/ecdh.h ../../include/openssl/err.h ++fips_ecdh_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h ++fips_ecdh_selftest.o: ../../include/openssl/lhash.h ++fips_ecdh_selftest.o: ../../include/openssl/obj_mac.h ++fips_ecdh_selftest.o: ../../include/openssl/objects.h ++fips_ecdh_selftest.o: ../../include/openssl/opensslconf.h ++fips_ecdh_selftest.o: ../../include/openssl/opensslv.h ++fips_ecdh_selftest.o: ../../include/openssl/ossl_typ.h ++fips_ecdh_selftest.o: ../../include/openssl/safestack.h ++fips_ecdh_selftest.o: ../../include/openssl/stack.h ++fips_ecdh_selftest.o: ../../include/openssl/symhacks.h fips_ecdh_selftest.c ++fips_ecdh_selftest.o: fips_locl.h ++fips_ecdsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_ecdsa_selftest.o: ../../include/openssl/bn.h ++fips_ecdsa_selftest.o: ../../include/openssl/crypto.h ++fips_ecdsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h ++fips_ecdsa_selftest.o: ../../include/openssl/ecdsa.h ++fips_ecdsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h ++fips_ecdsa_selftest.o: ../../include/openssl/fips.h ++fips_ecdsa_selftest.o: ../../include/openssl/lhash.h ++fips_ecdsa_selftest.o: ../../include/openssl/obj_mac.h ++fips_ecdsa_selftest.o: ../../include/openssl/objects.h ++fips_ecdsa_selftest.o: ../../include/openssl/opensslconf.h ++fips_ecdsa_selftest.o: ../../include/openssl/opensslv.h ++fips_ecdsa_selftest.o: ../../include/openssl/ossl_typ.h ++fips_ecdsa_selftest.o: ../../include/openssl/safestack.h ++fips_ecdsa_selftest.o: ../../include/openssl/stack.h ++fips_ecdsa_selftest.o: ../../include/openssl/symhacks.h fips_ecdsa_selftest.c ++fips_enc.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h ++fips_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h ++fips_enc.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h ++fips_enc.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h ++fips_enc.o: ../../include/openssl/opensslconf.h ++fips_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h ++fips_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h ++fips_enc.o: ../../include/openssl/symhacks.h fips_enc.c + fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h + fips_hmac_selftest.o: ../../include/openssl/crypto.h + fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +@@ -245,6 +300,15 @@ fips_hmac_selftest.o: ../../include/open + fips_hmac_selftest.o: ../../include/openssl/safestack.h + fips_hmac_selftest.o: ../../include/openssl/stack.h + fips_hmac_selftest.o: ../../include/openssl/symhacks.h fips_hmac_selftest.c ++fips_md.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_md.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h ++fips_md.o: ../../include/openssl/err.h ../../include/openssl/evp.h ++fips_md.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h ++fips_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h ++fips_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h ++fips_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h ++fips_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h ++fips_md.o: fips_md.c + fips_post.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h + fips_post.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h + fips_post.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c.fips-ec openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c.fips-ec 2013-10-15 01:08:06.047783146 +0100 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c 2013-10-15 01:08:06.047783146 +0100 +@@ -0,0 +1,496 @@ ++/* fips/ecdh/fips_ecdhvs.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * 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 ++ * licensing@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. ++ * ==================================================================== ++ */ ++ ++ ++#define OPENSSL_FIPSAPI ++#include ++ ++#ifndef OPENSSL_FIPS ++#include ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS ECDH support\n"); ++ return(0); ++} ++#else ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fips_utl.h" ++ ++static const EVP_MD *eparse_md(char *line) ++ { ++ char *p; ++ if (line[0] != '[' || line[1] != 'E') ++ return NULL; ++ p = strchr(line, '-'); ++ if (!p) ++ return NULL; ++ line = p + 1; ++ p = strchr(line, ']'); ++ if (!p) ++ return NULL; ++ *p = 0; ++ p = line; ++ while(isspace(*p)) ++ p++; ++ if (!strcmp(p, "SHA1")) ++ return EVP_sha1(); ++ else if (!strcmp(p, "SHA224")) ++ return EVP_sha224(); ++ else if (!strcmp(p, "SHA256")) ++ return EVP_sha256(); ++ else if (!strcmp(p, "SHA384")) ++ return EVP_sha384(); ++ else if (!strcmp(p, "SHA512")) ++ return EVP_sha512(); ++ else ++ return NULL; ++ } ++ ++static int lookup_curve2(char *cname) ++ { ++ char *p; ++ p = strchr(cname, ']'); ++ if (!p) ++ { ++ fprintf(stderr, "Parse error: missing ]\n"); ++ return NID_undef; ++ } ++ *p = 0; ++ ++ if (!strcmp(cname, "B-163")) ++ return NID_sect163r2; ++ if (!strcmp(cname, "B-233")) ++ return NID_sect233r1; ++ if (!strcmp(cname, "B-283")) ++ return NID_sect283r1; ++ if (!strcmp(cname, "B-409")) ++ return NID_sect409r1; ++ if (!strcmp(cname, "B-571")) ++ return NID_sect571r1; ++ if (!strcmp(cname, "K-163")) ++ return NID_sect163k1; ++ if (!strcmp(cname, "K-233")) ++ return NID_sect233k1; ++ if (!strcmp(cname, "K-283")) ++ return NID_sect283k1; ++ if (!strcmp(cname, "K-409")) ++ return NID_sect409k1; ++ if (!strcmp(cname, "K-571")) ++ return NID_sect571k1; ++ if (!strcmp(cname, "P-192")) ++ return NID_X9_62_prime192v1; ++ if (!strcmp(cname, "P-224")) ++ return NID_secp224r1; ++ if (!strcmp(cname, "P-256")) ++ return NID_X9_62_prime256v1; ++ if (!strcmp(cname, "P-384")) ++ return NID_secp384r1; ++ if (!strcmp(cname, "P-521")) ++ return NID_secp521r1; ++ ++ fprintf(stderr, "Unknown Curve name %s\n", cname); ++ return NID_undef; ++ } ++ ++static int lookup_curve(char *cname) ++ { ++ char *p; ++ p = strchr(cname, ':'); ++ if (!p) ++ { ++ fprintf(stderr, "Parse error: missing :\n"); ++ return NID_undef; ++ } ++ cname = p + 1; ++ while(isspace(*cname)) ++ cname++; ++ return lookup_curve2(cname); ++ } ++ ++static EC_POINT *make_peer(EC_GROUP *group, BIGNUM *x, BIGNUM *y) ++ { ++ EC_POINT *peer; ++ int rv; ++ BN_CTX *c; ++ peer = EC_POINT_new(group); ++ if (!peer) ++ return NULL; ++ c = BN_CTX_new(); ++ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ++ == NID_X9_62_prime_field) ++ rv = EC_POINT_set_affine_coordinates_GFp(group, peer, x, y, c); ++ else ++#ifdef OPENSSL_NO_EC2M ++ { ++ fprintf(stderr, "ERROR: GF2m not supported\n"); ++ exit(1); ++ } ++#else ++ rv = EC_POINT_set_affine_coordinates_GF2m(group, peer, x, y, c); ++#endif ++ ++ BN_CTX_free(c); ++ if (rv) ++ return peer; ++ EC_POINT_free(peer); ++ return NULL; ++ } ++ ++static int ec_print_key(FILE *out, EC_KEY *key, int add_e, int exout) ++ { ++ const EC_POINT *pt; ++ const EC_GROUP *grp; ++ const EC_METHOD *meth; ++ int rv; ++ BIGNUM *tx, *ty; ++ const BIGNUM *d = NULL; ++ BN_CTX *ctx; ++ ctx = BN_CTX_new(); ++ if (!ctx) ++ return 0; ++ tx = BN_CTX_get(ctx); ++ ty = BN_CTX_get(ctx); ++ if (!tx || !ty) ++ return 0; ++ grp = EC_KEY_get0_group(key); ++ pt = EC_KEY_get0_public_key(key); ++ if (exout) ++ d = EC_KEY_get0_private_key(key); ++ meth = EC_GROUP_method_of(grp); ++ if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) ++ rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, tx, ty, ctx); ++ else ++#ifdef OPENSSL_NO_EC2M ++ { ++ fprintf(stderr, "ERROR: GF2m not supported\n"); ++ exit(1); ++ } ++#else ++ rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, tx, ty, ctx); ++#endif ++ ++ if (add_e) ++ { ++ do_bn_print_name(out, "QeIUTx", tx); ++ do_bn_print_name(out, "QeIUTy", ty); ++ if (d) ++ do_bn_print_name(out, "QeIUTd", d); ++ } ++ else ++ { ++ do_bn_print_name(out, "QIUTx", tx); ++ do_bn_print_name(out, "QIUTy", ty); ++ if (d) ++ do_bn_print_name(out, "QIUTd", d); ++ } ++ ++ BN_CTX_free(ctx); ++ ++ return rv; ++ ++ } ++ ++static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group, ++ BIGNUM *ix, BIGNUM *iy, BIGNUM *id, BIGNUM *cx, ++ BIGNUM *cy, const EVP_MD *md, ++ unsigned char *rhash, size_t rhashlen) ++ { ++ EC_KEY *ec = NULL; ++ EC_POINT *peerkey = NULL; ++ unsigned char *Z; ++ unsigned char chash[EVP_MAX_MD_SIZE]; ++ int Zlen; ++ ec = EC_KEY_new(); ++ EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH); ++ EC_KEY_set_group(ec, group); ++ peerkey = make_peer(group, cx, cy); ++ if (rhash == NULL) ++ { ++ if (md) ++ rhashlen = M_EVP_MD_size(md); ++ EC_KEY_generate_key(ec); ++ ec_print_key(out, ec, md ? 1 : 0, exout); ++ } ++ else ++ { ++ EC_KEY_set_public_key_affine_coordinates(ec, ix, iy); ++ EC_KEY_set_private_key(ec, id); ++ } ++ Zlen = (EC_GROUP_get_degree(group) + 7)/8; ++ Z = OPENSSL_malloc(Zlen); ++ if (!Z) ++ exit(1); ++ ECDH_compute_key(Z, Zlen, peerkey, ec, 0); ++ if (md) ++ { ++ if (exout) ++ OutputValue("Z", Z, Zlen, out, 0); ++ FIPS_digest(Z, Zlen, chash, NULL, md); ++ OutputValue(rhash ? "IUTHashZZ" : "HashZZ", ++ chash, rhashlen, out, 0); ++ if (rhash) ++ { ++ fprintf(out, "Result = %s\n", ++ memcmp(chash, rhash, rhashlen) ? "F" : "P"); ++ } ++ } ++ else ++ OutputValue("ZIUT", Z, Zlen, out, 0); ++ OPENSSL_cleanse(Z, Zlen); ++ OPENSSL_free(Z); ++ EC_KEY_free(ec); ++ EC_POINT_free(peerkey); ++ } ++ ++#ifdef FIPS_ALGVS ++int fips_ecdhvs_main(int argc, char **argv) ++#else ++int main(int argc, char **argv) ++#endif ++ { ++ char **args = argv + 1; ++ int argn = argc - 1; ++ FILE *in, *out; ++ char buf[2048], lbuf[2048]; ++ unsigned char *rhash = NULL; ++ long rhashlen; ++ BIGNUM *cx = NULL, *cy = NULL; ++ BIGNUM *id = NULL, *ix = NULL, *iy = NULL; ++ const EVP_MD *md = NULL; ++ EC_GROUP *group = NULL; ++ char *keyword = NULL, *value = NULL; ++ int do_verify = -1, exout = 0; ++ int rv = 1; ++ ++ int curve_nids[5] = {0,0,0,0,0}; ++ int param_set = -1; ++ ++ fips_algtest_init(); ++ ++ if (argn && !strcmp(*args, "ecdhver")) ++ { ++ do_verify = 1; ++ args++; ++ argn--; ++ } ++ else if (argn && !strcmp(*args, "ecdhgen")) ++ { ++ do_verify = 0; ++ args++; ++ argn--; ++ } ++ ++ if (argn && !strcmp(*args, "-exout")) ++ { ++ exout = 1; ++ args++; ++ argn--; ++ } ++ ++ if (do_verify == -1) ++ { ++ fprintf(stderr,"%s [ecdhver|ecdhgen|] [-exout] (infile outfile)\n",argv[0]); ++ exit(1); ++ } ++ ++ if (argn == 2) ++ { ++ in = fopen(*args, "r"); ++ if (!in) ++ { ++ fprintf(stderr, "Error opening input file\n"); ++ exit(1); ++ } ++ out = fopen(args[1], "w"); ++ if (!out) ++ { ++ fprintf(stderr, "Error opening output file\n"); ++ exit(1); ++ } ++ } ++ else if (argn == 0) ++ { ++ in = stdin; ++ out = stdout; ++ } ++ else ++ { ++ fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]); ++ exit(1); ++ } ++ ++ while (fgets(buf, sizeof(buf), in) != NULL) ++ { ++ fputs(buf, out); ++ if (buf[0] == '[' && buf[1] == 'E') ++ { ++ int c = buf[2]; ++ if (c < 'A' || c > 'E') ++ goto parse_error; ++ param_set = c - 'A'; ++ /* If just [E?] then initial paramset */ ++ if (buf[3] == ']') ++ continue; ++ if (group) ++ EC_GROUP_free(group); ++ group = EC_GROUP_new_by_curve_name(curve_nids[c - 'A']); ++ } ++ if (strlen(buf) > 10 && !strncmp(buf, "[Curve", 6)) ++ { ++ int nid; ++ if (param_set == -1) ++ goto parse_error; ++ nid = lookup_curve(buf); ++ if (nid == NID_undef) ++ goto parse_error; ++ curve_nids[param_set] = nid; ++ } ++ ++ if (strlen(buf) > 4 && buf[0] == '[' && buf[2] == '-') ++ { ++ int nid = lookup_curve2(buf + 1); ++ if (nid == NID_undef) ++ goto parse_error; ++ if (group) ++ EC_GROUP_free(group); ++ group = EC_GROUP_new_by_curve_name(nid); ++ if (!group) ++ { ++ fprintf(stderr, "ERROR: unsupported curve %s\n", buf + 1); ++ return 1; ++ } ++ } ++ ++ if (strlen(buf) > 6 && !strncmp(buf, "[E", 2)) ++ { ++ md = eparse_md(buf); ++ if (md == NULL) ++ goto parse_error; ++ continue; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "QeCAVSx") || !strcmp(keyword, "QCAVSx")) ++ { ++ if (!do_hex2bn(&cx, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "QeCAVSy") || !strcmp(keyword, "QCAVSy")) ++ { ++ if (!do_hex2bn(&cy, value)) ++ goto parse_error; ++ if (do_verify == 0) ++ ec_output_Zhash(out, exout, group, ++ NULL, NULL, NULL, ++ cx, cy, md, rhash, rhashlen); ++ } ++ else if (!strcmp(keyword, "deIUT")) ++ { ++ if (!do_hex2bn(&id, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "QeIUTx")) ++ { ++ if (!do_hex2bn(&ix, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "QeIUTy")) ++ { ++ if (!do_hex2bn(&iy, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "CAVSHashZZ")) ++ { ++ if (!md) ++ goto parse_error; ++ rhash = hex2bin_m(value, &rhashlen); ++ if (!rhash || rhashlen != M_EVP_MD_size(md)) ++ goto parse_error; ++ ec_output_Zhash(out, exout, group, ix, iy, id, cx, cy, ++ md, rhash, rhashlen); ++ } ++ } ++ rv = 0; ++ parse_error: ++ if (id) ++ BN_free(id); ++ if (ix) ++ BN_free(ix); ++ if (iy) ++ BN_free(iy); ++ if (cx) ++ BN_free(cx); ++ if (cy) ++ BN_free(cy); ++ if (group) ++ EC_GROUP_free(group); ++ if (in && in != stdin) ++ fclose(in); ++ if (out && out != stdout) ++ fclose(out); ++ if (rv) ++ fprintf(stderr, "Error Parsing request file\n"); ++ return rv; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_ecdsavs.c.fips-ec openssl-1.0.1e/crypto/fips/cavs/fips_ecdsavs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_ecdsavs.c.fips-ec 2013-10-15 01:08:06.047783146 +0100 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_ecdsavs.c 2013-10-15 01:08:06.047783146 +0100 +@@ -0,0 +1,533 @@ ++/* fips/ecdsa/fips_ecdsavs.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * 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 ++ * licensing@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. ++ * ==================================================================== ++ */ ++ ++#define OPENSSL_FIPSAPI ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS ECDSA support\n"); ++ return(0); ++} ++#else ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "fips_utl.h" ++ ++#include ++ ++ ++static int elookup_curve(char *in, char *curve_name, const EVP_MD **pmd) ++ { ++ char *cname, *p; ++ /* Copy buffer as we will change it */ ++ strcpy(curve_name, in); ++ cname = curve_name + 1; ++ p = strchr(cname, ']'); ++ if (!p) ++ { ++ fprintf(stderr, "Parse error: missing ]\n"); ++ return NID_undef; ++ } ++ *p = 0; ++ p = strchr(cname, ','); ++ if (p) ++ { ++ if (!pmd) ++ { ++ fprintf(stderr, "Parse error: unexpected digest\n"); ++ return NID_undef; ++ } ++ *p = 0; ++ p++; ++ ++ if (!strcmp(p, "SHA-1")) ++ *pmd = EVP_sha1(); ++ else if (!strcmp(p, "SHA-224")) ++ *pmd = EVP_sha224(); ++ else if (!strcmp(p, "SHA-256")) ++ *pmd = EVP_sha256(); ++ else if (!strcmp(p, "SHA-384")) ++ *pmd = EVP_sha384(); ++ else if (!strcmp(p, "SHA-512")) ++ *pmd = EVP_sha512(); ++ else ++ { ++ fprintf(stderr, "Unknown digest %s\n", p); ++ return NID_undef; ++ } ++ } ++ else if(pmd) ++ *pmd = EVP_sha1(); ++ ++ if (!strcmp(cname, "B-163")) ++ return NID_sect163r2; ++ if (!strcmp(cname, "B-233")) ++ return NID_sect233r1; ++ if (!strcmp(cname, "B-283")) ++ return NID_sect283r1; ++ if (!strcmp(cname, "B-409")) ++ return NID_sect409r1; ++ if (!strcmp(cname, "B-571")) ++ return NID_sect571r1; ++ if (!strcmp(cname, "K-163")) ++ return NID_sect163k1; ++ if (!strcmp(cname, "K-233")) ++ return NID_sect233k1; ++ if (!strcmp(cname, "K-283")) ++ return NID_sect283k1; ++ if (!strcmp(cname, "K-409")) ++ return NID_sect409k1; ++ if (!strcmp(cname, "K-571")) ++ return NID_sect571k1; ++ if (!strcmp(cname, "P-192")) ++ return NID_X9_62_prime192v1; ++ if (!strcmp(cname, "P-224")) ++ return NID_secp224r1; ++ if (!strcmp(cname, "P-256")) ++ return NID_X9_62_prime256v1; ++ if (!strcmp(cname, "P-384")) ++ return NID_secp384r1; ++ if (!strcmp(cname, "P-521")) ++ return NID_secp521r1; ++ ++ fprintf(stderr, "Unknown Curve name %s\n", cname); ++ return NID_undef; ++ } ++ ++static int ec_get_pubkey(EC_KEY *key, BIGNUM *x, BIGNUM *y) ++ { ++ const EC_POINT *pt; ++ const EC_GROUP *grp; ++ const EC_METHOD *meth; ++ int rv; ++ BN_CTX *ctx; ++ ctx = BN_CTX_new(); ++ if (!ctx) ++ return 0; ++ grp = EC_KEY_get0_group(key); ++ pt = EC_KEY_get0_public_key(key); ++ meth = EC_GROUP_method_of(grp); ++ if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) ++ rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, x, y, ctx); ++ else ++#ifdef OPENSSL_NO_EC2M ++ { ++ fprintf(stderr, "ERROR: GF2m not supported\n"); ++ exit(1); ++ } ++#else ++ rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, x, y, ctx); ++#endif ++ ++ BN_CTX_free(ctx); ++ ++ return rv; ++ ++ } ++ ++static int KeyPair(FILE *in, FILE *out) ++ { ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ int curve_nid = NID_undef; ++ int i, count; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ const BIGNUM *d = NULL; ++ EC_KEY *key = NULL; ++ Qx = BN_new(); ++ Qy = BN_new(); ++ while(fgets(buf, sizeof buf, in) != NULL) ++ { ++ if (*buf == '[' && buf[2] == '-') ++ { ++ if (buf[2] == '-') ++ curve_nid = elookup_curve(buf, lbuf, NULL); ++ fputs(buf, out); ++ continue; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ { ++ fputs(buf, out); ++ continue; ++ } ++ if (!strcmp(keyword, "N")) ++ { ++ count = atoi(value); ++ ++ for (i = 0; i < count; i++) ++ { ++ ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ if (!EC_KEY_generate_key(key)) ++ { ++ fprintf(stderr, "Error generating key\n"); ++ return 0; ++ } ++ ++ if (!ec_get_pubkey(key, Qx, Qy)) ++ { ++ fprintf(stderr, "Error getting public key\n"); ++ return 0; ++ } ++ ++ d = EC_KEY_get0_private_key(key); ++ ++ do_bn_print_name(out, "d", d); ++ do_bn_print_name(out, "Qx", Qx); ++ do_bn_print_name(out, "Qy", Qy); ++ fputs(RESP_EOL, out); ++ EC_KEY_free(key); ++ ++ } ++ ++ } ++ ++ } ++ BN_free(Qx); ++ BN_free(Qy); ++ return 1; ++ } ++ ++static int PKV(FILE *in, FILE *out) ++ { ++ ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ int curve_nid = NID_undef; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ EC_KEY *key = NULL; ++ while(fgets(buf, sizeof buf, in) != NULL) ++ { ++ fputs(buf, out); ++ if (*buf == '[' && buf[2] == '-') ++ { ++ curve_nid = elookup_curve(buf, lbuf, NULL); ++ if (curve_nid == NID_undef) ++ return 0; ++ ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "Qx")) ++ { ++ if (!do_hex2bn(&Qx, value)) ++ { ++ fprintf(stderr, "Invalid Qx value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "Qy")) ++ { ++ int rv; ++ if (!do_hex2bn(&Qy, value)) ++ { ++ fprintf(stderr, "Invalid Qy value\n"); ++ return 0; ++ } ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ no_err = 1; ++ rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy); ++ no_err = 0; ++ EC_KEY_free(key); ++ fprintf(out, "Result = %s" RESP_EOL, rv ? "P":"F"); ++ } ++ ++ } ++ BN_free(Qx); ++ BN_free(Qy); ++ return 1; ++ } ++ ++static int SigGen(FILE *in, FILE *out) ++ { ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ unsigned char *msg; ++ int curve_nid = NID_undef; ++ long mlen; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ EC_KEY *key = NULL; ++ ECDSA_SIG *sig = NULL; ++ const EVP_MD *digest = NULL; ++ Qx = BN_new(); ++ Qy = BN_new(); ++ while(fgets(buf, sizeof buf, in) != NULL) ++ { ++ fputs(buf, out); ++ if (*buf == '[') ++ { ++ curve_nid = elookup_curve(buf, lbuf, &digest); ++ if (curve_nid == NID_undef) ++ return 0; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "Msg")) ++ { ++ msg = hex2bin_m(value, &mlen); ++ if (!msg) ++ { ++ fprintf(stderr, "Invalid Message\n"); ++ return 0; ++ } ++ ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ if (!EC_KEY_generate_key(key)) ++ { ++ fprintf(stderr, "Error generating key\n"); ++ return 0; ++ } ++ ++ if (!ec_get_pubkey(key, Qx, Qy)) ++ { ++ fprintf(stderr, "Error getting public key\n"); ++ return 0; ++ } ++ ++ sig = FIPS_ecdsa_sign(key, msg, mlen, digest); ++ ++ if (!sig) ++ { ++ fprintf(stderr, "Error signing message\n"); ++ return 0; ++ } ++ ++ do_bn_print_name(out, "Qx", Qx); ++ do_bn_print_name(out, "Qy", Qy); ++ do_bn_print_name(out, "R", sig->r); ++ do_bn_print_name(out, "S", sig->s); ++ ++ EC_KEY_free(key); ++ OPENSSL_free(msg); ++ FIPS_ecdsa_sig_free(sig); ++ ++ } ++ ++ } ++ BN_free(Qx); ++ BN_free(Qy); ++ return 1; ++ } ++ ++static int SigVer(FILE *in, FILE *out) ++ { ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ unsigned char *msg = NULL; ++ int curve_nid = NID_undef; ++ long mlen; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ EC_KEY *key = NULL; ++ ECDSA_SIG sg, *sig = &sg; ++ const EVP_MD *digest = NULL; ++ sig->r = NULL; ++ sig->s = NULL; ++ while(fgets(buf, sizeof buf, in) != NULL) ++ { ++ fputs(buf, out); ++ if (*buf == '[') ++ { ++ curve_nid = elookup_curve(buf, lbuf, &digest); ++ if (curve_nid == NID_undef) ++ return 0; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "Msg")) ++ { ++ msg = hex2bin_m(value, &mlen); ++ if (!msg) ++ { ++ fprintf(stderr, "Invalid Message\n"); ++ return 0; ++ } ++ } ++ ++ if (!strcmp(keyword, "Qx")) ++ { ++ if (!do_hex2bn(&Qx, value)) ++ { ++ fprintf(stderr, "Invalid Qx value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "Qy")) ++ { ++ if (!do_hex2bn(&Qy, value)) ++ { ++ fprintf(stderr, "Invalid Qy value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "R")) ++ { ++ if (!do_hex2bn(&sig->r, value)) ++ { ++ fprintf(stderr, "Invalid R value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "S")) ++ { ++ int rv; ++ if (!do_hex2bn(&sig->s, value)) ++ { ++ fprintf(stderr, "Invalid S value\n"); ++ return 0; ++ } ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy); ++ ++ if (rv != 1) ++ { ++ fprintf(stderr, "Error setting public key\n"); ++ return 0; ++ } ++ ++ no_err = 1; ++ rv = FIPS_ecdsa_verify(key, msg, mlen, digest, sig); ++ EC_KEY_free(key); ++ if (msg) ++ OPENSSL_free(msg); ++ no_err = 0; ++ ++ fprintf(out, "Result = %s" RESP_EOL, rv ? "P":"F"); ++ } ++ ++ } ++ if (sig->r) ++ BN_free(sig->r); ++ if (sig->s) ++ BN_free(sig->s); ++ if (Qx) ++ BN_free(Qx); ++ if (Qy) ++ BN_free(Qy); ++ return 1; ++ } ++#ifdef FIPS_ALGVS ++int fips_ecdsavs_main(int argc, char **argv) ++#else ++int main(int argc, char **argv) ++#endif ++ { ++ FILE *in = NULL, *out = NULL; ++ const char *cmd = argv[1]; ++ int rv = 0; ++ fips_algtest_init(); ++ ++ if (argc == 4) ++ { ++ in = fopen(argv[2], "r"); ++ if (!in) ++ { ++ fprintf(stderr, "Error opening input file\n"); ++ exit(1); ++ } ++ out = fopen(argv[3], "w"); ++ if (!out) ++ { ++ fprintf(stderr, "Error opening output file\n"); ++ exit(1); ++ } ++ } ++ else if (argc == 2) ++ { ++ in = stdin; ++ out = stdout; ++ } ++ ++ if (!cmd) ++ { ++ fprintf(stderr, "fips_ecdsavs [KeyPair|PKV|SigGen|SigVer]\n"); ++ return 1; ++ } ++ if (!strcmp(cmd, "KeyPair")) ++ rv = KeyPair(in, out); ++ else if (!strcmp(cmd, "PKV")) ++ rv = PKV(in, out); ++ else if (!strcmp(cmd, "SigVer")) ++ rv = SigVer(in, out); ++ else if (!strcmp(cmd, "SigGen")) ++ rv = SigGen(in, out); ++ else ++ { ++ fprintf(stderr, "Unknown command %s\n", cmd); ++ return 1; ++ } ++ ++ if (argc == 4) ++ { ++ fclose(in); ++ fclose(out); ++ } ++ ++ if (rv <= 0) ++ { ++ fprintf(stderr, "Error running %s\n", cmd); ++ return 1; ++ } ++ ++ return 0; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/fips.h.fips-ec openssl-1.0.1e/crypto/fips/fips.h +--- openssl-1.0.1e/crypto/fips/fips.h.fips-ec 2013-10-15 01:08:06.037783160 +0100 ++++ openssl-1.0.1e/crypto/fips/fips.h 2013-10-15 01:08:06.048783145 +0100 +@@ -94,6 +94,8 @@ int FIPS_selftest_rsa(void); + void FIPS_corrupt_dsa(void); + void FIPS_corrupt_dsa_keygen(void); + int FIPS_selftest_dsa(void); ++int FIPS_selftest_ecdsa(void); ++int FIPS_selftest_ecdh(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_ecdh_selftest.c.fips-ec openssl-1.0.1e/crypto/fips/fips_ecdh_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_ecdh_selftest.c.fips-ec 2013-10-15 01:08:06.048783145 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_ecdh_selftest.c 2013-10-15 01:08:06.048783145 +0100 +@@ -0,0 +1,252 @@ ++/* fips/ecdh/fips_ecdh_selftest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2011. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * 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 ++ * licensing@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. ++ * ==================================================================== ++ * ++ */ ++ ++#define OPENSSL_FIPSAPI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++#include "fips_locl.h" ++ ++static const unsigned char p256_qcavsx[] = { ++ 0x52,0xc6,0xa5,0x75,0xf3,0x04,0x98,0xb3,0x29,0x66,0x0c,0x62, ++ 0x18,0x60,0x55,0x41,0x59,0xd4,0x60,0x85,0x99,0xc1,0x51,0x13, ++ 0x6f,0x97,0x85,0x93,0x33,0x34,0x07,0x50 ++}; ++static const unsigned char p256_qcavsy[] = { ++ 0x6f,0x69,0x24,0xeb,0xe9,0x3b,0xa7,0xcc,0x47,0x17,0xaa,0x3f, ++ 0x70,0xfc,0x10,0x73,0x0a,0xcd,0x21,0xee,0x29,0x19,0x1f,0xaf, ++ 0xb4,0x1c,0x1e,0xc2,0x8e,0x97,0x81,0x6e ++}; ++static const unsigned char p256_qiutx[] = { ++ 0x71,0x46,0x88,0x08,0x92,0x21,0x1b,0x10,0x21,0x74,0xff,0x0c, ++ 0x94,0xde,0x34,0x7c,0x86,0x74,0xbe,0x67,0x41,0x68,0xd4,0xc1, ++ 0xe5,0x75,0x63,0x9c,0xa7,0x46,0x93,0x6f ++}; ++static const unsigned char p256_qiuty[] = { ++ 0x33,0x40,0xa9,0x6a,0xf5,0x20,0xb5,0x9e,0xfc,0x60,0x1a,0xae, ++ 0x3d,0xf8,0x21,0xd2,0xa7,0xca,0x52,0x34,0xb9,0x5f,0x27,0x75, ++ 0x6c,0x81,0xbe,0x32,0x4d,0xba,0xbb,0xf8 ++}; ++static const unsigned char p256_qiutd[] = { ++ 0x1a,0x48,0x55,0x6b,0x11,0xbe,0x92,0xd4,0x1c,0xd7,0x45,0xc3, ++ 0x82,0x81,0x51,0xf1,0x23,0x40,0xb7,0x83,0xfd,0x01,0x6d,0xbc, ++ 0xa1,0x66,0xaf,0x0a,0x03,0x23,0xcd,0xc8 ++}; ++static const unsigned char p256_ziut[] = { ++ 0x77,0x2a,0x1e,0x37,0xee,0xe6,0x51,0x02,0x71,0x40,0xf8,0x6a, ++ 0x36,0xf8,0x65,0x61,0x2b,0x18,0x71,0x82,0x23,0xe6,0xf2,0x77, ++ 0xce,0xec,0xb8,0x49,0xc7,0xbf,0x36,0x4f ++}; ++ ++ ++typedef struct ++ { ++ int curve; ++ const unsigned char *x1; ++ size_t x1len; ++ const unsigned char *y1; ++ size_t y1len; ++ const unsigned char *d1; ++ size_t d1len; ++ const unsigned char *x2; ++ size_t x2len; ++ const unsigned char *y2; ++ size_t y2len; ++ const unsigned char *z; ++ size_t zlen; ++ } ECDH_SELFTEST_DATA; ++ ++#define make_ecdh_test(nid, pr) { nid, \ ++ pr##_qiutx, sizeof(pr##_qiutx), \ ++ pr##_qiuty, sizeof(pr##_qiuty), \ ++ pr##_qiutd, sizeof(pr##_qiutd), \ ++ pr##_qcavsx, sizeof(pr##_qcavsx), \ ++ pr##_qcavsy, sizeof(pr##_qcavsy), \ ++ pr##_ziut, sizeof(pr##_ziut) } ++ ++static ECDH_SELFTEST_DATA test_ecdh_data[] = ++ { ++ make_ecdh_test(NID_X9_62_prime256v1, p256), ++ }; ++ ++int FIPS_selftest_ecdh(void) ++ { ++ EC_KEY *ec1 = NULL, *ec2 = NULL; ++ const EC_POINT *ecp = NULL; ++ BIGNUM *x = NULL, *y = NULL, *d = NULL; ++ unsigned char *ztmp = NULL; ++ int rv = 1; ++ size_t i; ++ ++ for (i = 0; i < sizeof(test_ecdh_data)/sizeof(ECDH_SELFTEST_DATA); i++) ++ { ++ ECDH_SELFTEST_DATA *ecd = test_ecdh_data + i; ++ if (!fips_post_started(FIPS_TEST_ECDH, ecd->curve, 0)) ++ continue; ++ ztmp = OPENSSL_malloc(ecd->zlen); ++ ++ x = BN_bin2bn(ecd->x1, ecd->x1len, x); ++ y = BN_bin2bn(ecd->y1, ecd->y1len, y); ++ d = BN_bin2bn(ecd->d1, ecd->d1len, d); ++ ++ if (!x || !y || !d || !ztmp) ++ { ++ rv = -1; ++ goto err; ++ } ++ ++ ec1 = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec1) ++ { ++ rv = -1; ++ goto err; ++ } ++ EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y)) ++ { ++ rv = -1; ++ goto err; ++ } ++ ++ if (!EC_KEY_set_private_key(ec1, d)) ++ { ++ rv = -1; ++ goto err; ++ } ++ ++ x = BN_bin2bn(ecd->x2, ecd->x2len, x); ++ y = BN_bin2bn(ecd->y2, ecd->y2len, y); ++ ++ if (!x || !y) ++ { ++ rv = -1; ++ goto err; ++ } ++ ++ ec2 = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec2) ++ { ++ rv = -1; ++ goto err; ++ } ++ EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y)) ++ { ++ rv = -1; ++ goto err; ++ } ++ ++ ecp = EC_KEY_get0_public_key(ec2); ++ if (!ecp) ++ { ++ rv = -1; ++ goto err; ++ } ++ ++ if (!ECDH_compute_key(ztmp, ecd->zlen, ecp, ec1, 0)) ++ { ++ rv = -1; ++ goto err; ++ } ++ ++ if (!fips_post_corrupt(FIPS_TEST_ECDH, ecd->curve, NULL)) ++ ztmp[0] ^= 0x1; ++ ++ if (memcmp(ztmp, ecd->z, ecd->zlen)) ++ { ++ fips_post_failed(FIPS_TEST_ECDH, ecd->curve, 0); ++ rv = 0; ++ } ++ else if (!fips_post_success(FIPS_TEST_ECDH, ecd->curve, 0)) ++ goto err; ++ ++ EC_KEY_free(ec1); ++ ec1 = NULL; ++ EC_KEY_free(ec2); ++ ec2 = NULL; ++ OPENSSL_free(ztmp); ++ ztmp = NULL; ++ } ++ ++ err: ++ ++ if (x) ++ BN_clear_free(x); ++ if (y) ++ BN_clear_free(y); ++ if (d) ++ BN_clear_free(d); ++ if (ec1) ++ EC_KEY_free(ec1); ++ if (ec2) ++ EC_KEY_free(ec2); ++ if (ztmp) ++ OPENSSL_free(ztmp); ++ ++ return rv; ++ ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/fips_ecdsa_selftest.c.fips-ec openssl-1.0.1e/crypto/fips/fips_ecdsa_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_ecdsa_selftest.c.fips-ec 2013-10-15 01:08:06.048783145 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_ecdsa_selftest.c 2013-10-15 01:08:06.048783145 +0100 +@@ -0,0 +1,167 @@ ++/* fips/ecdsa/fips_ecdsa_selftest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2011. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * 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 ++ * licensing@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. ++ * ==================================================================== ++ * ++ */ ++ ++#define OPENSSL_FIPSAPI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++static const char P_256_name[] = "ECDSA P-256"; ++ ++static const unsigned char P_256_d[] = { ++ 0x51,0xbd,0x06,0xa1,0x1c,0xda,0xe2,0x12,0x99,0xc9,0x52,0x3f, ++ 0xea,0xa4,0xd2,0xd1,0xf4,0x7f,0xd4,0x3e,0xbd,0xf8,0xfc,0x87, ++ 0xdc,0x82,0x53,0x21,0xee,0xa0,0xdc,0x64 ++}; ++static const unsigned char P_256_qx[] = { ++ 0x23,0x89,0xe0,0xf4,0x69,0xe0,0x49,0xe5,0xc7,0xe5,0x40,0x6e, ++ 0x8f,0x25,0xdd,0xad,0x11,0x16,0x14,0x9b,0xab,0x44,0x06,0x31, ++ 0xbf,0x5e,0xa6,0x44,0xac,0x86,0x00,0x07 ++}; ++static const unsigned char P_256_qy[] = { ++ 0xb3,0x05,0x0d,0xd0,0xdc,0xf7,0x40,0xe6,0xf9,0xd8,0x6d,0x7b, ++ 0x63,0xca,0x97,0xe6,0x12,0xf9,0xd4,0x18,0x59,0xbe,0xb2,0x5e, ++ 0x4a,0x6a,0x77,0x23,0xf4,0x11,0x9d,0xeb ++}; ++ ++typedef struct ++ { ++ int curve; ++ const char *name; ++ const unsigned char *x; ++ size_t xlen; ++ const unsigned char *y; ++ size_t ylen; ++ const unsigned char *d; ++ size_t dlen; ++ } EC_SELFTEST_DATA; ++ ++#define make_ecdsa_test(nid, pr) { nid, pr##_name, \ ++ pr##_qx, sizeof(pr##_qx), \ ++ pr##_qy, sizeof(pr##_qy), \ ++ pr##_d, sizeof(pr##_d)} ++ ++static EC_SELFTEST_DATA test_ec_data[] = ++ { ++ make_ecdsa_test(NID_X9_62_prime256v1, P_256), ++ }; ++ ++int FIPS_selftest_ecdsa() ++ { ++ EC_KEY *ec = NULL; ++ BIGNUM *x = NULL, *y = NULL, *d = NULL; ++ EVP_PKEY *pk = NULL; ++ int rv = 0; ++ size_t i; ++ ++ for (i = 0; i < sizeof(test_ec_data)/sizeof(EC_SELFTEST_DATA); i++) ++ { ++ EC_SELFTEST_DATA *ecd = test_ec_data + i; ++ ++ x = BN_bin2bn(ecd->x, ecd->xlen, x); ++ y = BN_bin2bn(ecd->y, ecd->ylen, y); ++ d = BN_bin2bn(ecd->d, ecd->dlen, d); ++ ++ if (!x || !y || !d) ++ goto err; ++ ++ ec = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec) ++ goto err; ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec, x, y)) ++ goto err; ++ ++ if (!EC_KEY_set_private_key(ec, d)) ++ goto err; ++ ++ if ((pk=EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_assign_EC_KEY(pk, ec); ++ ++ if (!fips_pkey_signature_test(pk, NULL, 0, ++ NULL, 0, EVP_sha256(), 0, ++ ecd->name)) ++ goto err; ++ } ++ ++ rv = 1; ++ ++ err: ++ ++ if (x) ++ BN_clear_free(x); ++ if (y) ++ BN_clear_free(y); ++ if (d) ++ BN_clear_free(d); ++ if (pk) ++ EVP_PKEY_free(pk); ++ else if (ec) ++ EC_KEY_free(ec); ++ ++ return rv; ++ ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/fips_post.c.fips-ec openssl-1.0.1e/crypto/fips/fips_post.c +--- openssl-1.0.1e/crypto/fips/fips_post.c.fips-ec 2013-10-15 01:08:06.005783204 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_post.c 2013-10-15 01:08:06.048783145 +0100 +@@ -95,8 +95,12 @@ int FIPS_selftest(void) + rv = 0; + if (!FIPS_selftest_rsa()) + rv = 0; ++ if (!FIPS_selftest_ecdsa()) ++ rv = 0; + if (!FIPS_selftest_dsa()) + rv = 0; ++ if (!FIPS_selftest_ecdh()) ++ rv = 0; + return rv; + } + +diff -up openssl-1.0.1e/version.map.fips-ec openssl-1.0.1e/version.map +--- openssl-1.0.1e/version.map.fips-ec 2013-10-15 01:08:06.016783189 +0100 ++++ openssl-1.0.1e/version.map 2013-10-15 01:08:06.048783145 +0100 +@@ -6,3 +6,7 @@ OPENSSL_1.0.1 { + _original*; + _current*; + }; ++OPENSSL_1.0.1_EC { ++ global: ++ EC*; ++}; diff --git a/openssl.spec b/openssl.spec index 248c5a9..32be3c9 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: 26%{?dist} +Release: 27%{?dist} Epoch: 1 # We have to remove certain patented algorithms from the openssl source # tarball with the hobble-openssl script which is included below. @@ -77,6 +77,7 @@ Patch82: openssl-1.0.1e-backports.patch Patch83: openssl-1.0.1e-bad-mac.patch Patch84: openssl-1.0.1e-trusted-first.patch Patch85: openssl-1.0.1e-arm-use-elf-auxv-caps.patch +Patch86: openssl-1.0.1e-fips-ec.patch License: OpenSSL Group: System Environment/Libraries @@ -197,6 +198,7 @@ OpenSSL FIPS module. %patch83 -p1 -b .bad-mac %patch84 -p1 -b .trusted-first %patch85 -p1 -b .armcap +%patch86 -p1 -b .fips-ec sed -i 's/SHLIB_VERSION_NUMBER "1.0.0"/SHLIB_VERSION_NUMBER "%{version}"/' crypto/opensslv.h @@ -251,7 +253,7 @@ sslarch=linux-ppc64 ./Configure \ --prefix=%{_prefix} --openssldir=%{_sysconfdir}/pki/tls ${sslflags} \ zlib enable-camellia enable-seed enable-tlsext enable-rfc3779 \ - enable-cms enable-md2 no-mdc2 no-rc5 no-ec no-ec2m no-ecdh no-ecdsa no-srp \ + enable-cms enable-md2 no-mdc2 no-rc5 no-srp \ --with-krb5-flavor=MIT --enginesdir=%{_libdir}/openssl/engines \ --with-krb5-dir=/usr shared ${sslarch} %{?!nofips:fips} @@ -473,6 +475,9 @@ rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.* prelink -u %{_libdir}/libcrypto.so.%{version} %{_libdir}/libssl.so.%{version} 2>/dev/null || : %changelog +* Mon Oct 14 2013 Tom Callaway - 1.0.1e-27 +- resolve bugzilla 319901 (phew! only took 6 years & 9 days) + * Fri Sep 27 2013 Tomáš Mráz 1.0.1e-26 - make DTLS1 work in FIPS mode - avoid RSA and DSA 512 bits and Whirlpool in 'openssl speed' in FIPS mode diff --git a/sources b/sources index f4ba3a1..d5abaf8 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -641677c116865e60601677329b514e2d openssl-1.0.1e-usa.tar.xz +3b0845cfbbb2af350ef3b026f8dfcd5f openssl-1.0.1e-usa.tar.xz