diff -up openssl-1.0.0k/Configure.fips openssl-1.0.0k/Configure --- openssl-1.0.0k/Configure.fips 2013-02-19 20:12:54.536663757 +0100 +++ openssl-1.0.0k/Configure 2013-02-19 20:12:54.574664476 +0100 @@ -664,6 +664,7 @@ my $cmll_enc="camellia.o cmll_misc.o cml my $processor=""; my $default_ranlib; my $perl; +my $fips=0; # All of the following is disabled by default (RC5 was enabled before 0.9.8): @@ -810,6 +811,10 @@ PROCESS_ARGS: } elsif (/^386$/) { $processor=386; } + elsif (/^fips$/) + { + $fips=1; + } elsif (/^rsaref$/) { # No RSAref support any more since it's not needed. @@ -1386,6 +1391,11 @@ $cflags.=" -DOPENSSL_IA32_SSE2" if (!$no $cflags.=" -DOPENSSL_BN_ASM_MONT" if ($bn_obj =~ /-mont/); +if ($fips) + { + $openssl_other_defines.="#define OPENSSL_FIPS\n"; + } + $cpuid_obj="mem_clr.o" unless ($cpuid_obj =~ /\.o$/); $des_obj=$des_enc unless ($des_obj =~ /\.o$/); $bf_obj=$bf_enc unless ($bf_obj =~ /\.o$/); @@ -1553,6 +1563,10 @@ while () s/^LIBKRB5=.*/LIBKRB5=$withargs{"krb5-lib"}/; s/^LIBZLIB=.*/LIBZLIB=$withargs{"zlib-lib"}/; s/^ZLIB_INCLUDE=.*/ZLIB_INCLUDE=$withargs{"zlib-include"}/; + if ($fips) + { + s/^FIPS=.*/FIPS=yes/; + } s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/; s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/; s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared); diff -up openssl-1.0.0k/crypto/bf/bf_skey.c.fips openssl-1.0.0k/crypto/bf/bf_skey.c --- openssl-1.0.0k/crypto/bf/bf_skey.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/bf/bf_skey.c 2013-02-19 20:12:54.574664476 +0100 @@ -59,10 +59,15 @@ #include #include #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + #include "bf_locl.h" #include "bf_pi.h" -void BF_set_key(BF_KEY *key, int len, const unsigned char *data) +FIPS_NON_FIPS_VCIPHER_Init(BF) { int i; BF_LONG *p,ri,in[2]; diff -up openssl-1.0.0k/crypto/bf/blowfish.h.fips openssl-1.0.0k/crypto/bf/blowfish.h --- openssl-1.0.0k/crypto/bf/blowfish.h.fips 2013-02-19 20:12:53.998653547 +0100 +++ openssl-1.0.0k/crypto/bf/blowfish.h 2013-02-19 20:12:54.575664496 +0100 @@ -104,7 +104,9 @@ typedef struct bf_key_st BF_LONG S[4*256]; } BF_KEY; - +#ifdef OPENSSL_FIPS +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data); +#endif void BF_set_key(BF_KEY *key, int len, const unsigned char *data); void BF_encrypt(BF_LONG *data,const BF_KEY *key); diff -up openssl-1.0.0k/crypto/bn/bn.h.fips openssl-1.0.0k/crypto/bn/bn.h --- openssl-1.0.0k/crypto/bn/bn.h.fips 2013-02-19 20:12:54.135656147 +0100 +++ openssl-1.0.0k/crypto/bn/bn.h 2013-02-19 20:12:54.575664496 +0100 @@ -558,6 +558,17 @@ int BN_is_prime_ex(const BIGNUM *p,int n int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, int do_trial_division, BN_GENCB *cb); +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + BIGNUM *Xp1, BIGNUM *Xp2, + const BIGNUM *Xp, + const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); + BN_MONT_CTX *BN_MONT_CTX_new(void ); void BN_MONT_CTX_init(BN_MONT_CTX *ctx); int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b, diff -up openssl-1.0.0k/crypto/bn/bn_x931p.c.fips openssl-1.0.0k/crypto/bn/bn_x931p.c --- openssl-1.0.0k/crypto/bn/bn_x931p.c.fips 2013-02-19 20:12:54.575664496 +0100 +++ openssl-1.0.0k/crypto/bn/bn_x931p.c 2013-02-19 20:12:54.576664516 +0100 @@ -0,0 +1,272 @@ +/* bn_x931p.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +/* X9.31 routines for prime derivation */ + +/* X9.31 prime derivation. This is used to generate the primes pi + * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd + * integers. + */ + +static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, + BN_GENCB *cb) + { + int i = 0; + if (!BN_copy(pi, Xpi)) + return 0; + if (!BN_is_odd(pi) && !BN_add_word(pi, 1)) + return 0; + for(;;) + { + i++; + BN_GENCB_call(cb, 0, i); + /* NB 27 MR is specificed in X9.31 */ + if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb)) + break; + if (!BN_add_word(pi, 2)) + return 0; + } + BN_GENCB_call(cb, 2, i); + return 1; + } + +/* This is the main X9.31 prime derivation function. From parameters + * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are + * not NULL they will be returned too: this is needed for testing. + */ + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb) + { + int ret = 0; + + BIGNUM *t, *p1p2, *pm1; + + /* Only even e supported */ + if (!BN_is_odd(e)) + return 0; + + BN_CTX_start(ctx); + if (!p1) + p1 = BN_CTX_get(ctx); + + if (!p2) + p2 = BN_CTX_get(ctx); + + t = BN_CTX_get(ctx); + + p1p2 = BN_CTX_get(ctx); + + pm1 = BN_CTX_get(ctx); + + if (!bn_x931_derive_pi(p1, Xp1, ctx, cb)) + goto err; + + if (!bn_x931_derive_pi(p2, Xp2, ctx, cb)) + goto err; + + if (!BN_mul(p1p2, p1, p2, ctx)) + goto err; + + /* First set p to value of Rp */ + + if (!BN_mod_inverse(p, p2, p1, ctx)) + goto err; + + if (!BN_mul(p, p, p2, ctx)) + goto err; + + if (!BN_mod_inverse(t, p1, p2, ctx)) + goto err; + + if (!BN_mul(t, t, p1, ctx)) + goto err; + + if (!BN_sub(p, p, t)) + goto err; + + if (p->neg && !BN_add(p, p, p1p2)) + goto err; + + /* p now equals Rp */ + + if (!BN_mod_sub(p, p, Xp, p1p2, ctx)) + goto err; + + if (!BN_add(p, p, Xp)) + goto err; + + /* p now equals Yp0 */ + + for (;;) + { + int i = 1; + BN_GENCB_call(cb, 0, i++); + if (!BN_copy(pm1, p)) + goto err; + if (!BN_sub_word(pm1, 1)) + goto err; + if (!BN_gcd(t, pm1, e, ctx)) + goto err; + if (BN_is_one(t) + /* X9.31 specifies 8 MR and 1 Lucas test or any prime test + * offering similar or better guarantees 50 MR is considerably + * better. + */ + && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb)) + break; + if (!BN_add(p, p, p1p2)) + goto err; + } + + BN_GENCB_call(cb, 3, 0); + + ret = 1; + + err: + + BN_CTX_end(ctx); + + return ret; + } + +/* Generate pair of paramters Xp, Xq for X9.31 prime generation. + * Note: nbits paramter is sum of number of bits in both. + */ + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) + { + BIGNUM *t; + int i; + /* Number of bits for each prime is of the form + * 512+128s for s = 0, 1, ... + */ + if ((nbits < 1024) || (nbits & 0xff)) + return 0; + nbits >>= 1; + /* The random value Xp must be between sqrt(2) * 2^(nbits-1) and + * 2^nbits - 1. By setting the top two bits we ensure that the lower + * bound is exceeded. + */ + if (!BN_rand(Xp, nbits, 1, 0)) + return 0; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + + for (i = 0; i < 1000; i++) + { + if (!BN_rand(Xq, nbits, 1, 0)) + return 0; + /* Check that |Xp - Xq| > 2^(nbits - 100) */ + BN_sub(t, Xp, Xq); + if (BN_num_bits(t) > (nbits - 100)) + break; + } + + BN_CTX_end(ctx); + + if (i < 1000) + return 1; + + return 0; + + } + +/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 + * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL + * the relevant parameter will be stored in it. + * + * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq + * are generated using the previous function and supplied as input. + */ + +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + BIGNUM *Xp1, BIGNUM *Xp2, + const BIGNUM *Xp, + const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb) + { + int ret = 0; + + BN_CTX_start(ctx); + if (!Xp1) + Xp1 = BN_CTX_get(ctx); + if (!Xp2) + Xp2 = BN_CTX_get(ctx); + + if (!BN_rand(Xp1, 101, 0, 0)) + goto error; + if (!BN_rand(Xp2, 101, 0, 0)) + goto error; + if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) + goto error; + + ret = 1; + + error: + BN_CTX_end(ctx); + + return ret; + + } + diff -up openssl-1.0.0k/crypto/bn/Makefile.fips openssl-1.0.0k/crypto/bn/Makefile --- openssl-1.0.0k/crypto/bn/Makefile.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/bn/Makefile 2013-02-19 20:12:54.576664516 +0100 @@ -26,13 +26,13 @@ LIBSRC= bn_add.c bn_div.c bn_exp.c bn_li bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \ bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \ bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \ - bn_depr.c bn_const.c + bn_depr.c bn_const.c bn_x931p.c LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \ bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \ bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \ bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o \ - bn_depr.o bn_const.o + bn_depr.o bn_const.o bn_x931p.o SRC= $(LIBSRC) diff -up openssl-1.0.0k/crypto/camellia/asm/cmll-x86.pl.fips openssl-1.0.0k/crypto/camellia/asm/cmll-x86.pl --- openssl-1.0.0k/crypto/camellia/asm/cmll-x86.pl.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/camellia/asm/cmll-x86.pl 2013-02-19 20:12:54.576664516 +0100 @@ -722,12 +722,15 @@ my $bias=int(@T[0])?shift(@T):0; } &function_end("Camellia_Ekeygen"); +$setkeyfunc = "Camellia_set_key"; +$setkeyfunc = "private_Camellia_set_key" if ($ENV{FIPS} ne ""); + if ($OPENSSL) { # int Camellia_set_key ( # const unsigned char *userKey, # int bits, # CAMELLIA_KEY *key) -&function_begin_B("Camellia_set_key"); +&function_begin_B($setkeyfunc); &push ("ebx"); &mov ("ecx",&wparam(0)); # pull arguments &mov ("ebx",&wparam(1)); @@ -760,7 +763,7 @@ if ($OPENSSL) { &set_label("done",4); &pop ("ebx"); &ret (); -&function_end_B("Camellia_set_key"); +&function_end_B($setkeyfunc); } @SBOX=( diff -up openssl-1.0.0k/crypto/camellia/camellia.h.fips openssl-1.0.0k/crypto/camellia/camellia.h --- openssl-1.0.0k/crypto/camellia/camellia.h.fips 2013-02-19 20:12:53.926652181 +0100 +++ openssl-1.0.0k/crypto/camellia/camellia.h 2013-02-19 20:12:54.577664536 +0100 @@ -88,6 +88,11 @@ struct camellia_key_st }; typedef struct camellia_key_st CAMELLIA_KEY; +#ifdef OPENSSL_FIPS +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); +#endif + int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key); diff -up openssl-1.0.0k/crypto/camellia/cmll_fblk.c.fips openssl-1.0.0k/crypto/camellia/cmll_fblk.c --- openssl-1.0.0k/crypto/camellia/cmll_fblk.c.fips 2013-02-19 20:12:54.577664536 +0100 +++ openssl-1.0.0k/crypto/camellia/cmll_fblk.c 2013-02-19 20:12:54.577664536 +0100 @@ -0,0 +1,68 @@ +/* crypto/camellia/camellia_misc.c -*- mode:C; c-file-style: "eay" -*- */ +/* ==================================================================== + * Copyright (c) 2006 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 + * 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 "cmll_locl.h" +#include +#ifdef OPENSSL_FIPS +#include +#endif + +#ifdef OPENSSL_FIPS +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) + { + if (FIPS_mode()) + FIPS_BAD_ABORT(CAMELLIA) + return private_Camellia_set_key(userKey, bits, key); + } +#endif diff -up openssl-1.0.0k/crypto/camellia/cmll_misc.c.fips openssl-1.0.0k/crypto/camellia/cmll_misc.c --- openssl-1.0.0k/crypto/camellia/cmll_misc.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/camellia/cmll_misc.c 2013-02-19 20:12:54.577664536 +0100 @@ -52,11 +52,20 @@ #include #include #include "cmll_locl.h" +#include +#ifdef OPENSSL_FIPS +#include +#endif const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; +#ifdef OPENSSL_FIPS +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) +#else int Camellia_set_key(const unsigned char *userKey, const int bits, CAMELLIA_KEY *key) +#endif { if(!userKey || !key) return -1; diff -up openssl-1.0.0k/crypto/camellia/Makefile.fips openssl-1.0.0k/crypto/camellia/Makefile --- openssl-1.0.0k/crypto/camellia/Makefile.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/camellia/Makefile 2013-02-19 20:12:54.578664555 +0100 @@ -23,9 +23,9 @@ APPS= LIB=$(TOP)/libcrypto.a LIBSRC=camellia.c cmll_misc.c cmll_ecb.c cmll_cbc.c cmll_ofb.c \ - cmll_cfb.c cmll_ctr.c + cmll_cfb.c cmll_ctr.c cmll_fblk.c -LIBOBJ= cmll_ecb.o cmll_ofb.o cmll_cfb.o cmll_ctr.o $(CMLL_ENC) +LIBOBJ= cmll_ecb.o cmll_ofb.o cmll_cfb.o cmll_ctr.o $(CMLL_ENC) cmll_fblk.o SRC= $(LIBSRC) diff -up openssl-1.0.0k/crypto/cast/cast.h.fips openssl-1.0.0k/crypto/cast/cast.h --- openssl-1.0.0k/crypto/cast/cast.h.fips 2013-02-19 20:12:54.363660475 +0100 +++ openssl-1.0.0k/crypto/cast/cast.h 2013-02-19 20:12:54.578664555 +0100 @@ -83,7 +83,9 @@ typedef struct cast_key_st int short_key; /* Use reduced rounds for short key */ } CAST_KEY; - +#ifdef OPENSSL_FIPS +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +#endif void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, const CAST_KEY *key, int enc); diff -up openssl-1.0.0k/crypto/cast/c_skey.c.fips openssl-1.0.0k/crypto/cast/c_skey.c --- openssl-1.0.0k/crypto/cast/c_skey.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/cast/c_skey.c 2013-02-19 20:12:54.578664555 +0100 @@ -57,6 +57,11 @@ */ #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + #include "cast_lcl.h" #include "cast_s.h" @@ -72,7 +77,7 @@ #define S6 CAST_S_table6 #define S7 CAST_S_table7 -void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) +FIPS_NON_FIPS_VCIPHER_Init(CAST) { CAST_LONG x[16]; CAST_LONG z[16]; diff -up openssl-1.0.0k/crypto/crypto.h.fips openssl-1.0.0k/crypto/crypto.h --- openssl-1.0.0k/crypto/crypto.h.fips 2013-02-19 20:12:54.000000000 +0100 +++ openssl-1.0.0k/crypto/crypto.h 2013-02-19 20:14:08.209061781 +0100 @@ -554,12 +554,70 @@ int OPENSSL_isservice(void); * non-zero. */ int CRYPTO_memcmp(const void *a, const void *b, size_t len); + +#ifdef OPENSSL_FIPS +#define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \ + alg " previous FIPS forbidden algorithm error ignored"); + +#define FIPS_BAD_ABORT(alg) OpenSSLDie(__FILE__, __LINE__, \ + #alg " Algorithm forbidden in FIPS mode"); + +#ifdef OPENSSL_FIPS_STRICT +#define FIPS_BAD_ALGORITHM(alg) FIPS_BAD_ABORT(alg) +#else +#define FIPS_BAD_ALGORITHM(alg) \ + { \ + FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); \ + ERR_add_error_data(2, "Algorithm=", #alg); \ + return 0; \ + } +#endif + +/* Low level digest API blocking macro */ + +#define FIPS_NON_FIPS_MD_Init(alg) \ + int alg##_Init(alg##_CTX *c) \ + { \ + if (FIPS_mode()) \ + FIPS_BAD_ALGORITHM(alg) \ + return private_##alg##_Init(c); \ + } \ + int private_##alg##_Init(alg##_CTX *c) + +/* For ciphers the API often varies from cipher to cipher and each needs to + * be treated as a special case. Variable key length ciphers (Blowfish, RC4, + * CAST) however are very similar and can use a blocking macro. + */ + +#define FIPS_NON_FIPS_VCIPHER_Init(alg) \ + void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) \ + { \ + if (FIPS_mode()) \ + FIPS_BAD_ABORT(alg) \ + private_##alg##_set_key(key, len, data); \ + } \ + void private_##alg##_set_key(alg##_KEY *key, int len, \ + const unsigned char *data) + +#else + +#define FIPS_NON_FIPS_VCIPHER_Init(alg) \ + void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) + +#define FIPS_NON_FIPS_MD_Init(alg) \ + int alg##_Init(alg##_CTX *c) + +#endif /* def OPENSSL_FIPS */ + /* 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. */ void ERR_load_CRYPTO_strings(void); +#define OPENSSL_HAVE_INIT 1 +void OPENSSL_init_library(void); + /* Error codes for the CRYPTO functions. */ /* Function codes. */ diff -up openssl-1.0.0k/crypto/dh/dh_err.c.fips openssl-1.0.0k/crypto/dh/dh_err.c --- openssl-1.0.0k/crypto/dh/dh_err.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/dh/dh_err.c 2013-02-19 20:12:54.579664573 +0100 @@ -73,6 +73,8 @@ static ERR_STRING_DATA DH_str_functs[]= {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"}, {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, +{ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"}, +{ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"}, {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"}, {ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"}, {ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"}, @@ -94,6 +96,7 @@ static ERR_STRING_DATA DH_str_reasons[]= {ERR_REASON(DH_R_BN_ERROR) ,"bn error"}, {ERR_REASON(DH_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"}, +{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(DH_R_KEYS_NOT_SET) ,"keys not set"}, {ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"}, {ERR_REASON(DH_R_NO_PARAMETERS_SET) ,"no parameters set"}, diff -up openssl-1.0.0k/crypto/dh/dh_gen.c.fips openssl-1.0.0k/crypto/dh/dh_gen.c --- openssl-1.0.0k/crypto/dh/dh_gen.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/dh/dh_gen.c 2013-02-19 20:12:54.579664573 +0100 @@ -65,6 +65,10 @@ #include "cryptlib.h" #include #include +#include +#ifdef OPENSSL_FIPS +#include +#endif static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); @@ -106,6 +110,20 @@ static int dh_builtin_genparams(DH *ret, int g,ok= -1; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif + ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); diff -up openssl-1.0.0k/crypto/dh/dh.h.fips openssl-1.0.0k/crypto/dh/dh.h --- openssl-1.0.0k/crypto/dh/dh.h.fips 2013-02-19 20:12:54.259658499 +0100 +++ openssl-1.0.0k/crypto/dh/dh.h 2013-02-19 20:12:54.580664592 +0100 @@ -77,6 +77,8 @@ # define OPENSSL_DH_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + #define DH_FLAG_CACHE_MONT_P 0x01 #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH * implementation now uses constant time @@ -241,6 +243,8 @@ void ERR_load_DH_strings(void); #define DH_F_GENERATE_PARAMETERS 104 #define DH_F_PKEY_DH_DERIVE 112 #define DH_F_PKEY_DH_KEYGEN 113 +#define DH_F_DH_COMPUTE_KEY 114 +#define DH_F_DH_GENERATE_KEY 115 /* Reason codes. */ #define DH_R_BAD_GENERATOR 101 @@ -253,6 +257,7 @@ void ERR_load_DH_strings(void); #define DH_R_NO_PARAMETERS_SET 107 #define DH_R_NO_PRIVATE_VALUE 100 #define DH_R_PARAMETER_ENCODING_ERROR 105 +#define DH_R_KEY_SIZE_TOO_SMALL 110 #ifdef __cplusplus } diff -up openssl-1.0.0k/crypto/dh/dh_key.c.fips openssl-1.0.0k/crypto/dh/dh_key.c --- openssl-1.0.0k/crypto/dh/dh_key.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/dh/dh_key.c 2013-02-19 20:12:54.580664592 +0100 @@ -61,6 +61,9 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif static int generate_key(DH *dh); static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); @@ -107,6 +110,14 @@ static int generate_key(DH *dh) BN_MONT_CTX *mont=NULL; BIGNUM *pub_key=NULL,*priv_key=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + return 0; + } +#endif + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -184,6 +195,13 @@ static int compute_key(unsigned char *ke DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE); goto err; } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -251,6 +269,9 @@ static int dh_bn_mod_exp(const DH *dh, B static int dh_init(DH *dh) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif dh->flags |= DH_FLAG_CACHE_MONT_P; return(1); } diff -up openssl-1.0.0k/crypto/dsa/dsa_gen.c.fips openssl-1.0.0k/crypto/dsa/dsa_gen.c --- openssl-1.0.0k/crypto/dsa/dsa_gen.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/dsa/dsa_gen.c 2013-02-19 20:12:54.580664592 +0100 @@ -77,8 +77,12 @@ #include "cryptlib.h" #include #include +#include #include #include +#ifdef OPENSSL_FIPS +#include +#endif #include "dsa_locl.h" int DSA_generate_parameters_ex(DSA *ret, int bits, @@ -126,6 +130,21 @@ int dsa_builtin_paramgen(DSA *ret, size_ BN_CTX *ctx=NULL; unsigned int h=2; +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, + FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif + if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && qsize != SHA256_DIGEST_LENGTH) /* invalid q size */ diff -up openssl-1.0.0k/crypto/dsa/dsa.h.fips openssl-1.0.0k/crypto/dsa/dsa.h --- openssl-1.0.0k/crypto/dsa/dsa.h.fips 2013-02-19 20:12:54.099655464 +0100 +++ openssl-1.0.0k/crypto/dsa/dsa.h 2013-02-19 20:12:54.581664610 +0100 @@ -88,6 +88,8 @@ # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + #define DSA_FLAG_CACHE_MONT_P 0x01 #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA * implementation now uses constant time @@ -97,6 +99,21 @@ * be used for all exponents. */ +/* If this flag is set the DSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define DSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define DSA_FLAG_NON_FIPS_ALLOW 0x0400 + #ifdef __cplusplus extern "C" { #endif @@ -270,8 +287,11 @@ void ERR_load_DSA_strings(void); #define DSA_F_DO_DSA_PRINT 104 #define DSA_F_DSAPARAMS_PRINT 100 #define DSA_F_DSAPARAMS_PRINT_FP 101 +#define DSA_F_DSA_BUILTIN_KEYGEN 124 +#define DSA_F_DSA_BUILTIN_PARAMGEN 123 #define DSA_F_DSA_DO_SIGN 112 #define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_GENERATE_PARAMETERS 125 #define DSA_F_DSA_NEW_METHOD 103 #define DSA_F_DSA_PARAM_DECODE 119 #define DSA_F_DSA_PRINT_FP 105 @@ -296,9 +316,12 @@ void ERR_load_DSA_strings(void); #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 #define DSA_R_DECODE_ERROR 104 #define DSA_R_INVALID_DIGEST_TYPE 106 +#define DSA_R_KEY_SIZE_TOO_SMALL 110 #define DSA_R_MISSING_PARAMETERS 101 #define DSA_R_MODULUS_TOO_LARGE 103 +#define DSA_R_NON_FIPS_METHOD 111 #define DSA_R_NO_PARAMETERS_SET 107 +#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 112 #define DSA_R_PARAMETER_ENCODING_ERROR 105 #ifdef __cplusplus diff -up openssl-1.0.0k/crypto/dsa/dsa_key.c.fips openssl-1.0.0k/crypto/dsa/dsa_key.c --- openssl-1.0.0k/crypto/dsa/dsa_key.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/dsa/dsa_key.c 2013-02-19 20:12:54.581664610 +0100 @@ -63,9 +63,55 @@ #include #include #include +#include +#include +#ifdef OPENSSL_FIPS +#include +#endif +#include "fips_locl.h" static int dsa_builtin_keygen(DSA *dsa); +#ifdef OPENSSL_FIPS + +static int fips_dsa_pairwise_fail = 0; + +void FIPS_corrupt_dsa_keygen(void) + { + fips_dsa_pairwise_fail = 1; + } + +int fips_check_dsa(DSA *dsa) + { + EVP_PKEY *pk; + unsigned char tbs[] = "DSA Pairwise Check Data"; + int ret = 0; + + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_set1_DSA(pk, dsa); + + if (!fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), 0, NULL)) + goto err; + + ret = 1; + +err: + if (ret == 0) + { + fips_set_selftest_fail(); + FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED); + } + + if (pk) + EVP_PKEY_free(pk); + + return ret; + } +#endif + int DSA_generate_key(DSA *dsa) { if(dsa->meth->dsa_keygen) @@ -79,6 +125,14 @@ static int dsa_builtin_keygen(DSA *dsa) BN_CTX *ctx=NULL; BIGNUM *pub_key=NULL,*priv_key=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif + if ((ctx=BN_CTX_new()) == NULL) goto err; if (dsa->priv_key == NULL) @@ -117,6 +171,15 @@ static int dsa_builtin_keygen(DSA *dsa) dsa->priv_key=priv_key; dsa->pub_key=pub_key; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if (fips_dsa_pairwise_fail) + BN_add_word(dsa->pub_key, 1); + if(!fips_check_dsa(dsa)) + goto err; + } +#endif ok=1; err: diff -up openssl-1.0.0k/crypto/dsa/dsa_ossl.c.fips openssl-1.0.0k/crypto/dsa/dsa_ossl.c --- openssl-1.0.0k/crypto/dsa/dsa_ossl.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/dsa/dsa_ossl.c 2013-02-19 20:12:54.582664628 +0100 @@ -65,6 +65,9 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); @@ -82,7 +85,7 @@ NULL, /* dsa_mod_exp, */ NULL, /* dsa_bn_mod_exp, */ dsa_init, dsa_finish, -0, +DSA_FLAG_FIPS_METHOD, NULL, NULL, NULL @@ -137,6 +140,20 @@ static DSA_SIG *dsa_do_sign(const unsign int reason=ERR_R_BN_LIB; DSA_SIG *ret=NULL; +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED); + return NULL; + } + + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL); + return NULL; + } +#endif + BN_init(&m); BN_init(&xr); @@ -303,6 +320,20 @@ static int dsa_do_verify(const unsigned return -1; } +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } +#endif + i = BN_num_bits(dsa->q); /* fips 186-3 allows only different sizes for q */ if (i != 160 && i != 224 && i != 256) @@ -385,6 +416,9 @@ static int dsa_do_verify(const unsigned static int dsa_init(DSA *dsa) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif dsa->flags|=DSA_FLAG_CACHE_MONT_P; return(1); } diff -up openssl-1.0.0k/crypto/err/err_all.c.fips openssl-1.0.0k/crypto/err/err_all.c --- openssl-1.0.0k/crypto/err/err_all.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/err/err_all.c 2013-02-19 20:12:54.582664628 +0100 @@ -98,6 +98,9 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif #ifndef OPENSSL_NO_CMS #include #endif @@ -152,6 +155,9 @@ void ERR_load_crypto_strings(void) #endif ERR_load_OCSP_strings(); ERR_load_UI_strings(); +#ifdef OPENSSL_FIPS + ERR_load_FIPS_strings(); +#endif #ifndef OPENSSL_NO_CMS ERR_load_CMS_strings(); #endif diff -up openssl-1.0.0k/crypto/evp/digest.c.fips openssl-1.0.0k/crypto/evp/digest.c --- openssl-1.0.0k/crypto/evp/digest.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/digest.c 2013-02-19 20:12:54.582664628 +0100 @@ -116,6 +116,7 @@ #ifndef OPENSSL_NO_ENGINE #include #endif +#include "evp_locl.h" void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { @@ -138,9 +139,50 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, cons return EVP_DigestInit_ex(ctx, type, NULL); } +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_MD_CTX *ctx) + { FIPS_ERROR_IGNORED("Digest init"); return 0;} + +static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count) + { FIPS_ERROR_IGNORED("Digest update"); return 0;} + +static int bad_final(EVP_MD_CTX *ctx,unsigned char *md) + { FIPS_ERROR_IGNORED("Digest Final"); return 0;} + +static const EVP_MD bad_md = + { + 0, + 0, + 0, + 0, + bad_init, + bad_update, + bad_final, + NULL, + NULL, + NULL, + 0, + {0,0,0,0}, + }; + +#endif + int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); + ctx->digest = &bad_md; + return 0; + } +#endif #ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing @@ -197,6 +239,18 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c #endif if (ctx->digest != type) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if (!(type->flags & EVP_MD_FLAG_FIPS) + && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) + { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); + ctx->digest = &bad_md; + return 0; + } + } +#endif if (ctx->digest && ctx->digest->ctx_size) OPENSSL_free(ctx->md_data); ctx->digest=type; @@ -230,6 +284,9 @@ skip_to_init: int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif return ctx->update(ctx,data,count); } @@ -246,6 +303,9 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, uns int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { int ret; +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret=ctx->digest->final(ctx,md); diff -up openssl-1.0.0k/crypto/evp/e_aes.c.fips openssl-1.0.0k/crypto/evp/e_aes.c --- openssl-1.0.0k/crypto/evp/e_aes.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/e_aes.c 2013-02-19 20:12:54.583664647 +0100 @@ -69,32 +69,29 @@ typedef struct IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, NID_aes_128, 16, 16, 16, 128, - 0, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY, NID_aes_192, 16, 24, 16, 128, - 0, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY, NID_aes_256, 16, 32, 16, 128, - 0, aes_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL) + EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + aes_init_key, + NULL, NULL, NULL, NULL) -#define IMPLEMENT_AES_CFBR(ksize,cbits) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16) +#define IMPLEMENT_AES_CFBR(ksize,cbits,flags) IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags) -IMPLEMENT_AES_CFBR(128,1) -IMPLEMENT_AES_CFBR(192,1) -IMPLEMENT_AES_CFBR(256,1) +IMPLEMENT_AES_CFBR(128,1,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(192,1,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(256,1,EVP_CIPH_FLAG_FIPS) -IMPLEMENT_AES_CFBR(128,8) -IMPLEMENT_AES_CFBR(192,8) -IMPLEMENT_AES_CFBR(256,8) +IMPLEMENT_AES_CFBR(128,8,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(192,8,EVP_CIPH_FLAG_FIPS) +IMPLEMENT_AES_CFBR(256,8,EVP_CIPH_FLAG_FIPS) static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) diff -up openssl-1.0.0k/crypto/evp/e_camellia.c.fips openssl-1.0.0k/crypto/evp/e_camellia.c --- openssl-1.0.0k/crypto/evp/e_camellia.c.fips 2013-02-05 12:47:28.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/e_camellia.c 2013-02-19 20:12:54.583664647 +0100 @@ -93,7 +93,7 @@ IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, EVP_CIPHER_get_asn1_iv, NULL) -#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16) +#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0) IMPLEMENT_CAMELLIA_CFBR(128,1) IMPLEMENT_CAMELLIA_CFBR(192,1) diff -up openssl-1.0.0k/crypto/evp/e_des3.c.fips openssl-1.0.0k/crypto/evp/e_des3.c --- openssl-1.0.0k/crypto/evp/e_des3.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/e_des3.c 2013-02-19 20:12:54.583664647 +0100 @@ -206,9 +206,9 @@ static int des_ede3_cfb8_cipher(EVP_CIPH } BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, - EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede_init_key, + NULL, NULL, NULL, des3_ctrl) #define des_ede3_cfb64_cipher des_ede_cfb64_cipher @@ -217,21 +217,21 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, #define des_ede3_ecb_cipher des_ede_ecb_cipher BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, - EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, - EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, + EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, + NULL, NULL, NULL, des3_ctrl) static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, diff -up openssl-1.0.0k/crypto/evp/e_null.c.fips openssl-1.0.0k/crypto/evp/e_null.c --- openssl-1.0.0k/crypto/evp/e_null.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/e_null.c 2013-02-19 20:12:54.584664666 +0100 @@ -69,7 +69,7 @@ static const EVP_CIPHER n_cipher= { NID_undef, 1,0,0, - 0, + EVP_CIPH_FLAG_FIPS, null_init_key, null_cipher, NULL, diff -up openssl-1.0.0k/crypto/evp/e_rc4.c.fips openssl-1.0.0k/crypto/evp/e_rc4.c --- openssl-1.0.0k/crypto/evp/e_rc4.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/e_rc4.c 2013-02-19 20:12:54.584664666 +0100 @@ -64,6 +64,7 @@ #include #include #include +#include "evp_locl.h" /* FIXME: surely this is available elsewhere? */ #define EVP_RC4_KEY_SIZE 16 diff -up openssl-1.0.0k/crypto/evp/evp_enc.c.fips openssl-1.0.0k/crypto/evp/evp_enc.c --- openssl-1.0.0k/crypto/evp/evp_enc.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/evp_enc.c 2013-02-19 20:12:54.584664666 +0100 @@ -68,8 +68,53 @@ const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT; +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) + { FIPS_ERROR_IGNORED("Cipher init"); return 0;} + +static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) + { FIPS_ERROR_IGNORED("Cipher update"); return 0;} + +/* NB: no cleanup because it is allowed after failed init */ + +static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) + { FIPS_ERROR_IGNORED("Cipher set_asn1"); return 0;} +static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) + { FIPS_ERROR_IGNORED("Cipher get_asn1"); return 0;} +static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) + { FIPS_ERROR_IGNORED("Cipher ctrl"); return 0;} + +static const EVP_CIPHER bad_cipher = + { + 0, + 0, + 0, + 0, + 0, + bad_init, + bad_do_cipher, + NULL, + 0, + bad_set_asn1, + bad_get_asn1, + bad_ctrl, + NULL + }; + +#endif + void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif memset(ctx,0,sizeof(EVP_CIPHER_CTX)); /* ctx->cipher=NULL; */ } @@ -101,6 +146,14 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct enc = 1; ctx->encrypt = enc; } +#ifdef OPENSSL_FIPS + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_EVP_CIPHERINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); + ctx->cipher = &bad_cipher; + return 0; + } +#endif #ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing @@ -220,6 +273,22 @@ skip_to_init: } } +#ifdef OPENSSL_FIPS + /* After 'key' is set no further parameters changes are permissible. + * So only check for non FIPS enabling at this point. + */ + if (key && FIPS_mode()) + { + if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS) + & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) + { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS); + ctx->cipher = &bad_cipher; + return 0; + } + } +#endif + if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { if(!ctx->cipher->init(ctx,key,iv,enc)) return 0; } diff -up openssl-1.0.0k/crypto/evp/evp_err.c.fips openssl-1.0.0k/crypto/evp/evp_err.c --- openssl-1.0.0k/crypto/evp/evp_err.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/evp_err.c 2013-02-19 20:12:54.585664685 +0100 @@ -155,6 +155,7 @@ static ERR_STRING_DATA EVP_str_reasons[] {ERR_REASON(EVP_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES) ,"different key types"}, {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS) ,"different parameters"}, +{ERR_REASON(EVP_R_DISABLED_FOR_FIPS) ,"disabled for fips"}, {ERR_REASON(EVP_R_ENCODE_ERROR) ,"encode error"}, {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"}, {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY) ,"expecting an rsa key"}, diff -up openssl-1.0.0k/crypto/evp/evp.h.fips openssl-1.0.0k/crypto/evp/evp.h --- openssl-1.0.0k/crypto/evp/evp.h.fips 2013-02-19 20:12:54.344660112 +0100 +++ openssl-1.0.0k/crypto/evp/evp.h 2013-02-19 20:12:54.585664685 +0100 @@ -75,6 +75,10 @@ #include #endif +#ifdef OPENSSL_FIPS +#include +#endif + /* #define EVP_RC2_KEY_SIZE 16 #define EVP_RC4_KEY_SIZE 16 @@ -197,6 +201,8 @@ typedef int evp_verify_method(int type,c #define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 +#define EVP_MD_FLAG_FIPS 0x0400 /* Note if suitable for use in FIPS mode */ + /* DigestAlgorithmIdentifier flags... */ #define EVP_MD_FLAG_DIGALGID_MASK 0x0018 @@ -269,10 +275,6 @@ struct env_md_ctx_st * cleaned */ #define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data * in EVP_MD_CTX_cleanup */ -/* FIPS and pad options are ignored in 1.0.0, definitions are here - * so we don't accidentally reuse the values for other purposes. - */ - #define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest * in FIPS mode */ @@ -284,6 +286,10 @@ struct env_md_ctx_st #define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ #define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */ #define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ +#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \ + ((ctx->flags>>16) &0xFFFF) /* seed length */ +#define EVP_MD_CTX_FLAG_PSS_MDLEN 0xFFFF /* salt len same as digest */ +#define EVP_MD_CTX_FLAG_PSS_MREC 0xFFFE /* salt max or auto recovered */ #define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */ @@ -330,12 +336,16 @@ struct evp_cipher_st #define EVP_CIPH_NO_PADDING 0x100 /* cipher handles random key generation */ #define EVP_CIPH_RAND_KEY 0x200 -/* cipher has its own additional copying logic */ -#define EVP_CIPH_CUSTOM_COPY 0x400 +/* Note if suitable for use in FIPS mode */ +#define EVP_CIPH_FLAG_FIPS 0x400 +/* Allow non FIPS cipher in FIPS mode */ +#define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 /* Allow use default ASN1 get/set iv */ #define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 /* Buffer length in bits not bytes: CFB1 mode only */ #define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* cipher has its own additional copying logic */ +#define EVP_CIPH_CUSTOM_COPY 0x4000 /* ctrl() values */ @@ -1239,6 +1249,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_DECODE_ERROR 114 #define EVP_R_DIFFERENT_KEY_TYPES 101 #define EVP_R_DIFFERENT_PARAMETERS 153 +#define EVP_R_DISABLED_FOR_FIPS 160 #define EVP_R_ENCODE_ERROR 115 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 #define EVP_R_EXPECTING_AN_RSA_KEY 127 diff -up openssl-1.0.0k/crypto/evp/evp_lib.c.fips openssl-1.0.0k/crypto/evp/evp_lib.c --- openssl-1.0.0k/crypto/evp/evp_lib.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/evp_lib.c 2013-02-19 20:12:54.586664704 +0100 @@ -67,6 +67,8 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_ if (c->cipher->set_asn1_parameters != NULL) ret=c->cipher->set_asn1_parameters(c,type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret=EVP_CIPHER_set_asn1_iv(c, type); else ret=-1; return(ret); @@ -78,6 +80,8 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_ if (c->cipher->get_asn1_parameters != NULL) ret=c->cipher->get_asn1_parameters(c,type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) + ret=EVP_CIPHER_get_asn1_iv(c, type); else ret=-1; return(ret); @@ -186,6 +190,9 @@ int EVP_CIPHER_CTX_block_size(const EVP_ int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif return ctx->cipher->do_cipher(ctx,out,in,inl); } diff -up openssl-1.0.0k/crypto/evp/evp_locl.h.fips openssl-1.0.0k/crypto/evp/evp_locl.h --- openssl-1.0.0k/crypto/evp/evp_locl.h.fips 2013-02-19 20:12:54.335659942 +0100 +++ openssl-1.0.0k/crypto/evp/evp_locl.h 2013-02-19 20:12:54.586664704 +0100 @@ -254,14 +254,32 @@ const EVP_CIPHER *EVP_##cname##_ecb(void #define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data) -#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \ +#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \ BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ - 0, cipher##_init_key, NULL, \ - EVP_CIPHER_set_asn1_iv, \ - EVP_CIPHER_get_asn1_iv, \ - NULL) + (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \ + cipher##_init_key, NULL, NULL, NULL, NULL) + +#ifdef OPENSSL_FIPS +#define RC2_set_key private_RC2_set_key +#define RC4_set_key private_RC4_set_key +#define CAST_set_key private_CAST_set_key +#define RC5_32_set_key private_RC5_32_set_key +#define BF_set_key private_BF_set_key +#define SEED_set_key private_SEED_set_key +#define Camellia_set_key private_Camellia_set_key +#define idea_set_encrypt_key private_idea_set_encrypt_key + +#define MD5_Init private_MD5_Init +#define MD4_Init private_MD4_Init +#define MD2_Init private_MD2_Init +#define MDC2_Init private_MDC2_Init +#define SHA_Init private_SHA_Init +#define RIPEMD160_Init private_RIPEMD160_Init +#define WHIRLPOOL_Init private_WHIRLPOOL_Init + +#endif struct evp_pkey_ctx_st { diff -up openssl-1.0.0k/crypto/evp/m_dss1.c.fips openssl-1.0.0k/crypto/evp/m_dss1.c --- openssl-1.0.0k/crypto/evp/m_dss1.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_dss1.c 2013-02-19 20:12:54.587664724 +0100 @@ -82,7 +82,7 @@ static const EVP_MD dss1_md= NID_dsa, NID_dsaWithSHA1, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, + EVP_MD_FLAG_PKEY_DIGEST|EVP_MD_FLAG_FIPS, init, update, final, diff -up openssl-1.0.0k/crypto/evp/m_dss.c.fips openssl-1.0.0k/crypto/evp/m_dss.c --- openssl-1.0.0k/crypto/evp/m_dss.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_dss.c 2013-02-19 20:12:54.587664724 +0100 @@ -81,7 +81,7 @@ static const EVP_MD dsa_md= NID_dsaWithSHA, NID_dsaWithSHA, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, + EVP_MD_FLAG_PKEY_DIGEST|EVP_MD_FLAG_FIPS, init, update, final, diff -up openssl-1.0.0k/crypto/evp/m_md2.c.fips openssl-1.0.0k/crypto/evp/m_md2.c --- openssl-1.0.0k/crypto/evp/m_md2.c.fips 2013-02-05 12:47:28.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_md2.c 2013-02-19 20:12:54.587664724 +0100 @@ -68,6 +68,7 @@ #ifndef OPENSSL_NO_RSA #include #endif +#include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { return MD2_Init(ctx->md_data); } diff -up openssl-1.0.0k/crypto/evp/m_md4.c.fips openssl-1.0.0k/crypto/evp/m_md4.c --- openssl-1.0.0k/crypto/evp/m_md4.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_md4.c 2013-02-19 20:12:54.588664743 +0100 @@ -68,6 +68,7 @@ #ifndef OPENSSL_NO_RSA #include #endif +#include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { return MD4_Init(ctx->md_data); } diff -up openssl-1.0.0k/crypto/evp/m_md5.c.fips openssl-1.0.0k/crypto/evp/m_md5.c --- openssl-1.0.0k/crypto/evp/m_md5.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_md5.c 2013-02-19 20:12:54.588664743 +0100 @@ -68,6 +68,7 @@ #ifndef OPENSSL_NO_RSA #include #endif +#include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { return MD5_Init(ctx->md_data); } diff -up openssl-1.0.0k/crypto/evp/m_mdc2.c.fips openssl-1.0.0k/crypto/evp/m_mdc2.c --- openssl-1.0.0k/crypto/evp/m_mdc2.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_mdc2.c 2013-02-19 20:12:54.587664724 +0100 @@ -68,6 +68,7 @@ #ifndef OPENSSL_NO_RSA #include #endif +#include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { return MDC2_Init(ctx->md_data); } diff -up openssl-1.0.0k/crypto/evp/m_ripemd.c.fips openssl-1.0.0k/crypto/evp/m_ripemd.c --- openssl-1.0.0k/crypto/evp/m_ripemd.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_ripemd.c 2013-02-19 20:12:54.588664743 +0100 @@ -68,6 +68,7 @@ #ifndef OPENSSL_NO_RSA #include #endif +#include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { return RIPEMD160_Init(ctx->md_data); } diff -up openssl-1.0.0k/crypto/evp/m_sha1.c.fips openssl-1.0.0k/crypto/evp/m_sha1.c --- openssl-1.0.0k/crypto/evp/m_sha1.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_sha1.c 2013-02-19 20:12:54.589664762 +0100 @@ -82,7 +82,8 @@ static const EVP_MD sha1_md= NID_sha1, NID_sha1WithRSAEncryption, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init, update, final, @@ -119,7 +120,8 @@ static const EVP_MD sha224_md= NID_sha224, NID_sha224WithRSAEncryption, SHA224_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init224, update256, final256, @@ -138,7 +140,8 @@ static const EVP_MD sha256_md= NID_sha256, NID_sha256WithRSAEncryption, SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init256, update256, final256, @@ -169,7 +172,8 @@ static const EVP_MD sha384_md= NID_sha384, NID_sha384WithRSAEncryption, SHA384_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init384, update512, final512, @@ -188,7 +192,8 @@ static const EVP_MD sha512_md= NID_sha512, NID_sha512WithRSAEncryption, SHA512_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT| + EVP_MD_FLAG_FIPS, init512, update512, final512, diff -up openssl-1.0.0k/crypto/evp/m_wp.c.fips openssl-1.0.0k/crypto/evp/m_wp.c --- openssl-1.0.0k/crypto/evp/m_wp.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/m_wp.c 2013-02-19 20:12:54.589664762 +0100 @@ -9,6 +9,7 @@ #include #include #include +#include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { return WHIRLPOOL_Init(ctx->md_data); } diff -up openssl-1.0.0k/crypto/evp/names.c.fips openssl-1.0.0k/crypto/evp/names.c --- openssl-1.0.0k/crypto/evp/names.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/names.c 2013-02-19 20:12:54.589664762 +0100 @@ -66,6 +66,10 @@ int EVP_add_cipher(const EVP_CIPHER *c) { int r; +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); +#endif + r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c); if (r == 0) return(0); check_defer(c->nid); @@ -79,6 +83,10 @@ int EVP_add_digest(const EVP_MD *md) int r; const char *name; +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); +#endif + name=OBJ_nid2sn(md->type); r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md); if (r == 0) return(0); diff -up openssl-1.0.0k/crypto/evp/p_sign.c.fips openssl-1.0.0k/crypto/evp/p_sign.c --- openssl-1.0.0k/crypto/evp/p_sign.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/p_sign.c 2013-02-19 20:12:54.589664762 +0100 @@ -61,6 +61,7 @@ #include #include #include +#include #ifdef undef void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) @@ -101,6 +102,22 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsig goto err; if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931) + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0) + goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) + { + int saltlen; + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) + goto err; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + } if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) goto err; *siglen = sltmp; diff -up openssl-1.0.0k/crypto/evp/p_verify.c.fips openssl-1.0.0k/crypto/evp/p_verify.c --- openssl-1.0.0k/crypto/evp/p_verify.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/evp/p_verify.c 2013-02-19 20:12:54.590664781 +0100 @@ -61,6 +61,7 @@ #include #include #include +#include int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey) @@ -86,6 +87,22 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, con goto err; if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931) + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0) + goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) + { + int saltlen; + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) + goto err; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + } i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); err: EVP_PKEY_CTX_free(pkctx); diff -up openssl-1.0.0k/crypto/fips/cavs/fips_aesavs.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_aesavs.c --- openssl-1.0.0k/crypto/fips/cavs/fips_aesavs.c.fips 2013-02-19 20:12:54.591664800 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_aesavs.c 2013-02-19 20:12:54.591664800 +0100 @@ -0,0 +1,939 @@ +/* ==================================================================== + * Copyright (c) 2004 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 + * 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. + * + */ +/*--------------------------------------------- + NIST AES Algorithm Validation Suite + Test Program + + Donated to OpenSSL by: + V-ONE Corporation + 20250 Century Blvd, Suite 300 + Germantown, MD 20874 + U.S.A. + ----------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "e_os.h" + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS AES support\n"); + return(0); +} + +#else + +#include +#include "fips_utl.h" + +#define AES_BLOCK_SIZE 16 + +#define VERBOSE 0 + +/*-----------------------------------------------*/ + +int AESTest(EVP_CIPHER_CTX *ctx, + char *amode, int akeysz, unsigned char *aKey, + unsigned char *iVec, + int dir, /* 0 = decrypt, 1 = encrypt */ + unsigned char *plaintext, unsigned char *ciphertext, int len) + { + const EVP_CIPHER *cipher = NULL; + + if (strcasecmp(amode, "CBC") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cbc(); + break; + + case 192: + cipher = EVP_aes_192_cbc(); + break; + + case 256: + cipher = EVP_aes_256_cbc(); + break; + } + + } + else if (strcasecmp(amode, "ECB") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_ecb(); + break; + + case 192: + cipher = EVP_aes_192_ecb(); + break; + + case 256: + cipher = EVP_aes_256_ecb(); + break; + } + } + else if (strcasecmp(amode, "CFB128") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb128(); + break; + + case 192: + cipher = EVP_aes_192_cfb128(); + break; + + case 256: + cipher = EVP_aes_256_cfb128(); + break; + } + + } + else if (strncasecmp(amode, "OFB", 3) == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_ofb(); + break; + + case 192: + cipher = EVP_aes_192_ofb(); + break; + + case 256: + cipher = EVP_aes_256_ofb(); + break; + } + } + else if(!strcasecmp(amode,"CFB1")) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb1(); + break; + + case 192: + cipher = EVP_aes_192_cfb1(); + break; + + case 256: + cipher = EVP_aes_256_cfb1(); + break; + } + } + else if(!strcasecmp(amode,"CFB8")) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb8(); + break; + + case 192: + cipher = EVP_aes_192_cfb8(); + break; + + case 256: + cipher = EVP_aes_256_cfb8(); + break; + } + } + else + { + printf("Unknown mode: %s\n", amode); + return 0; + } + if (!cipher) + { + printf("Invalid key size: %d\n", akeysz); + return 0; + } + if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) + return 0; + if(!strcasecmp(amode,"CFB1")) + M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); + if (dir) + EVP_Cipher(ctx, ciphertext, plaintext, len); + else + EVP_Cipher(ctx, plaintext, ciphertext, len); + return 1; + } + +/*-----------------------------------------------*/ +char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; +char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"}; +enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128}; +enum XCrypt {XDECRYPT, XENCRYPT}; + +/*=============================*/ +/* Monte Carlo Tests */ +/*-----------------------------*/ + +/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/ +/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/ + +#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1) +#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8))) + +int do_mct(char *amode, + int akeysz, unsigned char *aKey,unsigned char *iVec, + int dir, unsigned char *text, int len, + FILE *rfp) + { + int ret = 0; + unsigned char key[101][32]; + unsigned char iv[101][AES_BLOCK_SIZE]; + unsigned char ptext[1001][32]; + unsigned char ctext[1001][32]; + unsigned char ciphertext[64+4]; + int i, j, n, n1, n2; + int imode = 0, nkeysz = akeysz/8; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (len > 32) + { + printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n", + amode, akeysz); + return -1; + } + for (imode = 0; imode < 6; ++imode) + if (strcmp(amode, t_mode[imode]) == 0) + break; + if (imode == 6) + { + printf("Unrecognized mode: %s\n", amode); + return -1; + } + + memcpy(key[0], aKey, nkeysz); + if (iVec) + memcpy(iv[0], iVec, AES_BLOCK_SIZE); + if (dir == XENCRYPT) + memcpy(ptext[0], text, len); + else + memcpy(ctext[0], text, len); + for (i = 0; i < 100; ++i) + { + /* printf("Iteration %d\n", i); */ + if (i > 0) + { + fprintf(rfp,"COUNT = %d\n",i); + OutputValue("KEY",key[i],nkeysz,rfp,0); + if (imode != ECB) /* ECB */ + OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0); + /* Output Ciphertext | Plaintext */ + OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp, + imode == CFB1); + } + for (j = 0; j < 1000; ++j) + { + switch (imode) + { + case ECB: + if (j == 0) + { /* set up encryption */ + ret = AESTest(&ctx, amode, akeysz, key[i], NULL, + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + if (dir == XENCRYPT) + memcpy(ptext[j+1], ctext[j], len); + else + memcpy(ctext[j+1], ptext[j], len); + } + else + { + if (dir == XENCRYPT) + { + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + memcpy(ptext[j+1], ctext[j], len); + } + else + { + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + memcpy(ctext[j+1], ptext[j], len); + } + } + break; + + case CBC: + case OFB: + case CFB128: + if (j == 0) + { + ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + if (dir == XENCRYPT) + memcpy(ptext[j+1], iv[i], len); + else + memcpy(ctext[j+1], iv[i], len); + } + else + { + if (dir == XENCRYPT) + { + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + memcpy(ptext[j+1], ctext[j-1], len); + } + else + { + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + memcpy(ctext[j+1], ptext[j-1], len); + } + } + break; + + case CFB8: + if (j == 0) + { + ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + } + else + { + if (dir == XENCRYPT) + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + else + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + } + if (dir == XENCRYPT) + { + if (j < 16) + memcpy(ptext[j+1], &iv[i][j], len); + else + memcpy(ptext[j+1], ctext[j-16], len); + } + else + { + if (j < 16) + memcpy(ctext[j+1], &iv[i][j], len); + else + memcpy(ctext[j+1], ptext[j-16], len); + } + break; + + case CFB1: + if(j == 0) + { +#if 0 + /* compensate for wrong endianness of input file */ + if(i == 0) + ptext[0][0]<<=7; +#endif + ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir, + ptext[j], ctext[j], len); + } + else + { + if (dir == XENCRYPT) + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + else + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + + } + if(dir == XENCRYPT) + { + if(j < 128) + sb(ptext[j+1],0,gb(iv[i],j)); + else + sb(ptext[j+1],0,gb(ctext[j-128],0)); + } + else + { + if(j < 128) + sb(ctext[j+1],0,gb(iv[i],j)); + else + sb(ctext[j+1],0,gb(ptext[j-128],0)); + } + break; + } + } + --j; /* reset to last of range */ + /* Output Ciphertext | Plaintext */ + OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp, + imode == CFB1); + fprintf(rfp, "\n"); /* add separator */ + + /* Compute next KEY */ + if (dir == XENCRYPT) + { + if (imode == CFB8) + { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ + for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) + ciphertext[n1] = ctext[j-n2][0]; + } + else if(imode == CFB1) + { + for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) + sb(ciphertext,n1,gb(ctext[j-n2],0)); + } + else + switch (akeysz) + { + case 128: + memcpy(ciphertext, ctext[j], 16); + break; + case 192: + memcpy(ciphertext, ctext[j-1]+8, 8); + memcpy(ciphertext+8, ctext[j], 16); + break; + case 256: + memcpy(ciphertext, ctext[j-1], 16); + memcpy(ciphertext+16, ctext[j], 16); + break; + } + } + else + { + if (imode == CFB8) + { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ + for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) + ciphertext[n1] = ptext[j-n2][0]; + } + else if(imode == CFB1) + { + for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) + sb(ciphertext,n1,gb(ptext[j-n2],0)); + } + else + switch (akeysz) + { + case 128: + memcpy(ciphertext, ptext[j], 16); + break; + case 192: + memcpy(ciphertext, ptext[j-1]+8, 8); + memcpy(ciphertext+8, ptext[j], 16); + break; + case 256: + memcpy(ciphertext, ptext[j-1], 16); + memcpy(ciphertext+16, ptext[j], 16); + break; + } + } + /* Compute next key: Key[i+1] = Key[i] xor ct */ + for (n = 0; n < nkeysz; ++n) + key[i+1][n] = key[i][n] ^ ciphertext[n]; + + /* Compute next IV and text */ + if (dir == XENCRYPT) + { + switch (imode) + { + case ECB: + memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE); + break; + case CBC: + case OFB: + case CFB128: + memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE); + memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE); + break; + case CFB8: + /* IV[i+1] = ct */ + for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) + iv[i+1][n1] = ctext[j-n2][0]; + ptext[0][0] = ctext[j-16][0]; + break; + case CFB1: + for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) + sb(iv[i+1],n1,gb(ctext[j-n2],0)); + ptext[0][0]=ctext[j-128][0]&0x80; + break; + } + } + else + { + switch (imode) + { + case ECB: + memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE); + break; + case CBC: + case OFB: + case CFB128: + memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE); + memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE); + break; + case CFB8: + for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) + iv[i+1][n1] = ptext[j-n2][0]; + ctext[0][0] = ptext[j-16][0]; + break; + case CFB1: + for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) + sb(iv[i+1],n1,gb(ptext[j-n2],0)); + ctext[0][0]=ptext[j-128][0]&0x80; + break; + } + } + } + + return ret; + } + +/*================================================*/ +/*---------------------------- + # Config info for v-one + # AESVS MMT test data for ECB + # State : Encrypt and Decrypt + # Key Length : 256 + # Fri Aug 30 04:07:22 PM + ----------------------------*/ + +int proc_file(char *rqfile, char *rspfile) + { + char afn[256], rfn[256]; + FILE *afp = NULL, *rfp = NULL; + char ibuf[2048]; + char tbuf[2048]; + int ilen, len, ret = 0; + char algo[8] = ""; + char amode[8] = ""; + char atest[8] = ""; + int akeysz = 0; + unsigned char iVec[20], aKey[40]; + int dir = -1, err = 0, step = 0; + unsigned char plaintext[2048]; + unsigned char ciphertext[2048]; + char *rp; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (!rqfile || !(*rqfile)) + { + printf("No req file\n"); + return -1; + } + strcpy(afn, rqfile); + + if ((afp = fopen(afn, "r")) == NULL) + { + printf("Cannot open file: %s, %s\n", + afn, strerror(errno)); + return -1; + } + if (!rspfile) + { + strcpy(rfn,afn); + rp=strstr(rfn,"req/"); +#ifdef OPENSSL_SYS_WIN32 + if (!rp) + rp=strstr(rfn,"req\\"); +#endif + assert(rp); + memcpy(rp,"rsp",3); + rp = strstr(rfn, ".req"); + memcpy(rp, ".rsp", 4); + rspfile = rfn; + } + if ((rfp = fopen(rspfile, "w")) == NULL) + { + printf("Cannot open file: %s, %s\n", + rfn, strerror(errno)); + fclose(afp); + afp = NULL; + return -1; + } + while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) + { + tidy_line(tbuf, ibuf); + ilen = strlen(ibuf); + /* printf("step=%d ibuf=%s",step,ibuf); */ + switch (step) + { + case 0: /* read preamble */ + if (ibuf[0] == '\n') + { /* end of preamble */ + if ((*algo == '\0') || + (*amode == '\0') || + (akeysz == 0)) + { + printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n", + algo,amode,akeysz); + err = 1; + } + else + { + fputs(ibuf, rfp); + ++ step; + } + } + else if (ibuf[0] != '#') + { + printf("Invalid preamble item: %s\n", ibuf); + err = 1; + } + else + { /* process preamble */ + char *xp, *pp = ibuf+2; + int n; + if (akeysz) + { /* insert current time & date */ + time_t rtim = time(0); + fprintf(rfp, "# %s", ctime(&rtim)); + } + else + { + fputs(ibuf, rfp); + if (strncmp(pp, "AESVS ", 6) == 0) + { + strcpy(algo, "AES"); + /* get test type */ + pp += 6; + xp = strchr(pp, ' '); + n = xp-pp; + strncpy(atest, pp, n); + atest[n] = '\0'; + /* get mode */ + xp = strrchr(pp, ' '); /* get mode" */ + n = strlen(xp+1)-1; + strncpy(amode, xp+1, n); + amode[n] = '\0'; + /* amode[3] = '\0'; */ + if (VERBOSE) + printf("Test = %s, Mode = %s\n", atest, amode); + } + else if (strncasecmp(pp, "Key Length : ", 13) == 0) + { + akeysz = atoi(pp+13); + if (VERBOSE) + printf("Key size = %d\n", akeysz); + } + } + } + break; + + case 1: /* [ENCRYPT] | [DECRYPT] */ + if (ibuf[0] == '[') + { + fputs(ibuf, rfp); + ++step; + if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) + dir = 1; + else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) + dir = 0; + else + { + printf("Invalid keyword: %s\n", ibuf); + err = 1; + } + break; + } + else if (dir == -1) + { + err = 1; + printf("Missing ENCRYPT/DECRYPT keyword\n"); + break; + } + else + step = 2; + + case 2: /* KEY = xxxx */ + fputs(ibuf, rfp); + if(*ibuf == '\n') + break; + if(!strncasecmp(ibuf,"COUNT = ",8)) + break; + + if (strncasecmp(ibuf, "KEY = ", 6) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+6, aKey); + if (len < 0) + { + printf("Invalid KEY\n"); + err =1; + break; + } + PrintValue("KEY", aKey, len); + if (strcmp(amode, "ECB") == 0) + { + memset(iVec, 0, sizeof(iVec)); + step = (dir)? 4: 5; /* no ivec for ECB */ + } + else + ++step; + } + break; + + case 3: /* IV = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "IV = ", 5) != 0) + { + printf("Missing IV\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+5, iVec); + if (len < 0) + { + printf("Invalid IV\n"); + err =1; + break; + } + PrintValue("IV", iVec, len); + step = (dir)? 4: 5; + } + break; + + case 4: /* PLAINTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) + { + printf("Missing PLAINTEXT\n"); + err = 1; + } + else + { + int nn = strlen(ibuf+12); + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+12,nn-1,plaintext); + else + len=hex2bin(ibuf+12, plaintext); + if (len < 0) + { + printf("Invalid PLAINTEXT: %s", ibuf+12); + err =1; + break; + } + if (len >= sizeof(plaintext)) + { + printf("Buffer overflow\n"); + } + PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); + if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ + { + if(do_mct(amode, akeysz, aKey, iVec, + dir, (unsigned char*)plaintext, len, + rfp) < 0) + EXIT(1); + } + else + { + ret = AESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("CIPHERTEXT",ciphertext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 5: /* CIPHERTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); + else + len = hex2bin(ibuf+13,ciphertext); + if (len < 0) + { + printf("Invalid CIPHERTEXT\n"); + err =1; + break; + } + + PrintValue("CIPHERTEXT", ciphertext, len); + if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ + { + do_mct(amode, akeysz, aKey, iVec, + dir, ciphertext, len, rfp); + } + else + { + ret = AESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 6: + if (ibuf[0] != '\n') + { + err = 1; + printf("Missing terminator\n"); + } + else if (strcmp(atest, "MCT") != 0) + { /* MCT already added terminating nl */ + fputs(ibuf, rfp); + } + step = 1; + break; + } + } + if (rfp) + fclose(rfp); + if (afp) + fclose(afp); + return err; + } + +/*-------------------------------------------------- + Processes either a single file or + a set of files whose names are passed in a file. + A single file is specified as: + aes_test -f xxx.req + A set of files is specified as: + aes_test -d xxxxx.xxx + The default is: -d req.txt +--------------------------------------------------*/ +int main(int argc, char **argv) + { + char *rqlist = "req.txt", *rspfile = NULL; + FILE *fp = NULL; + char fn[250] = "", rfn[256] = ""; + int f_opt = 0, d_opt = 1; + +#ifdef OPENSSL_FIPS + if(!FIPS_mode_set(1)) + { + do_print_errors(); + EXIT(1); + } +#endif + if (argc > 1) + { + if (strcasecmp(argv[1], "-d") == 0) + { + d_opt = 1; + } + else if (strcasecmp(argv[1], "-f") == 0) + { + f_opt = 1; + d_opt = 0; + } + else + { + printf("Invalid parameter: %s\n", argv[1]); + return 0; + } + if (argc < 3) + { + printf("Missing parameter\n"); + return 0; + } + if (d_opt) + rqlist = argv[2]; + else + { + strcpy(fn, argv[2]); + rspfile = argv[3]; + } + } + if (d_opt) + { /* list of files (directory) */ + if (!(fp = fopen(rqlist, "r"))) + { + printf("Cannot open req list file\n"); + return -1; + } + while (fgets(fn, sizeof(fn), fp)) + { + strtok(fn, "\r\n"); + strcpy(rfn, fn); + if (VERBOSE) + printf("Processing: %s\n", rfn); + if (proc_file(rfn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", rfn); + EXIT(1); + } + } + fclose(fp); + } + else /* single file */ + { + if (VERBOSE) + printf("Processing: %s\n", fn); + if (proc_file(fn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", fn); + } + } + EXIT(0); + return 0; + } + +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_desmovs.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_desmovs.c --- openssl-1.0.0k/crypto/fips/cavs/fips_desmovs.c.fips 2013-02-19 20:12:54.591664800 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_desmovs.c 2013-02-19 20:12:54.591664800 +0100 @@ -0,0 +1,702 @@ +/* ==================================================================== + * Copyright (c) 2004 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 + * 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. + * + */ +/*--------------------------------------------- + NIST DES Modes of Operation Validation System + Test Program + + Based on the AES Validation Suite, which was: + Donated to OpenSSL by: + V-ONE Corporation + 20250 Century Blvd, Suite 300 + Germantown, MD 20874 + U.S.A. + ----------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "e_os.h" + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS DES support\n"); + return(0); +} + +#else + +#include +#include "fips_utl.h" + +#define DES_BLOCK_SIZE 8 + +#define VERBOSE 0 + +int DESTest(EVP_CIPHER_CTX *ctx, + char *amode, int akeysz, unsigned char *aKey, + unsigned char *iVec, + int dir, /* 0 = decrypt, 1 = encrypt */ + unsigned char *out, unsigned char *in, int len) + { + const EVP_CIPHER *cipher = NULL; + + if (akeysz != 192) + { + printf("Invalid key size: %d\n", akeysz); + EXIT(1); + } + + if (strcasecmp(amode, "CBC") == 0) + cipher = EVP_des_ede3_cbc(); + else if (strcasecmp(amode, "ECB") == 0) + cipher = EVP_des_ede3_ecb(); + else if (strcasecmp(amode, "CFB64") == 0) + cipher = EVP_des_ede3_cfb64(); + else if (strncasecmp(amode, "OFB", 3) == 0) + cipher = EVP_des_ede3_ofb(); + else if(!strcasecmp(amode,"CFB8")) + cipher = EVP_des_ede3_cfb8(); + else if(!strcasecmp(amode,"CFB1")) + cipher = EVP_des_ede3_cfb1(); + else + { + printf("Unknown mode: %s\n", amode); + EXIT(1); + } + + if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) + return 0; + if(!strcasecmp(amode,"CFB1")) + M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); + EVP_Cipher(ctx, out, in, len); + + return 1; + } + +void DebugValue(char *tag, unsigned char *val, int len) + { + char obuf[2048]; + int olen; + olen = bin2hex(val, len, obuf); + printf("%s = %.*s\n", tag, olen, obuf); + } + +void shiftin(unsigned char *dst,unsigned char *src,int nbits) + { + int n; + + /* move the bytes... */ + memmove(dst,dst+nbits/8,3*8-nbits/8); + /* append new data */ + memcpy(dst+3*8-nbits/8,src,(nbits+7)/8); + /* left shift the bits */ + if(nbits%8) + for(n=0 ; n < 3*8 ; ++n) + dst[n]=(dst[n] << (nbits%8))|(dst[n+1] >> (8-nbits%8)); + } + +/*-----------------------------------------------*/ +char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; +char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"}; +enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64}; +int Sizes[6]={64,64,64,1,8,64}; + +void do_mct(char *amode, + int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec, + int dir, unsigned char *text, int len, + FILE *rfp) + { + int i,imode; + unsigned char nk[4*8]; /* longest key+8 */ + unsigned char text0[8]; + + for (imode=0 ; imode < 6 ; ++imode) + if(!strcmp(amode,t_mode[imode])) + break; + if (imode == 6) + { + printf("Unrecognized mode: %s\n", amode); + EXIT(1); + } + + for(i=0 ; i < 400 ; ++i) + { + int j; + int n; + int kp=akeysz/64; + unsigned char old_iv[8]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + fprintf(rfp,"\nCOUNT = %d\n",i); + if(kp == 1) + OutputValue("KEY",akey,8,rfp,0); + else + for(n=0 ; n < kp ; ++n) + { + fprintf(rfp,"KEY%d",n+1); + OutputValue("",akey+n*8,8,rfp,0); + } + + if(imode != ECB) + OutputValue("IV",ivec,8,rfp,0); + OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1); +#if 0 + /* compensate for endianness */ + if(imode == CFB1) + text[0]<<=7; +#endif + memcpy(text0,text,8); + + for(j=0 ; j < 10000 ; ++j) + { + unsigned char old_text[8]; + + memcpy(old_text,text,8); + if(j == 0) + { + memcpy(old_iv,ivec,8); + DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len); + } + else + { + memcpy(old_iv,ctx.iv,8); + EVP_Cipher(&ctx,text,text,len); + } + if(j == 9999) + { + OutputValue(t_tag[dir],text,len,rfp,imode == CFB1); + /* memcpy(ivec,text,8); */ + } + /* DebugValue("iv",ctx.iv,8); */ + /* accumulate material for the next key */ + shiftin(nk,text,Sizes[imode]); + /* DebugValue("nk",nk,24);*/ + if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64 + || imode == CBC)) || imode == OFB) + memcpy(text,old_iv,8); + + if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64)) + { + /* the test specifies using the output of the raw DES operation + which we don't have, so reconstruct it... */ + for(n=0 ; n < 8 ; ++n) + text[n]^=old_text[n]; + } + } + for(n=0 ; n < 8 ; ++n) + akey[n]^=nk[16+n]; + for(n=0 ; n < 8 ; ++n) + akey[8+n]^=nk[8+n]; + for(n=0 ; n < 8 ; ++n) + akey[16+n]^=nk[n]; + if(numkeys < 3) + memcpy(&akey[2*8],akey,8); + if(numkeys < 2) + memcpy(&akey[8],akey,8); + DES_set_odd_parity((DES_cblock *)akey); + DES_set_odd_parity((DES_cblock *)(akey+8)); + DES_set_odd_parity((DES_cblock *)(akey+16)); + memcpy(ivec,ctx.iv,8); + + /* pointless exercise - the final text doesn't depend on the + initial text in OFB mode, so who cares what it is? (Who + designed these tests?) */ + if(imode == OFB) + for(n=0 ; n < 8 ; ++n) + text[n]=text0[n]^old_iv[n]; + } + } + +int proc_file(char *rqfile, char *rspfile) + { + char afn[256], rfn[256]; + FILE *afp = NULL, *rfp = NULL; + char ibuf[2048], tbuf[2048]; + int ilen, len, ret = 0; + char amode[8] = ""; + char atest[100] = ""; + int akeysz=0; + unsigned char iVec[20], aKey[40]; + int dir = -1, err = 0, step = 0; + unsigned char plaintext[2048]; + unsigned char ciphertext[2048]; + char *rp; + EVP_CIPHER_CTX ctx; + int numkeys=1; + EVP_CIPHER_CTX_init(&ctx); + + if (!rqfile || !(*rqfile)) + { + printf("No req file\n"); + return -1; + } + strcpy(afn, rqfile); + + if ((afp = fopen(afn, "r")) == NULL) + { + printf("Cannot open file: %s, %s\n", + afn, strerror(errno)); + return -1; + } + if (!rspfile) + { + strcpy(rfn,afn); + rp=strstr(rfn,"req/"); +#ifdef OPENSSL_SYS_WIN32 + if (!rp) + rp=strstr(rfn,"req\\"); +#endif + assert(rp); + memcpy(rp,"rsp",3); + rp = strstr(rfn, ".req"); + memcpy(rp, ".rsp", 4); + rspfile = rfn; + } + if ((rfp = fopen(rspfile, "w")) == NULL) + { + printf("Cannot open file: %s, %s\n", + rfn, strerror(errno)); + fclose(afp); + afp = NULL; + return -1; + } + while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) + { + tidy_line(tbuf, ibuf); + ilen = strlen(ibuf); + /* printf("step=%d ibuf=%s",step,ibuf);*/ + if(step == 3 && !strcmp(amode,"ECB")) + { + memset(iVec, 0, sizeof(iVec)); + step = (dir)? 4: 5; /* no ivec for ECB */ + } + switch (step) + { + case 0: /* read preamble */ + if (ibuf[0] == '\n') + { /* end of preamble */ + if (*amode == '\0') + { + printf("Missing Mode\n"); + err = 1; + } + else + { + fputs(ibuf, rfp); + ++ step; + } + } + else if (ibuf[0] != '#') + { + printf("Invalid preamble item: %s\n", ibuf); + err = 1; + } + else + { /* process preamble */ + char *xp, *pp = ibuf+2; + int n; + if(*amode) + { /* insert current time & date */ + time_t rtim = time(0); + fprintf(rfp, "# %s", ctime(&rtim)); + } + else + { + fputs(ibuf, rfp); + if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4) + || !strncmp(pp,"TDES ",5) + || !strncmp(pp,"PERMUTATION ",12) + || !strncmp(pp,"SUBSTITUTION ",13) + || !strncmp(pp,"VARIABLE ",9)) + { + /* get test type */ + if(!strncmp(pp,"DES ",4)) + pp+=4; + else if(!strncmp(pp,"TDES ",5)) + pp+=5; + xp = strchr(pp, ' '); + n = xp-pp; + strncpy(atest, pp, n); + atest[n] = '\0'; + /* get mode */ + xp = strrchr(pp, ' '); /* get mode" */ + n = strlen(xp+1)-1; + strncpy(amode, xp+1, n); + amode[n] = '\0'; + /* amode[3] = '\0'; */ + if (VERBOSE) + printf("Test=%s, Mode=%s\n",atest,amode); + } + } + } + break; + + case 1: /* [ENCRYPT] | [DECRYPT] */ + if(ibuf[0] == '\n') + break; + if (ibuf[0] == '[') + { + fputs(ibuf, rfp); + ++step; + if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) + dir = 1; + else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) + dir = 0; + else + { + printf("Invalid keyword: %s\n", ibuf); + err = 1; + } + break; + } + else if (dir == -1) + { + err = 1; + printf("Missing ENCRYPT/DECRYPT keyword\n"); + break; + } + else + step = 2; + + case 2: /* KEY = xxxx */ + if(*ibuf == '\n') + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"COUNT = ",8)) + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"COUNT=",6)) + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"NumKeys = ",10)) + { + numkeys=atoi(ibuf+10); + break; + } + + fputs(ibuf, rfp); + if(!strncasecmp(ibuf,"KEY = ",6)) + { + akeysz=64; + len = hex2bin((char*)ibuf+6, aKey); + if (len < 0) + { + printf("Invalid KEY\n"); + err=1; + break; + } + PrintValue("KEY", aKey, len); + ++step; + } + else if(!strncasecmp(ibuf,"KEYs = ",7)) + { + akeysz=64*3; + len=hex2bin(ibuf+7,aKey); + if(len != 8) + { + printf("Invalid KEY\n"); + err=1; + break; + } + memcpy(aKey+8,aKey,8); + memcpy(aKey+16,aKey,8); + ibuf[4]='\0'; + PrintValue("KEYs",aKey,len); + ++step; + } + else if(!strncasecmp(ibuf,"KEY",3)) + { + int n=ibuf[3]-'1'; + + akeysz=64*3; + len=hex2bin(ibuf+7,aKey+n*8); + if(len != 8) + { + printf("Invalid KEY\n"); + err=1; + break; + } + ibuf[4]='\0'; + PrintValue(ibuf,aKey,len); + if(n == 2) + ++step; + } + else + { + printf("Missing KEY\n"); + err = 1; + } + break; + + case 3: /* IV = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "IV = ", 5) != 0) + { + printf("Missing IV\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+5, iVec); + if (len < 0) + { + printf("Invalid IV\n"); + err =1; + break; + } + PrintValue("IV", iVec, len); + step = (dir)? 4: 5; + } + break; + + case 4: /* PLAINTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) + { + printf("Missing PLAINTEXT\n"); + err = 1; + } + else + { + int nn = strlen(ibuf+12); + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+12,nn-1,plaintext); + else + len=hex2bin(ibuf+12, plaintext); + if (len < 0) + { + printf("Invalid PLAINTEXT: %s", ibuf+12); + err =1; + break; + } + if (len >= sizeof(plaintext)) + { + printf("Buffer overflow\n"); + } + PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); + if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ + { + do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp); + } + else + { + assert(dir == 1); + ret = DESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + ciphertext, plaintext, len); + OutputValue("CIPHERTEXT",ciphertext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 5: /* CIPHERTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); + else + len = hex2bin(ibuf+13,ciphertext); + if (len < 0) + { + printf("Invalid CIPHERTEXT\n"); + err =1; + break; + } + + PrintValue("CIPHERTEXT", ciphertext, len); + if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ + { + do_mct(amode, akeysz, numkeys, aKey, iVec, + dir, ciphertext, len, rfp); + } + else + { + assert(dir == 0); + ret = DESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 6: + if (ibuf[0] != '\n') + { + err = 1; + printf("Missing terminator\n"); + } + else if (strcmp(atest, "MCT") != 0) + { /* MCT already added terminating nl */ + fputs(ibuf, rfp); + } + step = 1; + break; + } + } + if (rfp) + fclose(rfp); + if (afp) + fclose(afp); + return err; + } + +/*-------------------------------------------------- + Processes either a single file or + a set of files whose names are passed in a file. + A single file is specified as: + aes_test -f xxx.req + A set of files is specified as: + aes_test -d xxxxx.xxx + The default is: -d req.txt +--------------------------------------------------*/ +int main(int argc, char **argv) + { + char *rqlist = "req.txt", *rspfile = NULL; + FILE *fp = NULL; + char fn[250] = "", rfn[256] = ""; + int f_opt = 0, d_opt = 1; + +#ifdef OPENSSL_FIPS + if(!FIPS_mode_set(1)) + { + do_print_errors(); + EXIT(1); + } +#endif + if (argc > 1) + { + if (strcasecmp(argv[1], "-d") == 0) + { + d_opt = 1; + } + else if (strcasecmp(argv[1], "-f") == 0) + { + f_opt = 1; + d_opt = 0; + } + else + { + printf("Invalid parameter: %s\n", argv[1]); + return 0; + } + if (argc < 3) + { + printf("Missing parameter\n"); + return 0; + } + if (d_opt) + rqlist = argv[2]; + else + { + strcpy(fn, argv[2]); + rspfile = argv[3]; + } + } + if (d_opt) + { /* list of files (directory) */ + if (!(fp = fopen(rqlist, "r"))) + { + printf("Cannot open req list file\n"); + return -1; + } + while (fgets(fn, sizeof(fn), fp)) + { + strtok(fn, "\r\n"); + strcpy(rfn, fn); + printf("Processing: %s\n", rfn); + if (proc_file(rfn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", rfn); + EXIT(1); + } + } + fclose(fp); + } + else /* single file */ + { + if (VERBOSE) + printf("Processing: %s\n", fn); + if (proc_file(fn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", fn); + } + } + EXIT(0); + return 0; + } + +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_dssvs.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_dssvs.c --- openssl-1.0.0k/crypto/fips/cavs/fips_dssvs.c.fips 2013-02-19 20:12:54.591664800 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_dssvs.c 2013-02-19 20:12:54.591664800 +0100 @@ -0,0 +1,537 @@ +#include + +#ifndef OPENSSL_FIPS +#include + +int main(int argc, char **argv) +{ + printf("No FIPS DSA support\n"); + return(0); +} +#else + +#include +#include +#include +#include +#include +#include +#include + +#include "fips_utl.h" + +static void pbn(const char *name, BIGNUM *bn) + { + int len, i; + unsigned char *tmp; + len = BN_num_bytes(bn); + tmp = OPENSSL_malloc(len); + if (!tmp) + { + fprintf(stderr, "Memory allocation error\n"); + return; + } + BN_bn2bin(bn, tmp); + printf("%s = ", name); + for (i = 0; i < len; i++) + printf("%02X", tmp[i]); + fputs("\n", stdout); + OPENSSL_free(tmp); + return; + } + +void primes() + { + char buf[10240]; + char lbuf[10240]; + char *keyword, *value; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Prime")) + { + BIGNUM *pp; + + pp=BN_new(); + do_hex2bn(&pp,value); + printf("result= %c\n", + BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F'); + } + } + } + +void pqg() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"N")) + { + int n=atoi(value); + + printf("[mod = %d]\n\n",nmod); + + while(n--) + { + unsigned char seed[20]; + DSA *dsa; + int counter; + unsigned long h; + dsa = FIPS_dsa_new(); + + if (!DSA_generate_parameters_ex(dsa, nmod,seed,0,&counter,&h,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + pv("Seed",seed,20); + printf("c = %d\n",counter); + printf("H = %lx\n",h); + putc('\n',stdout); + } + } + else + fputs(buf,stdout); + } + } + +void pqgver() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + BIGNUM *p = NULL, *q = NULL, *g = NULL; + int counter, counter2; + unsigned long h, h2; + DSA *dsa=NULL; + int nmod=0; + unsigned char seed[1024]; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + fputs(buf, stdout); + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"P")) + p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + q=hex2bn(value); + else if(!strcmp(keyword,"G")) + g=hex2bn(value); + else if(!strcmp(keyword,"Seed")) + { + int slen = hex2bin(value, seed); + if (slen != 20) + { + fprintf(stderr, "Seed parse length error\n"); + exit (1); + } + } + else if(!strcmp(keyword,"c")) + counter =atoi(buf+4); + else if(!strcmp(keyword,"H")) + { + h = atoi(value); + if (!p || !q || !g) + { + fprintf(stderr, "Parse Error\n"); + exit (1); + } + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL)) + { + do_print_errors(); + exit(1); + } + if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g) + || (counter != counter2) || (h != h2)) + printf("Result = F\n"); + else + printf("Result = P\n"); + BN_free(p); + BN_free(q); + BN_free(g); + p = NULL; + q = NULL; + g = NULL; + FIPS_dsa_free(dsa); + dsa = NULL; + } + } + } + +/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2 + * algorithm tests. It is an additional test to perform sanity checks on the + * output of the KeyPair test. + */ + +static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g, + BN_CTX *ctx) + { + BIGNUM *rem = NULL; + if (BN_num_bits(p) != nmod) + return 0; + if (BN_num_bits(q) != 160) + return 0; + if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1) + return 0; + if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1) + return 0; + rem = BN_new(); + if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem) + || (BN_cmp(g, BN_value_one()) <= 0) + || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) + { + BN_free(rem); + return 0; + } + /* Todo: check g */ + BN_free(rem); + return 1; + } + +void keyver() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL; + BIGNUM *Y2; + BN_CTX *ctx = NULL; + int nmod=0, paramcheck = 0; + + ctx = BN_CTX_new(); + Y2 = BN_new(); + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + if (p) + BN_free(p); + p = NULL; + if (q) + BN_free(q); + q = NULL; + if (g) + BN_free(g); + g = NULL; + paramcheck = 0; + nmod=atoi(value); + } + else if(!strcmp(keyword,"P")) + p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + q=hex2bn(value); + else if(!strcmp(keyword,"G")) + g=hex2bn(value); + else if(!strcmp(keyword,"X")) + X=hex2bn(value); + else if(!strcmp(keyword,"Y")) + { + Y=hex2bn(value); + if (!p || !q || !g || !X || !Y) + { + fprintf(stderr, "Parse Error\n"); + exit (1); + } + pbn("P",p); + pbn("Q",q); + pbn("G",g); + pbn("X",X); + pbn("Y",Y); + if (!paramcheck) + { + if (dss_paramcheck(nmod, p, q, g, ctx)) + paramcheck = 1; + else + paramcheck = -1; + } + if (paramcheck != 1) + printf("Result = F\n"); + else + { + if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y)) + printf("Result = F\n"); + else + printf("Result = P\n"); + } + BN_free(X); + BN_free(Y); + X = NULL; + Y = NULL; + } + } + if (p) + BN_free(p); + if (q) + BN_free(q); + if (g) + BN_free(g); + if (Y2) + BN_free(Y2); + } + +void keypair() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"N")) + { + DSA *dsa; + int n=atoi(value); + + printf("[mod = %d]\n\n",nmod); + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + + while(n--) + { + if (!DSA_generate_key(dsa)) + { + do_print_errors(); + exit(1); + } + + pbn("X",dsa->priv_key); + pbn("Y",dsa->pub_key); + putc('\n',stdout); + } + } + } + } + +void siggen() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + DSA *dsa=NULL; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + nmod=atoi(value); + printf("[mod = %d]\n\n",nmod); + if (dsa) + FIPS_dsa_free(dsa); + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + } + else if(!strcmp(keyword,"Msg")) + { + unsigned char msg[1024]; + unsigned char sbuf[60]; + unsigned int slen; + int n; + EVP_PKEY pk; + EVP_MD_CTX mctx; + DSA_SIG *sig; + EVP_MD_CTX_init(&mctx); + + n=hex2bin(value,msg); + pv("Msg",msg,n); + + if (!DSA_generate_key(dsa)) + { + do_print_errors(); + exit(1); + } + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + pbn("Y",dsa->pub_key); + + EVP_SignInit_ex(&mctx, EVP_dss1(), NULL); + EVP_SignUpdate(&mctx, msg, n); + EVP_SignFinal(&mctx, sbuf, &slen, &pk); + + sig = DSA_SIG_new(); + FIPS_dsa_sig_decode(sig, sbuf, slen); + + pbn("R",sig->r); + pbn("S",sig->s); + putc('\n',stdout); + DSA_SIG_free(sig); + EVP_MD_CTX_cleanup(&mctx); + } + } + if (dsa) + FIPS_dsa_free(dsa); + } + +void sigver() + { + DSA *dsa=NULL; + char buf[1024]; + char lbuf[1024]; + unsigned char msg[1024]; + char *keyword, *value; + int nmod=0, n=0; + DSA_SIG sg, *sig = &sg; + + sig->r = NULL; + sig->s = NULL; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + nmod=atoi(value); + if(dsa) + FIPS_dsa_free(dsa); + dsa=FIPS_dsa_new(); + } + else if(!strcmp(keyword,"P")) + dsa->p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + dsa->q=hex2bn(value); + else if(!strcmp(keyword,"G")) + { + dsa->g=hex2bn(value); + + printf("[mod = %d]\n\n",nmod); + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + } + else if(!strcmp(keyword,"Msg")) + { + n=hex2bin(value,msg); + pv("Msg",msg,n); + } + else if(!strcmp(keyword,"Y")) + dsa->pub_key=hex2bn(value); + else if(!strcmp(keyword,"R")) + sig->r=hex2bn(value); + else if(!strcmp(keyword,"S")) + { + EVP_MD_CTX mctx; + EVP_PKEY pk; + unsigned char sigbuf[60]; + unsigned int slen; + int r; + EVP_MD_CTX_init(&mctx); + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + sig->s=hex2bn(value); + + pbn("Y",dsa->pub_key); + pbn("R",sig->r); + pbn("S",sig->s); + + slen = FIPS_dsa_sig_encode(sigbuf, sig); + EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL); + EVP_VerifyUpdate(&mctx, msg, n); + r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk); + EVP_MD_CTX_cleanup(&mctx); + + printf("Result = %c\n", r == 1 ? 'P' : 'F'); + putc('\n',stdout); + } + } + } + +int main(int argc,char **argv) + { + if(argc != 2) + { + fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]); + exit(1); + } + if(!FIPS_mode_set(1)) + { + do_print_errors(); + exit(1); + } + if(!strcmp(argv[1],"prime")) + primes(); + else if(!strcmp(argv[1],"pqg")) + pqg(); + else if(!strcmp(argv[1],"pqgver")) + pqgver(); + else if(!strcmp(argv[1],"keypair")) + keypair(); + else if(!strcmp(argv[1],"keyver")) + keyver(); + else if(!strcmp(argv[1],"siggen")) + siggen(); + else if(!strcmp(argv[1],"sigver")) + sigver(); + else + { + fprintf(stderr,"Don't know how to %s.\n",argv[1]); + exit(1); + } + + return 0; + } + +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_rngvs.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_rngvs.c --- openssl-1.0.0k/crypto/fips/cavs/fips_rngvs.c.fips 2013-02-19 20:12:54.591664800 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_rngvs.c 2013-02-19 20:12:54.591664800 +0100 @@ -0,0 +1,230 @@ +/* + * Crude test driver for processing the VST and MCT testvector files + * generated by the CMVP RNGVS product. + * + * Note the input files are assumed to have a _very_ specific format + * as described in the NIST document "The Random Number Generator + * Validation System (RNGVS)", May 25, 2004. + * + */ +#include + +#ifndef OPENSSL_FIPS +#include + +int main(int argc, char **argv) +{ + printf("No FIPS RNG support\n"); + return 0; +} +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fips_utl.h" + +void vst() + { + unsigned char *key = NULL; + unsigned char *v = NULL; + unsigned char *dt = NULL; + unsigned char ret[16]; + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + long i, keylen; + + keylen = 0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if(!strncmp(buf,"[AES 128-Key]", 13)) + keylen = 16; + else if(!strncmp(buf,"[AES 192-Key]", 13)) + keylen = 24; + else if(!strncmp(buf,"[AES 256-Key]", 13)) + keylen = 32; + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Key")) + { + key=hex2bin_m(value,&i); + if (i != keylen) + { + fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); + return; + } + } + else if(!strcmp(keyword,"DT")) + { + dt=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid DT length\n"); + return; + } + } + else if(!strcmp(keyword,"V")) + { + v=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid V length\n"); + return; + } + + if (!key || !dt) + { + fprintf(stderr, "Missing key or DT\n"); + return; + } + + FIPS_rand_set_key(key, keylen); + FIPS_rand_seed(v,16); + FIPS_rand_set_dt(dt); + if (FIPS_rand_bytes(ret,16) <= 0) + { + fprintf(stderr, "Error getting PRNG value\n"); + return; + } + + pv("R",ret,16); + OPENSSL_free(key); + key = NULL; + OPENSSL_free(dt); + dt = NULL; + OPENSSL_free(v); + v = NULL; + } + } + } + +void mct() + { + unsigned char *key = NULL; + unsigned char *v = NULL; + unsigned char *dt = NULL; + unsigned char ret[16]; + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + long i, keylen; + int j; + + keylen = 0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if(!strncmp(buf,"[AES 128-Key]", 13)) + keylen = 16; + else if(!strncmp(buf,"[AES 192-Key]", 13)) + keylen = 24; + else if(!strncmp(buf,"[AES 256-Key]", 13)) + keylen = 32; + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Key")) + { + key=hex2bin_m(value,&i); + if (i != keylen) + { + fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); + return; + } + } + else if(!strcmp(keyword,"DT")) + { + dt=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid DT length\n"); + return; + } + } + else if(!strcmp(keyword,"V")) + { + v=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid V length\n"); + return; + } + + if (!key || !dt) + { + fprintf(stderr, "Missing key or DT\n"); + return; + } + + FIPS_rand_set_key(key, keylen); + FIPS_rand_seed(v,16); + for (i = 0; i < 10000; i++) + { + FIPS_rand_set_dt(dt); + if (FIPS_rand_bytes(ret,16) <= 0) + { + fprintf(stderr, "Error getting PRNG value\n"); + return; + } + /* Increment DT */ + for (j = 15; j >= 0; j--) + { + dt[j]++; + if (dt[j]) + break; + } + } + + pv("R",ret,16); + OPENSSL_free(key); + key = NULL; + OPENSSL_free(dt); + dt = NULL; + OPENSSL_free(v); + v = NULL; + } + } + } + +int main(int argc,char **argv) + { + if(argc != 2) + { + fprintf(stderr,"%s [mct|vst]\n",argv[0]); + exit(1); + } + if(!FIPS_mode_set(1)) + { + do_print_errors(); + exit(1); + } + FIPS_rand_reset(); + if (!FIPS_rand_test_mode()) + { + fprintf(stderr, "Error setting PRNG test mode\n"); + do_print_errors(); + exit(1); + } + if(!strcmp(argv[1],"mct")) + mct(); + else if(!strcmp(argv[1],"vst")) + vst(); + else + { + fprintf(stderr,"Don't know how to %s.\n",argv[1]); + exit(1); + } + + return 0; + } +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_rsagtest.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_rsagtest.c --- openssl-1.0.0k/crypto/fips/cavs/fips_rsagtest.c.fips 2013-02-19 20:12:54.592664819 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_rsagtest.c 2013-02-19 20:12:54.592664819 +0100 @@ -0,0 +1,390 @@ +/* fips_rsagtest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005,2007 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in); +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e); +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_test(out, in)) + { + fprintf(stderr, "FATAL RSAGTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_test(FILE *out, FILE *in) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL; + BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL; + BIGNUM *e = NULL; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [foo = bar] line) just copy */ + if (!p || *keyword=='[') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword, "xp1")) + { + if (Xp1 || !do_hex2bn(&Xp1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xp2")) + { + if (Xp2 || !do_hex2bn(&Xp2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xp")) + { + if (Xp || !do_hex2bn(&Xp,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq1")) + { + if (Xq1 || !do_hex2bn(&Xq1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq2")) + { + if (Xq2 || !do_hex2bn(&Xq2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xq")) + { + if (Xq || !do_hex2bn(&Xq,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (e || !do_hex2bn(&e,value)) + goto parse_error; + } + else if (!strcmp(keyword, "p1")) + continue; + else if (!strcmp(keyword, "p2")) + continue; + else if (!strcmp(keyword, "p")) + continue; + else if (!strcmp(keyword, "q1")) + continue; + else if (!strcmp(keyword, "q2")) + continue; + else if (!strcmp(keyword, "q")) + continue; + else if (!strcmp(keyword, "n")) + continue; + else if (!strcmp(keyword, "d")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (e && Xp1 && Xp2 && Xp) + { + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e)) + goto error; + BN_free(Xp1); + Xp1 = NULL; + BN_free(Xp2); + Xp2 = NULL; + BN_free(Xp); + Xp = NULL; + BN_free(e); + e = NULL; + } + + if (rsa && Xq1 && Xq2 && Xq) + { + if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq)) + goto error; + BN_free(Xq1); + Xq1 = NULL; + BN_free(Xq2); + Xq2 = NULL; + BN_free(Xq); + Xq = NULL; + FIPS_rsa_free(rsa); + rsa = NULL; + } + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + + if (Xp1) + BN_free(Xp1); + if (Xp2) + BN_free(Xp2); + if (Xp) + BN_free(Xp); + if (Xq1) + BN_free(Xq1); + if (Xq1) + BN_free(Xq1); + if (Xq2) + BN_free(Xq2); + if (Xq) + BN_free(Xq); + if (e) + BN_free(e); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e) + { + int ret = 0; + BIGNUM *p1 = NULL, *p2 = NULL; + p1 = BN_new(); + p2 = BN_new(); + if (!p1 || !p2) + goto error; + + if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp, + NULL, NULL, NULL, e, NULL)) + goto error; + + do_bn_print_name(out, "p1", p1); + do_bn_print_name(out, "p2", p2); + do_bn_print_name(out, "p", rsa->p); + + ret = 1; + + error: + if (p1) + BN_free(p1); + if (p2) + BN_free(p2); + + return ret; + } + +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq) + { + int ret = 0; + BIGNUM *q1 = NULL, *q2 = NULL; + q1 = BN_new(); + q2 = BN_new(); + if (!q1 || !q2) + goto error; + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL, + Xq1, Xq2, Xq, NULL, NULL)) + goto error; + + do_bn_print_name(out, "q1", q1); + do_bn_print_name(out, "q2", q2); + do_bn_print_name(out, "q", rsa->q); + do_bn_print_name(out, "n", rsa->n); + do_bn_print_name(out, "d", rsa->d); + + ret = 1; + + error: + if (q1) + BN_free(q1); + if (q2) + BN_free(q2); + + return ret; + } + +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_rsastest.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_rsastest.c --- openssl-1.0.0k/crypto/fips/cavs/fips_rsastest.c.fips 2013-02-19 20:12:54.592664819 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_rsastest.c 2013-02-19 20:12:54.592664819 +0100 @@ -0,0 +1,370 @@ +/* fips_rsastest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +static int rsa_stest(FILE *out, FILE *in, int Saltlen); +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1, Saltlen = -1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if ((argc > 2) && !strcmp("-saltlen", argv[1])) + { + Saltlen = atoi(argv[2]); + if (Saltlen < 0) + { + fprintf(stderr, "FATAL: Invalid salt length\n"); + goto end; + } + argc -= 2; + argv += 2; + } + else if ((argc > 1) && !strcmp("-x931", argv[1])) + { + Saltlen = -2; + argc--; + argv++; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_stest(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSASTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_stest(FILE *out, FILE *in, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + const EVP_MD *dgst = NULL; + unsigned char *Msg = NULL; + long Msglen = -1; + int keylen = -1, current_keylen = -1; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = just copy */ + if (!p) + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + /* Look for [mod = XXX] for key length */ + + if (!strcmp(keyword, "[mod")) + { + p = value + strlen(value) - 1; + if (*p != ']') + goto parse_error; + *p = 0; + keylen = atoi(value); + if (keylen < 0) + goto parse_error; + } + else if (!strcmp(keyword, "SHAAlg")) + { + if (!strcmp(value, "SHA1")) + dgst = EVP_sha1(); + else if (!strcmp(value, "SHA224")) + dgst = EVP_sha224(); + else if (!strcmp(value, "SHA256")) + dgst = EVP_sha256(); + else if (!strcmp(value, "SHA384")) + dgst = EVP_sha384(); + else if (!strcmp(value, "SHA512")) + dgst = EVP_sha512(); + else + { + fprintf(stderr, + "FATAL: unsupported algorithm \"%s\"\n", + value); + goto parse_error; + } + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + + fputs(olinebuf, out); + + /* If key length has changed, generate and output public + * key components of new RSA private key. + */ + + if (keylen != current_keylen) + { + BIGNUM *bn_e; + if (rsa) + FIPS_rsa_free(rsa); + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + bn_e = BN_new(); + if (!bn_e || !BN_set_word(bn_e, 0x1001)) + goto error; + if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL)) + goto error; + BN_free(bn_e); + fputs("n = ", out); + do_bn_print(out, rsa->n); + fputs("\ne = ", out); + do_bn_print(out, rsa->e); + fputs("\n", out); + current_keylen = keylen; + } + + if (Msg && dgst) + { + if (!rsa_printsig(out, rsa, dgst, Msg, Msglen, + Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + } + + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen) + { + int ret = 0; + unsigned char *sigbuf = NULL; + int i, siglen; + /* EVP_PKEY structure */ + EVP_PKEY pk; + EVP_MD_CTX ctx; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa; + + siglen = RSA_size(rsa); + sigbuf = OPENSSL_malloc(siglen); + if (!sigbuf) + goto error; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_SignInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_SignUpdate(&ctx, Msg, Msglen)) + goto error; + if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) + goto error; + + EVP_MD_CTX_cleanup(&ctx); + + fputs("S = ", out); + + for (i = 0; i < siglen; i++) + fprintf(out, "%02X", sigbuf[i]); + + fputs("\n", out); + + ret = 1; + + error: + + return ret; + } +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_rsavtest.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_rsavtest.c --- openssl-1.0.0k/crypto/fips/cavs/fips_rsavtest.c.fips 2013-02-19 20:12:54.592664819 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_rsavtest.c 2013-02-19 20:12:54.592664819 +0100 @@ -0,0 +1,377 @@ +/* fips_rsavtest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in, int saltlen); +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + int Saltlen = -1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if ((argc > 2) && !strcmp("-saltlen", argv[1])) + { + Saltlen = atoi(argv[2]); + if (Saltlen < 0) + { + fprintf(stderr, "FATAL: Invalid salt length\n"); + goto end; + } + argc -= 2; + argv += 2; + } + else if ((argc > 1) && !strcmp("-x931", argv[1])) + { + Saltlen = -2; + argc--; + argv++; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_test(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSAVTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_test(FILE *out, FILE *in, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + const EVP_MD *dgst = NULL; + BIGNUM *n = NULL, *e = NULL; + unsigned char *Msg = NULL, *S = NULL; + long Msglen, Slen; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [foo = bar] line) just copy */ + if (!p || *keyword=='[') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword, "n")) + { + if (!do_hex2bn(&n,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (!do_hex2bn(&e,value)) + goto parse_error; + } + else if (!strcmp(keyword, "SHAAlg")) + { + if (!strcmp(value, "SHA1")) + dgst = EVP_sha1(); + else if (!strcmp(value, "SHA224")) + dgst = EVP_sha224(); + else if (!strcmp(value, "SHA256")) + dgst = EVP_sha256(); + else if (!strcmp(value, "SHA384")) + dgst = EVP_sha384(); + else if (!strcmp(value, "SHA512")) + dgst = EVP_sha512(); + else + { + fprintf(stderr, + "FATAL: unsupported algorithm \"%s\"\n", + value); + goto parse_error; + } + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + else if (!strcmp(keyword, "S")) + { + if (S) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + S = hex2bin_m(value, &Slen); + if (!S) + goto parse_error; + } + else if (!strcmp(keyword, "Result")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (n && e && Msg && S && dgst) + { + if (!rsa_printver(out, n, e, dgst, + Msg, Msglen, S, Slen, Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + OPENSSL_free(S); + S = NULL; + } + + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (n) + BN_free(n); + if (e) + BN_free(e); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen) + { + int ret = 0, r; + /* Setup RSA and EVP_PKEY structures */ + RSA *rsa_pubkey = NULL; + EVP_PKEY pk; + EVP_MD_CTX ctx; + unsigned char *buf = NULL; + rsa_pubkey = FIPS_rsa_new(); + if (!rsa_pubkey) + goto error; + rsa_pubkey->n = BN_dup(n); + rsa_pubkey->e = BN_dup(e); + if (!rsa_pubkey->n || !rsa_pubkey->e) + goto error; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa_pubkey; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_VerifyInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_VerifyUpdate(&ctx, Msg, Msglen)) + goto error; + + r = EVP_VerifyFinal(&ctx, S, Slen, &pk); + + + EVP_MD_CTX_cleanup(&ctx); + + if (r < 0) + goto error; + ERR_clear_error(); + + if (r == 0) + fputs("Result = F\n", out); + else + fputs("Result = P\n", out); + + ret = 1; + + error: + if (rsa_pubkey) + FIPS_rsa_free(rsa_pubkey); + if (buf) + OPENSSL_free(buf); + + return ret; + } +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_shatest.c.fips openssl-1.0.0k/crypto/fips/cavs/fips_shatest.c --- openssl-1.0.0k/crypto/fips/cavs/fips_shatest.c.fips 2013-02-19 20:12:54.592664819 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_shatest.c 2013-02-19 20:12:54.592664819 +0100 @@ -0,0 +1,388 @@ +/* fips_shatest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS SHAXXX support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +static int dgst_test(FILE *out, FILE *in); +static int print_dgst(const EVP_MD *md, FILE *out, + unsigned char *Msg, int Msglen); +static int print_monte(const EVP_MD *md, FILE *out, + unsigned char *Seed, int SeedLen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!dgst_test(out, in)) + { + fprintf(stderr, "FATAL digest file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define SHA_TEST_MAX_BITS 102400 +#define SHA_TEST_MAXLINELEN (((SHA_TEST_MAX_BITS >> 3) * 2) + 100) + +int dgst_test(FILE *out, FILE *in) + { + const EVP_MD *md = NULL; + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + unsigned char *Msg = NULL, *Seed = NULL; + long MsgLen = -1, Len = -1, SeedLen = -1; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + + while (fgets(olinebuf, SHA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [L=20] line) just copy */ + if (!p) + { + fputs(olinebuf, out); + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword,"[L") && *p==']') + { + switch (atoi(value)) + { + case 20: md=EVP_sha1(); break; + case 28: md=EVP_sha224(); break; + case 32: md=EVP_sha256(); break; + case 48: md=EVP_sha384(); break; + case 64: md=EVP_sha512(); break; + default: goto parse_error; + } + } + else if (!strcmp(keyword, "Len")) + { + if (Len != -1) + goto parse_error; + Len = atoi(value); + if (Len < 0) + goto parse_error; + /* Only handle multiples of 8 bits */ + if (Len & 0x7) + goto parse_error; + if (Len > SHA_TEST_MAX_BITS) + goto parse_error; + MsgLen = Len >> 3; + } + + else if (!strcmp(keyword, "Msg")) + { + long tmplen; + if (strlen(value) & 1) + *(--value) = '0'; + if (Msg) + goto parse_error; + Msg = hex2bin_m(value, &tmplen); + if (!Msg) + goto parse_error; + } + else if (!strcmp(keyword, "Seed")) + { + if (strlen(value) & 1) + *(--value) = '0'; + if (Seed) + goto parse_error; + Seed = hex2bin_m(value, &SeedLen); + if (!Seed) + goto parse_error; + } + else if (!strcmp(keyword, "MD")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (md && Msg && (MsgLen >= 0)) + { + if (!print_dgst(md, out, Msg, MsgLen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + MsgLen = -1; + Len = -1; + } + else if (md && Seed && (SeedLen > 0)) + { + if (!print_monte(md, out, Seed, SeedLen)) + goto error; + OPENSSL_free(Seed); + Seed = NULL; + SeedLen = -1; + } + + + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (Msg) + OPENSSL_free(Msg); + if (Seed) + OPENSSL_free(Seed); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int print_dgst(const EVP_MD *emd, FILE *out, + unsigned char *Msg, int Msglen) + { + int i, mdlen; + unsigned char md[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(Msg, Msglen, md, (unsigned int *)&mdlen, emd, NULL)) + { + fputs("Error calculating HASH\n", stderr); + return 0; + } + fputs("MD = ", out); + for (i = 0; i < mdlen; i++) + fprintf(out, "%02x", md[i]); + fputs("\n", out); + return 1; + } + +static int print_monte(const EVP_MD *md, FILE *out, + unsigned char *Seed, int SeedLen) + { + unsigned int i, j, k; + int ret = 0; + EVP_MD_CTX ctx; + unsigned char *m1, *m2, *m3, *p; + unsigned int mlen, m1len, m2len, m3len; + + EVP_MD_CTX_init(&ctx); + + if (SeedLen > EVP_MAX_MD_SIZE) + mlen = SeedLen; + else + mlen = EVP_MAX_MD_SIZE; + + m1 = OPENSSL_malloc(mlen); + m2 = OPENSSL_malloc(mlen); + m3 = OPENSSL_malloc(mlen); + + if (!m1 || !m2 || !m3) + goto mc_error; + + m1len = m2len = m3len = SeedLen; + memcpy(m1, Seed, SeedLen); + memcpy(m2, Seed, SeedLen); + memcpy(m3, Seed, SeedLen); + + fputs("\n", out); + + for (j = 0; j < 100; j++) + { + for (i = 0; i < 1000; i++) + { + EVP_DigestInit_ex(&ctx, md, NULL); + EVP_DigestUpdate(&ctx, m1, m1len); + EVP_DigestUpdate(&ctx, m2, m2len); + EVP_DigestUpdate(&ctx, m3, m3len); + p = m1; + m1 = m2; + m1len = m2len; + m2 = m3; + m2len = m3len; + m3 = p; + EVP_DigestFinal_ex(&ctx, m3, &m3len); + } + fprintf(out, "COUNT = %d\n", j); + fputs("MD = ", out); + for (k = 0; k < m3len; k++) + fprintf(out, "%02x", m3[k]); + fputs("\n\n", out); + memcpy(m1, m3, m3len); + memcpy(m2, m3, m3len); + m1len = m2len = m3len; + } + + ret = 1; + + mc_error: + if (m1) + OPENSSL_free(m1); + if (m2) + OPENSSL_free(m2); + if (m3) + OPENSSL_free(m3); + + EVP_MD_CTX_cleanup(&ctx); + + return ret; + } + +#endif diff -up openssl-1.0.0k/crypto/fips/cavs/fips_utl.h.fips openssl-1.0.0k/crypto/fips/cavs/fips_utl.h --- openssl-1.0.0k/crypto/fips/cavs/fips_utl.h.fips 2013-02-19 20:12:54.593664838 +0100 +++ openssl-1.0.0k/crypto/fips/cavs/fips_utl.h 2013-02-19 20:12:54.593664838 +0100 @@ -0,0 +1,343 @@ +/* ==================================================================== + * Copyright (c) 2007 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 + * 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. + * + */ + +void do_print_errors(void) + { + const char *file, *data; + int line, flags; + unsigned long l; + while ((l = ERR_get_error_line_data(&file, &line, &data, &flags))) + { + fprintf(stderr, "ERROR:%lx:lib=%d,func=%d,reason=%d" + ":file=%s:line=%d:%s\n", + l, ERR_GET_LIB(l), ERR_GET_FUNC(l), ERR_GET_REASON(l), + file, line, flags & ERR_TXT_STRING ? data : ""); + } + } + +int hex2bin(const char *in, unsigned char *out) + { + int n1, n2; + unsigned char ch; + + for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; ) + { /* first byte */ + if ((in[n1] >= '0') && (in[n1] <= '9')) + ch = in[n1++] - '0'; + else if ((in[n1] >= 'A') && (in[n1] <= 'F')) + ch = in[n1++] - 'A' + 10; + else if ((in[n1] >= 'a') && (in[n1] <= 'f')) + ch = in[n1++] - 'a' + 10; + else + return -1; + if(!in[n1]) + { + out[n2++]=ch; + break; + } + out[n2] = ch << 4; + /* second byte */ + if ((in[n1] >= '0') && (in[n1] <= '9')) + ch = in[n1++] - '0'; + else if ((in[n1] >= 'A') && (in[n1] <= 'F')) + ch = in[n1++] - 'A' + 10; + else if ((in[n1] >= 'a') && (in[n1] <= 'f')) + ch = in[n1++] - 'a' + 10; + else + return -1; + out[n2++] |= ch; + } + return n2; + } + +unsigned char *hex2bin_m(const char *in, long *plen) + { + unsigned char *p; + p = OPENSSL_malloc((strlen(in) + 1)/2); + *plen = hex2bin(in, p); + return p; + } + +int do_hex2bn(BIGNUM **pr, const char *in) + { + unsigned char *p; + long plen; + int r = 0; + p = hex2bin_m(in, &plen); + if (!p) + return 0; + if (!*pr) + *pr = BN_new(); + if (!*pr) + return 0; + if (BN_bin2bn(p, plen, *pr)) + r = 1; + OPENSSL_free(p); + return r; + } + +int do_bn_print(FILE *out, BIGNUM *bn) + { + int len, i; + unsigned char *tmp; + len = BN_num_bytes(bn); + if (len == 0) + { + fputs("00", out); + return 1; + } + + tmp = OPENSSL_malloc(len); + if (!tmp) + { + fprintf(stderr, "Memory allocation error\n"); + return 0; + } + BN_bn2bin(bn, tmp); + for (i = 0; i < len; i++) + fprintf(out, "%02x", tmp[i]); + OPENSSL_free(tmp); + return 1; + } + +int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn) + { + int r; + fprintf(out, "%s = ", name); + r = do_bn_print(out, bn); + if (!r) + return 0; + fputs("\n", out); + return 1; + } + +int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf) + { + char *keyword, *value, *p, *q; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no '=' exit */ + if (!p) + return 0; + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + *pkw = keyword; + *pval = value; + return 1; + } + +BIGNUM *hex2bn(const char *in) + { + BIGNUM *p=NULL; + + if (!do_hex2bn(&p, in)) + return NULL; + + return p; + } + +int bin2hex(const unsigned char *in,int len,char *out) + { + int n1, n2; + unsigned char ch; + + for (n1=0,n2=0 ; n1 < len ; ++n1) + { + ch=in[n1] >> 4; + if (ch <= 0x09) + out[n2++]=ch+'0'; + else + out[n2++]=ch-10+'a'; + ch=in[n1] & 0x0f; + if(ch <= 0x09) + out[n2++]=ch+'0'; + else + out[n2++]=ch-10+'a'; + } + out[n2]='\0'; + return n2; + } + +void pv(const char *tag,const unsigned char *val,int len) + { + char obuf[2048]; + + bin2hex(val,len,obuf); + printf("%s = %s\n",tag,obuf); + } + +/* To avoid extensive changes to test program at this stage just convert + * the input line into an acceptable form. Keyword lines converted to form + * "keyword = value\n" no matter what white space present, all other lines + * just have leading and trailing space removed. + */ + +int tidy_line(char *linebuf, char *olinebuf) + { + char *keyword, *value, *p, *q; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no '=' just chop leading, trailing ws */ + if (!p) + { + p = keyword + strlen(keyword) - 1; + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + strcpy(olinebuf, keyword); + strcat(olinebuf, "\n"); + return 1; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + strcpy(olinebuf, keyword); + strcat(olinebuf, " = "); + strcat(olinebuf, value); + strcat(olinebuf, "\n"); + + return 1; + } + +/* NB: this return the number of _bits_ read */ +int bint2bin(const char *in, int len, unsigned char *out) + { + int n; + + memset(out,0,len); + for(n=0 ; n < len ; ++n) + if(in[n] == '1') + out[n/8]|=(0x80 >> (n%8)); + return len; + } + +int bin2bint(const unsigned char *in,int len,char *out) + { + int n; + + for(n=0 ; n < len ; ++n) + out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0'; + return n; + } + +/*-----------------------------------------------*/ + +void PrintValue(char *tag, unsigned char *val, int len) +{ +#if VERBOSE + char obuf[2048]; + int olen; + olen = bin2hex(val, len, obuf); + printf("%s = %.*s\n", tag, olen, obuf); +#endif +} + +void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode) + { + char obuf[2048]; + int olen; + + if(bitmode) + olen=bin2bint(val,len,obuf); + else + olen=bin2hex(val,len,obuf); + + fprintf(rfp, "%s = %.*s\n", tag, olen, obuf); +#if VERBOSE + printf("%s = %.*s\n", tag, olen, obuf); +#endif + } + diff -up openssl-1.0.0k/crypto/fips_err.c.fips openssl-1.0.0k/crypto/fips_err.c --- openssl-1.0.0k/crypto/fips_err.c.fips 2013-02-19 20:12:54.593664838 +0100 +++ openssl-1.0.0k/crypto/fips_err.c 2013-02-19 20:12:54.593664838 +0100 @@ -0,0 +1,7 @@ +#include + +#ifdef OPENSSL_FIPS +# include "fips_err.h" +#else +static void *dummy=&dummy; +#endif diff -up openssl-1.0.0k/crypto/fips_err.h.fips openssl-1.0.0k/crypto/fips_err.h --- openssl-1.0.0k/crypto/fips_err.h.fips 2013-02-19 20:12:54.593664838 +0100 +++ openssl-1.0.0k/crypto/fips_err.h 2013-02-19 20:12:54.593664838 +0100 @@ -0,0 +1,137 @@ +/* crypto/fips_err.h */ +/* ==================================================================== + * Copyright (c) 1999-2007 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 + * 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason) + +static ERR_STRING_DATA FIPS_str_functs[]= + { +{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, +{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"}, +{ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"}, +{ERR_FUNC(FIPS_F_DSA_DO_VERIFY), "DSA_do_verify"}, +{ERR_FUNC(FIPS_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, +{ERR_FUNC(FIPS_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, +{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA), "FIPS_CHECK_DSA"}, +{ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT), "FIPS_CHECK_INCORE_FINGERPRINT"}, +{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "FIPS_CHECK_RSA"}, +{ERR_FUNC(FIPS_F_FIPS_DSA_CHECK), "FIPS_DSA_CHECK"}, +{ERR_FUNC(FIPS_F_FIPS_MODE_SET), "FIPS_mode_set"}, +{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"}, +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"}, +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"}, +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"}, +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"}, +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RNG), "FIPS_selftest_rng"}, +{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"}, +{ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"}, +{ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, +{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, +{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, +{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, +{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, +{ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX), "RSA_X931_generate_key_ex"}, +{ERR_FUNC(FIPS_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, +{0,NULL} + }; + +static ERR_STRING_DATA FIPS_str_reasons[]= + { +{ERR_REASON(FIPS_R_CANNOT_READ_EXE) ,"cannot read exe"}, +{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"}, +{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"}, +{ERR_REASON(FIPS_R_EXE_DIGEST_DOES_NOT_MATCH),"exe digest does not match"}, +{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH),"fingerprint does not match"}, +{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED),"fingerprint does not match nonpic relocated"}, +{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING),"fingerprint does not match segment aliasing"}, +{ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET),"fips mode already set"}, +{ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED) ,"fips selftest failed"}, +{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH) ,"invalid key length"}, +{ERR_REASON(FIPS_R_KEY_TOO_SHORT) ,"key too short"}, +{ERR_REASON(FIPS_R_NON_FIPS_METHOD) ,"non fips method"}, +{ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED) ,"pairwise test failed"}, +{ERR_REASON(FIPS_R_RSA_DECRYPT_ERROR) ,"rsa decrypt error"}, +{ERR_REASON(FIPS_R_RSA_ENCRYPT_ERROR) ,"rsa encrypt error"}, +{ERR_REASON(FIPS_R_SELFTEST_FAILED) ,"selftest failed"}, +{ERR_REASON(FIPS_R_TEST_FAILURE) ,"test failure"}, +{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"}, +{0,NULL} + }; + +#endif + +void ERR_load_FIPS_strings(void) + { +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL) + { + ERR_load_strings(0,FIPS_str_functs); + ERR_load_strings(0,FIPS_str_reasons); + } +#endif + } diff -up openssl-1.0.0k/crypto/fips/fips_aes_selftest.c.fips openssl-1.0.0k/crypto/fips/fips_aes_selftest.c --- openssl-1.0.0k/crypto/fips/fips_aes_selftest.c.fips 2013-02-19 20:12:54.593664838 +0100 +++ openssl-1.0.0k/crypto/fips/fips_aes_selftest.c 2013-02-19 20:12:54.593664838 +0100 @@ -0,0 +1,103 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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 +#ifdef OPENSSL_FIPS +#include +#endif +#include + +#ifdef OPENSSL_FIPS +static struct + { + unsigned char key[16]; + unsigned char plaintext[16]; + unsigned char ciphertext[16]; + } tests[]= + { + { + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, + { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, + 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }, + { 0x69,0xC4,0xE0,0xD8,0x6A,0x7B,0x04,0x30, + 0xD8,0xCD,0xB7,0x80,0x70,0xB4,0xC5,0x5A }, + }, + }; + +void FIPS_corrupt_aes() + { + tests[0].key[0]++; + } + +int FIPS_selftest_aes() + { + int n; + int ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + for(n=0 ; n < 1 ; ++n) + { + if (fips_cipher_test(&ctx, EVP_aes_128_ecb(), + tests[n].key, NULL, + tests[n].plaintext, + tests[n].ciphertext, + 16) <= 0) + goto err; + } + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED); + return ret; + } +#endif diff -up openssl-1.0.0k/crypto/fips/fips.c.fips openssl-1.0.0k/crypto/fips/fips.c --- openssl-1.0.0k/crypto/fips/fips.c.fips 2013-02-19 20:12:54.593664838 +0100 +++ openssl-1.0.0k/crypto/fips/fips.c 2013-02-19 20:12:54.593664838 +0100 @@ -0,0 +1,419 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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 +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +#include + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +static int fips_selftest_fail; +static int fips_mode; +static const void *fips_rand_check; + +static void fips_set_mode(int onoff) + { + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_w_lock(); + fips_mode = onoff; + if (!owning_thread) fips_w_unlock(); + } + } + +static void fips_set_rand_check(const void *rand_check) + { + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_w_lock(); + fips_rand_check = rand_check; + if (!owning_thread) fips_w_unlock(); + } + } + +int FIPS_mode(void) + { + int ret = 0; + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_r_lock(); + ret = fips_mode; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +const void *FIPS_rand_check(void) + { + const void *ret = 0; + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_r_lock(); + ret = fips_rand_check; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +int FIPS_selftest_failed(void) + { + int ret = 0; + if (fips_is_started()) + { + int owning_thread = fips_is_owning_thread(); + + if (!owning_thread) fips_r_lock(); + ret = fips_selftest_fail; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +/* Selftest failure fatal exit routine. This will be called + * during *any* cryptographic operation. It has the minimum + * overhead possible to avoid too big a performance hit. + */ + +void FIPS_selftest_check(void) + { + if (fips_selftest_fail) + { + OpenSSLDie(__FILE__,__LINE__, "FATAL FIPS SELFTEST FAILURE"); + } + } + +void fips_set_selftest_fail(void) + { + fips_selftest_fail = 1; + } + +int FIPS_selftest() + { + + return FIPS_selftest_sha1() + && FIPS_selftest_hmac() + && FIPS_selftest_aes() + && FIPS_selftest_des() + && FIPS_selftest_rsa() + && FIPS_selftest_dsa(); + } + +int FIPS_mode_set(int onoff) + { + int fips_set_owning_thread(); + int fips_clear_owning_thread(); + int ret = 0; + + fips_w_lock(); + fips_set_started(); + fips_set_owning_thread(); + + if(onoff) + { + unsigned char buf[48]; + + fips_selftest_fail = 0; + + /* Don't go into FIPS mode twice, just so we can do automagic + seeding */ + if(FIPS_mode()) + { + FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + +#ifdef OPENSSL_IA32_SSE2 + if ((OPENSSL_ia32cap & (1<<25|1<<26)) != (1<<25|1<<26)) + { + FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM); + fips_selftest_fail = 1; + ret = 0; + goto end; + } +#endif + + /* Perform RNG KAT before seeding */ + if (!FIPS_selftest_rng()) + { + fips_selftest_fail = 1; + ret = 0; + goto end; + } + + /* automagically seed PRNG if not already seeded */ + if(!FIPS_rand_status()) + { + if(RAND_bytes(buf,sizeof buf) <= 0) + { + fips_selftest_fail = 1; + ret = 0; + goto end; + } + FIPS_rand_set_key(buf,32); + FIPS_rand_seed(buf+32,16); + } + + /* now switch into FIPS mode */ + fips_set_rand_check(FIPS_rand_method()); + RAND_set_rand_method(FIPS_rand_method()); + if(FIPS_selftest()) + fips_set_mode(1); + else + { + fips_selftest_fail = 1; + ret = 0; + goto end; + } + ret = 1; + goto end; + } + fips_set_mode(0); + fips_selftest_fail = 0; + ret = 1; +end: + fips_clear_owning_thread(); + fips_w_unlock(); + return ret; + } + +void fips_w_lock(void) { CRYPTO_w_lock(CRYPTO_LOCK_FIPS); } +void fips_w_unlock(void) { CRYPTO_w_unlock(CRYPTO_LOCK_FIPS); } +void fips_r_lock(void) { CRYPTO_r_lock(CRYPTO_LOCK_FIPS); } +void fips_r_unlock(void) { CRYPTO_r_unlock(CRYPTO_LOCK_FIPS); } + +static int fips_started = 0; +static unsigned long fips_thread = 0; + +void fips_set_started(void) + { + fips_started = 1; + } + +int fips_is_started(void) + { + return fips_started; + } + +int fips_is_owning_thread(void) + { + int ret = 0; + + if (fips_is_started()) + { + CRYPTO_r_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread != 0 && fips_thread == CRYPTO_thread_id()) + ret = 1; + CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; + } + +int fips_set_owning_thread(void) + { + int ret = 0; + + if (fips_is_started()) + { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread == 0) + { + fips_thread = CRYPTO_thread_id(); + ret = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; + } + +int fips_clear_owning_thread(void) + { + int ret = 0; + + if (fips_is_started()) + { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread == CRYPTO_thread_id()) + { + fips_thread = 0; + ret = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; + } + +/* Generalized public key test routine. Signs and verifies the data + * supplied in tbs using mesage digest md and setting option digest + * flags md_flags. If the 'kat' parameter is not NULL it will + * additionally check the signature matches it: a known answer test + * The string "fail_str" is used for identification purposes in case + * of failure. + */ + +int fips_pkey_signature_test(EVP_PKEY *pkey, + const unsigned char *tbs, int tbslen, + const unsigned char *kat, unsigned int katlen, + const EVP_MD *digest, unsigned int md_flags, + const char *fail_str) + { + int ret = 0; + unsigned char sigtmp[256], *sig = sigtmp; + unsigned int siglen; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + + if ((pkey->type == EVP_PKEY_RSA) + && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp))) + { + sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa)); + if (!sig) + { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (tbslen == -1) + tbslen = strlen((char *)tbs); + + if (md_flags) + EVP_MD_CTX_set_flags(&mctx, md_flags); + + if (!EVP_SignInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_SignUpdate(&mctx, tbs, tbslen)) + goto error; + if (!EVP_SignFinal(&mctx, sig, &siglen, pkey)) + goto error; + + if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) + goto error; + + if (!EVP_VerifyInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_VerifyUpdate(&mctx, tbs, tbslen)) + goto error; + ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey); + + error: + if (sig != sigtmp) + OPENSSL_free(sig); + EVP_MD_CTX_cleanup(&mctx); + if (ret != 1) + { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE); + if (fail_str) + ERR_add_error_data(2, "Type=", fail_str); + return 0; + } + return 1; + } + +/* Generalized symmetric cipher test routine. Encrypt data, verify result + * against known answer, decrypt and compare with original plaintext. + */ + +int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len) + { + unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; + unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; + OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0) + return 0; + EVP_Cipher(ctx, citmp, plaintext, len); + if (memcmp(citmp, ciphertext, len)) + return 0; + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0) + return 0; + EVP_Cipher(ctx, pltmp, citmp, len); + if (memcmp(pltmp, plaintext, len)) + return 0; + return 1; + } + +#if 0 +/* The purpose of this is to ensure the error code exists and the function + * name is to keep the error checking script quiet + */ +void hash_final(void) + { + FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); + } +#endif + + +#endif diff -up openssl-1.0.0k/crypto/fips/fips_des_selftest.c.fips openssl-1.0.0k/crypto/fips/fips_des_selftest.c --- openssl-1.0.0k/crypto/fips/fips_des_selftest.c.fips 2013-02-19 20:12:54.594664857 +0100 +++ openssl-1.0.0k/crypto/fips/fips_des_selftest.c 2013-02-19 20:12:54.594664857 +0100 @@ -0,0 +1,139 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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 +#ifdef OPENSSL_FIPS +#include +#endif +#include +#include + +#ifdef OPENSSL_FIPS + +static struct + { + unsigned char key[16]; + unsigned char plaintext[8]; + unsigned char ciphertext[8]; + } tests2[]= + { + { + { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec, + 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 }, + { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef }, + { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd } + }, + { + { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34, + 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 }, + { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e }, + { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff }, + } + }; + +static struct + { + unsigned char key[24]; + unsigned char plaintext[8]; + unsigned char ciphertext[8]; + } tests3[]= + { + { + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10, + 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 }, + { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c }, + { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b }, + }, + { + { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 }, + { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, + { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 }, + }, + }; + +void FIPS_corrupt_des() + { + tests2[0].plaintext[0]++; + } + +int FIPS_selftest_des() + { + int n, ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + /* Encrypt/decrypt with 2-key 3DES and compare to known answers */ + for(n=0 ; n < 2 ; ++n) + { + if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(), + tests2[n].key, NULL, + tests2[n].plaintext, tests2[n].ciphertext, 8)) + goto err; + } + + /* Encrypt/decrypt with 3DES and compare to known answers */ + for(n=0 ; n < 2 ; ++n) + { + if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(), + tests3[n].key, NULL, + tests3[n].plaintext, tests3[n].ciphertext, 8)) + goto err; + } + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); + + return ret; + } +#endif diff -up openssl-1.0.0k/crypto/fips/fips_dsa_selftest.c.fips openssl-1.0.0k/crypto/fips/fips_dsa_selftest.c --- openssl-1.0.0k/crypto/fips/fips_dsa_selftest.c.fips 2013-02-19 20:12:54.594664857 +0100 +++ openssl-1.0.0k/crypto/fips/fips_dsa_selftest.c 2013-02-19 20:12:54.594664857 +0100 @@ -0,0 +1,186 @@ +/* crypto/dsa/dsatest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#ifdef OPENSSL_FIPS +#include +#endif +#include +#include +#include + +#ifdef OPENSSL_FIPS + +/* seed, out_p, out_q, out_g are taken the NIST test vectors */ + +static unsigned char seed[20] = { + 0x77, 0x8f, 0x40, 0x74, 0x6f, 0x66, 0xbe, 0x33, 0xce, 0xbe, 0x99, 0x34, + 0x4c, 0xfc, 0xf3, 0x28, 0xaa, 0x70, 0x2d, 0x3a + }; + +static unsigned char out_p[] = { + 0xf7, 0x7c, 0x1b, 0x83, 0xd8, 0xe8, 0x5c, 0x7f, 0x85, 0x30, 0x17, 0x57, + 0x21, 0x95, 0xfe, 0x26, 0x04, 0xeb, 0x47, 0x4c, 0x3a, 0x4a, 0x81, 0x4b, + 0x71, 0x2e, 0xed, 0x6e, 0x4f, 0x3d, 0x11, 0x0f, 0x7c, 0xfe, 0x36, 0x43, + 0x51, 0xd9, 0x81, 0x39, 0x17, 0xdf, 0x62, 0xf6, 0x9c, 0x01, 0xa8, 0x69, + 0x71, 0xdd, 0x29, 0x7f, 0x47, 0xe6, 0x65, 0xa6, 0x22, 0xe8, 0x6a, 0x12, + 0x2b, 0xc2, 0x81, 0xff, 0x32, 0x70, 0x2f, 0x9e, 0xca, 0x53, 0x26, 0x47, + 0x0f, 0x59, 0xd7, 0x9e, 0x2c, 0xa5, 0x07, 0xc4, 0x49, 0x52, 0xa3, 0xe4, + 0x6b, 0x04, 0x00, 0x25, 0x49, 0xe2, 0xe6, 0x7f, 0x28, 0x78, 0x97, 0xb8, + 0x3a, 0x32, 0x14, 0x38, 0xa2, 0x51, 0x33, 0x22, 0x44, 0x7e, 0xd7, 0xef, + 0x45, 0xdb, 0x06, 0x4a, 0xd2, 0x82, 0x4a, 0x82, 0x2c, 0xb1, 0xd7, 0xd8, + 0xb6, 0x73, 0x00, 0x4d, 0x94, 0x77, 0x94, 0xef + }; + +static unsigned char out_q[] = { + 0xd4, 0x0a, 0xac, 0x9f, 0xbd, 0x8c, 0x80, 0xc2, 0x38, 0x7e, 0x2e, 0x0c, + 0x52, 0x5c, 0xea, 0x34, 0xa1, 0x83, 0x32, 0xf3 + }; + +static unsigned char out_g[] = { + 0x34, 0x73, 0x8b, 0x57, 0x84, 0x8e, 0x55, 0xbf, 0x57, 0xcc, 0x41, 0xbb, + 0x5e, 0x2b, 0xd5, 0x42, 0xdd, 0x24, 0x22, 0x2a, 0x09, 0xea, 0x26, 0x1e, + 0x17, 0x65, 0xcb, 0x1a, 0xb3, 0x12, 0x44, 0xa3, 0x9e, 0x99, 0xe9, 0x63, + 0xeb, 0x30, 0xb1, 0x78, 0x7b, 0x09, 0x40, 0x30, 0xfa, 0x83, 0xc2, 0x35, + 0xe1, 0xc4, 0x2d, 0x74, 0x1a, 0xb1, 0x83, 0x54, 0xd8, 0x29, 0xf4, 0xcf, + 0x7f, 0x6f, 0x67, 0x1c, 0x36, 0x49, 0xee, 0x6c, 0xa2, 0x3c, 0x2d, 0x6a, + 0xe9, 0xd3, 0x9a, 0xf6, 0x57, 0x78, 0x6f, 0xfd, 0x33, 0xcd, 0x3c, 0xed, + 0xfd, 0xd4, 0x41, 0xe6, 0x5c, 0x8b, 0xe0, 0x68, 0x31, 0x47, 0x47, 0xaf, + 0x12, 0xa7, 0xf9, 0x32, 0x0d, 0x94, 0x15, 0x48, 0xd0, 0x54, 0x85, 0xb2, + 0x04, 0xb5, 0x4d, 0xd4, 0x9d, 0x05, 0x22, 0x25, 0xd9, 0xfd, 0x6c, 0x36, + 0xef, 0xbe, 0x69, 0x6c, 0x55, 0xf4, 0xee, 0xec + }; + +static const unsigned char str1[]="12345678901234567890"; + +void FIPS_corrupt_dsa() + { + ++seed[0]; + } + +int FIPS_selftest_dsa() + { + DSA *dsa; + int counter,i,j, ret = 0; + unsigned int slen; + unsigned char buf[256]; + unsigned long h; + EVP_MD_CTX mctx; + EVP_PKEY *pk = NULL; + + EVP_MD_CTX_init(&mctx); + + dsa = DSA_new(); + + if(dsa == NULL) + goto err; + if(!DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,NULL)) + goto err; + if (counter != 378) + goto err; + if (h != 2) + goto err; + i=BN_bn2bin(dsa->q,buf); + j=sizeof(out_q); + if (i != j || memcmp(buf,out_q,i) != 0) + goto err; + + i=BN_bn2bin(dsa->p,buf); + j=sizeof(out_p); + if (i != j || memcmp(buf,out_p,i) != 0) + goto err; + + i=BN_bn2bin(dsa->g,buf); + j=sizeof(out_g); + if (i != j || memcmp(buf,out_g,i) != 0) + goto err; + DSA_generate_key(dsa); + + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + EVP_PKEY_assign_DSA(pk, dsa); + + if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) + goto err; + if (!EVP_SignUpdate(&mctx, str1, 20)) + goto err; + if (!EVP_SignFinal(&mctx, buf, &slen, pk)) + goto err; + + if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) + goto err; + if (!EVP_VerifyUpdate(&mctx, str1, 20)) + goto err; + if (EVP_VerifyFinal(&mctx, buf, slen, pk) != 1) + goto err; + + ret = 1; + + err: + EVP_MD_CTX_cleanup(&mctx); + if (pk) + EVP_PKEY_free(pk); + else if (dsa) + DSA_free(dsa); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED); + return ret; + } +#endif diff -up openssl-1.0.0k/crypto/fips/fips.h.fips openssl-1.0.0k/crypto/fips/fips.h --- openssl-1.0.0k/crypto/fips/fips.h.fips 2013-02-19 20:12:54.594664857 +0100 +++ openssl-1.0.0k/crypto/fips/fips.h 2013-02-19 20:12:54.594664857 +0100 @@ -0,0 +1,163 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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 + +#ifndef OPENSSL_FIPS +#error FIPS is disabled. +#endif + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +struct dsa_st; +struct evp_pkey_st; +struct env_md_st; +struct evp_cipher_st; +struct evp_cipher_ctx_st; + +int FIPS_mode_set(int onoff); +int FIPS_mode(void); +const void *FIPS_rand_check(void); +int FIPS_selftest_failed(void); +void FIPS_selftest_check(void); +void FIPS_corrupt_sha1(void); +int FIPS_selftest_sha1(void); +void FIPS_corrupt_aes(void); +int FIPS_selftest_aes(void); +void FIPS_corrupt_des(void); +int FIPS_selftest_des(void); +void FIPS_corrupt_rsa(void); +void FIPS_corrupt_rsa_keygen(void); +int FIPS_selftest_rsa(void); +void FIPS_corrupt_dsa(void); +void FIPS_corrupt_dsa_keygen(void); +int FIPS_selftest_dsa(void); +void FIPS_corrupt_rng(void); +void FIPS_rng_stick(void); +int FIPS_selftest_rng(void); +int FIPS_selftest_hmac(void); + +int fips_pkey_signature_test(struct evp_pkey_st *pkey, + const unsigned char *tbs, int tbslen, + const unsigned char *kat, unsigned int katlen, + const struct env_md_st *digest, unsigned int md_flags, + const char *fail_str); + +int fips_cipher_test(struct evp_cipher_ctx_st *ctx, + const struct evp_cipher_st *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len); + +/* 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. + */ +void ERR_load_FIPS_strings(void); + +/* Error codes for the FIPS functions. */ + +/* Function codes. */ +#define FIPS_F_DH_BUILTIN_GENPARAMS 100 +#define FIPS_F_DSA_BUILTIN_PARAMGEN 101 +#define FIPS_F_DSA_DO_SIGN 102 +#define FIPS_F_DSA_DO_VERIFY 103 +#define FIPS_F_EVP_CIPHERINIT_EX 124 +#define FIPS_F_EVP_DIGESTINIT_EX 125 +#define FIPS_F_FIPS_CHECK_DSA 104 +#define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT 105 +#define FIPS_F_FIPS_CHECK_RSA 106 +#define FIPS_F_FIPS_DSA_CHECK 107 +#define FIPS_F_FIPS_MODE_SET 108 +#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109 +#define FIPS_F_FIPS_SELFTEST_AES 110 +#define FIPS_F_FIPS_SELFTEST_DES 111 +#define FIPS_F_FIPS_SELFTEST_DSA 112 +#define FIPS_F_FIPS_SELFTEST_HMAC 113 +#define FIPS_F_FIPS_SELFTEST_RNG 114 +#define FIPS_F_FIPS_SELFTEST_SHA1 115 +#define FIPS_F_HASH_FINAL 123 +#define FIPS_F_RSA_BUILTIN_KEYGEN 116 +#define FIPS_F_RSA_EAY_PRIVATE_DECRYPT 117 +#define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT 118 +#define FIPS_F_RSA_EAY_PUBLIC_DECRYPT 119 +#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT 120 +#define FIPS_F_RSA_X931_GENERATE_KEY_EX 121 +#define FIPS_F_SSLEAY_RAND_BYTES 122 + +/* Reason codes. */ +#define FIPS_R_CANNOT_READ_EXE 103 +#define FIPS_R_CANNOT_READ_EXE_DIGEST 104 +#define FIPS_R_CONTRADICTING_EVIDENCE 114 +#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH 105 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH 110 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112 +#define FIPS_R_FIPS_MODE_ALREADY_SET 102 +#define FIPS_R_FIPS_SELFTEST_FAILED 106 +#define FIPS_R_INVALID_KEY_LENGTH 109 +#define FIPS_R_KEY_TOO_SHORT 108 +#define FIPS_R_NON_FIPS_METHOD 100 +#define FIPS_R_PAIRWISE_TEST_FAILED 107 +#define FIPS_R_RSA_DECRYPT_ERROR 115 +#define FIPS_R_RSA_ENCRYPT_ERROR 116 +#define FIPS_R_SELFTEST_FAILED 101 +#define FIPS_R_TEST_FAILURE 117 +#define FIPS_R_UNSUPPORTED_PLATFORM 113 + +#ifdef __cplusplus +} +#endif +#endif diff -up openssl-1.0.0k/crypto/fips/fips_hmac_selftest.c.fips openssl-1.0.0k/crypto/fips/fips_hmac_selftest.c --- openssl-1.0.0k/crypto/fips/fips_hmac_selftest.c.fips 2013-02-19 20:12:54.594664857 +0100 +++ openssl-1.0.0k/crypto/fips/fips_hmac_selftest.c 2013-02-19 20:12:54.594664857 +0100 @@ -0,0 +1,137 @@ +/* ==================================================================== + * Copyright (c) 2005 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 + * 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 +#ifdef OPENSSL_FIPS +#include +#endif +#include + +#ifdef OPENSSL_FIPS +typedef struct { + const EVP_MD *(*alg)(void); + const char *key, *iv; + unsigned char kaval[EVP_MAX_MD_SIZE]; +} HMAC_KAT; + +static const HMAC_KAT vector[] = { + { EVP_sha1, + /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */ + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x09,0x22,0xd3,0x40,0x5f,0xaa,0x3d,0x19, + 0x4f,0x82,0xa4,0x58,0x30,0x73,0x7d,0x5c, + 0xc6,0xc7,0x5d,0x24 } + }, + { EVP_sha224, + /* just keep extending the above... */ + "0123456789:;<=>?@ABC", + "Sample #2", + { 0xdd,0xef,0x0a,0x40,0xcb,0x7d,0x50,0xfb, + 0x6e,0xe6,0xce,0xa1,0x20,0xba,0x26,0xaa, + 0x08,0xf3,0x07,0x75,0x87,0xb8,0xad,0x1b, + 0x8c,0x8d,0x12,0xc7 } + }, + { EVP_sha256, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0xb8,0xf2,0x0d,0xb5,0x41,0xea,0x43,0x09, + 0xca,0x4e,0xa9,0x38,0x0c,0xd0,0xe8,0x34, + 0xf7,0x1f,0xbe,0x91,0x74,0xa2,0x61,0x38, + 0x0d,0xc1,0x7e,0xae,0x6a,0x34,0x51,0xd9 } + }, + { EVP_sha384, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x08,0xbc,0xb0,0xda,0x49,0x1e,0x87,0xad, + 0x9a,0x1d,0x6a,0xce,0x23,0xc5,0x0b,0xf6, + 0xb7,0x18,0x06,0xa5,0x77,0xcd,0x49,0x04, + 0x89,0xf1,0xe6,0x23,0x44,0x51,0x51,0x9f, + 0x85,0x56,0x80,0x79,0x0c,0xbd,0x4d,0x50, + 0xa4,0x5f,0x29,0xe3,0x93,0xf0,0xe8,0x7f } + }, + { EVP_sha512, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x80,0x9d,0x44,0x05,0x7c,0x5b,0x95,0x41, + 0x05,0xbd,0x04,0x13,0x16,0xdb,0x0f,0xac, + 0x44,0xd5,0xa4,0xd5,0xd0,0x89,0x2b,0xd0, + 0x4e,0x86,0x64,0x12,0xc0,0x90,0x77,0x68, + 0xf1,0x87,0xb7,0x7c,0x4f,0xae,0x2c,0x2f, + 0x21,0xa5,0xb5,0x65,0x9a,0x4f,0x4b,0xa7, + 0x47,0x02,0xa3,0xde,0x9b,0x51,0xf1,0x45, + 0xbd,0x4f,0x25,0x27,0x42,0x98,0x99,0x05 } + }, +}; + +int FIPS_selftest_hmac() + { + int n; + unsigned int outlen; + unsigned char out[EVP_MAX_MD_SIZE]; + const EVP_MD *md; + const HMAC_KAT *t; + + for(n=0,t=vector; nalg)(); + HMAC(md,t->key,strlen(t->key), + (const unsigned char *)t->iv,strlen(t->iv), + out,&outlen); + + if(memcmp(out,t->kaval,outlen)) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED); + return 0; + } + } + return 1; + } +#endif diff -up openssl-1.0.0k/crypto/fips/fips_rand.c.fips openssl-1.0.0k/crypto/fips/fips_rand.c --- openssl-1.0.0k/crypto/fips/fips_rand.c.fips 2013-02-19 20:12:54.594664857 +0100 +++ openssl-1.0.0k/crypto/fips/fips_rand.c 2013-02-19 20:12:54.594664857 +0100 @@ -0,0 +1,412 @@ +/* ==================================================================== + * Copyright (c) 2007 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 + * 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. + * + */ + +/* + * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4. + */ + +#include "e_os.h" + +/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't + be defined and gettimeofday() won't be declared with strict compilers + like DEC C in ANSI C mode. */ +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED 1 +#endif + +#include +#include +#include +#include +#ifndef OPENSSL_SYS_WIN32 +#include +#endif +#include +#ifndef OPENSSL_SYS_WIN32 +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +#endif +#include +#ifdef OPENSSL_FIPS +#include +#endif +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +void *OPENSSL_stderr(void); + +#define AES_BLOCK_LENGTH 16 + + +/* AES FIPS PRNG implementation */ + +typedef struct + { + int seeded; + int keyed; + int test_mode; + int second; + int error; + unsigned long counter; + AES_KEY ks; + int vpos; + /* Temporary storage for key if it equals seed length */ + unsigned char tmp_key[AES_BLOCK_LENGTH]; + unsigned char V[AES_BLOCK_LENGTH]; + unsigned char DT[AES_BLOCK_LENGTH]; + unsigned char last[AES_BLOCK_LENGTH]; + } FIPS_PRNG_CTX; + +static FIPS_PRNG_CTX sctx; + +static int fips_prng_fail = 0; + +void FIPS_rng_stick(void) + { + fips_prng_fail = 1; + } + +void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx) + { + ctx->seeded = 0; + ctx->keyed = 0; + ctx->test_mode = 0; + ctx->counter = 0; + ctx->second = 0; + ctx->error = 0; + ctx->vpos = 0; + OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH); + OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY)); + } + + +static int fips_set_prng_key(FIPS_PRNG_CTX *ctx, + const unsigned char *key, FIPS_RAND_SIZE_T keylen) + { + FIPS_selftest_check(); + if (keylen != 16 && keylen != 24 && keylen != 32) + { + /* error: invalid key size */ + return 0; + } + AES_set_encrypt_key(key, keylen << 3, &ctx->ks); + if (keylen == 16) + { + memcpy(ctx->tmp_key, key, 16); + ctx->keyed = 2; + } + else + ctx->keyed = 1; + ctx->seeded = 0; + ctx->second = 0; + return 1; + } + +static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx, + const unsigned char *seed, FIPS_RAND_SIZE_T seedlen) + { + int i; + if (!ctx->keyed) + return 0; + /* In test mode seed is just supplied data */ + if (ctx->test_mode) + { + if (seedlen != AES_BLOCK_LENGTH) + return 0; + memcpy(ctx->V, seed, AES_BLOCK_LENGTH); + ctx->seeded = 1; + return 1; + } + /* Outside test mode XOR supplied data with existing seed */ + for (i = 0; i < seedlen; i++) + { + ctx->V[ctx->vpos++] ^= seed[i]; + if (ctx->vpos == AES_BLOCK_LENGTH) + { + ctx->vpos = 0; + /* Special case if first seed and key length equals + * block size check key and seed do not match. + */ + if (ctx->keyed == 2) + { + if (!memcmp(ctx->tmp_key, ctx->V, 16)) + { + RANDerr(RAND_F_FIPS_SET_PRNG_SEED, + RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY); + return 0; + } + OPENSSL_cleanse(ctx->tmp_key, 16); + ctx->keyed = 1; + } + ctx->seeded = 1; + } + } + return 1; + } + +int fips_set_test_mode(FIPS_PRNG_CTX *ctx) + { + if (ctx->keyed) + { + RANDerr(RAND_F_FIPS_SET_TEST_MODE,RAND_R_PRNG_KEYED); + return 0; + } + ctx->test_mode = 1; + return 1; + } + +int FIPS_rand_test_mode(void) + { + return fips_set_test_mode(&sctx); + } + +int FIPS_rand_set_dt(unsigned char *dt) + { + if (!sctx.test_mode) + { + RANDerr(RAND_F_FIPS_RAND_SET_DT,RAND_R_NOT_IN_TEST_MODE); + return 0; + } + memcpy(sctx.DT, dt, AES_BLOCK_LENGTH); + return 1; + } + +static void fips_get_dt(FIPS_PRNG_CTX *ctx) + { +#ifdef OPENSSL_SYS_WIN32 + FILETIME ft; +#else + struct timeval tv; +#endif + unsigned char *buf = ctx->DT; + +#ifndef GETPID_IS_MEANINGLESS + unsigned long pid; +#endif + +#ifdef OPENSSL_SYS_WIN32 + GetSystemTimeAsFileTime(&ft); + buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff); + buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff); + buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff); + buf[3] = (unsigned char) ((ft.dwHighDateTime >> 24) & 0xff); + buf[4] = (unsigned char) (ft.dwLowDateTime & 0xff); + buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff); + buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff); + buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff); +#else + gettimeofday(&tv,NULL); + buf[0] = (unsigned char) (tv.tv_sec & 0xff); + buf[1] = (unsigned char) ((tv.tv_sec >> 8) & 0xff); + buf[2] = (unsigned char) ((tv.tv_sec >> 16) & 0xff); + buf[3] = (unsigned char) ((tv.tv_sec >> 24) & 0xff); + buf[4] = (unsigned char) (tv.tv_usec & 0xff); + buf[5] = (unsigned char) ((tv.tv_usec >> 8) & 0xff); + buf[6] = (unsigned char) ((tv.tv_usec >> 16) & 0xff); + buf[7] = (unsigned char) ((tv.tv_usec >> 24) & 0xff); +#endif + buf[8] = (unsigned char) (ctx->counter & 0xff); + buf[9] = (unsigned char) ((ctx->counter >> 8) & 0xff); + buf[10] = (unsigned char) ((ctx->counter >> 16) & 0xff); + buf[11] = (unsigned char) ((ctx->counter >> 24) & 0xff); + + ctx->counter++; + + +#ifndef GETPID_IS_MEANINGLESS + pid=(unsigned long)getpid(); + buf[12] = (unsigned char) (pid & 0xff); + buf[13] = (unsigned char) ((pid >> 8) & 0xff); + buf[14] = (unsigned char) ((pid >> 16) & 0xff); + buf[15] = (unsigned char) ((pid >> 24) & 0xff); +#endif + } + +static int fips_rand(FIPS_PRNG_CTX *ctx, + unsigned char *out, FIPS_RAND_SIZE_T outlen) + { + unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH]; + unsigned char tmp[AES_BLOCK_LENGTH]; + int i; + if (ctx->error) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR); + return 0; + } + if (!ctx->keyed) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_NO_KEY_SET); + return 0; + } + if (!ctx->seeded) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_NOT_SEEDED); + return 0; + } + for (;;) + { + if (!ctx->test_mode) + fips_get_dt(ctx); + AES_encrypt(ctx->DT, I, &ctx->ks); + for (i = 0; i < AES_BLOCK_LENGTH; i++) + tmp[i] = I[i] ^ ctx->V[i]; + AES_encrypt(tmp, R, &ctx->ks); + for (i = 0; i < AES_BLOCK_LENGTH; i++) + tmp[i] = R[i] ^ I[i]; + AES_encrypt(tmp, ctx->V, &ctx->ks); + /* Continuous PRNG test */ + if (ctx->second) + { + if (fips_prng_fail) + memcpy(ctx->last, R, AES_BLOCK_LENGTH); + if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH)) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_STUCK); + ctx->error = 1; + fips_set_selftest_fail(); + return 0; + } + } + memcpy(ctx->last, R, AES_BLOCK_LENGTH); + if (!ctx->second) + { + ctx->second = 1; + if (!ctx->test_mode) + continue; + } + + if (outlen <= AES_BLOCK_LENGTH) + { + memcpy(out, R, outlen); + break; + } + + memcpy(out, R, AES_BLOCK_LENGTH); + out += AES_BLOCK_LENGTH; + outlen -= AES_BLOCK_LENGTH; + } + return 1; + } + + +int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_set_prng_key(&sctx, key, keylen); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +int FIPS_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_set_prng_seed(&sctx, seed, seedlen); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + + +int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T count) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_rand(&sctx, out, count); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +int FIPS_rand_status(void) + { + int ret; + CRYPTO_r_lock(CRYPTO_LOCK_RAND); + ret = sctx.seeded; + CRYPTO_r_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +void FIPS_rand_reset(void) + { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + fips_rand_prng_reset(&sctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + +static void fips_do_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen) + { + FIPS_rand_seed(seed, seedlen); + } + +static void fips_do_rand_add(const void *seed, FIPS_RAND_SIZE_T seedlen, + double add_entropy) + { + FIPS_rand_seed(seed, seedlen); + } + +static const RAND_METHOD rand_fips_meth= + { + fips_do_rand_seed, + FIPS_rand_bytes, + FIPS_rand_reset, + fips_do_rand_add, + FIPS_rand_bytes, + FIPS_rand_status + }; + +const RAND_METHOD *FIPS_rand_method(void) +{ + return &rand_fips_meth; +} + +#endif diff -up openssl-1.0.0k/crypto/fips/fips_rand.h.fips openssl-1.0.0k/crypto/fips/fips_rand.h --- openssl-1.0.0k/crypto/fips/fips_rand.h.fips 2013-02-19 20:12:54.595664876 +0100 +++ openssl-1.0.0k/crypto/fips/fips_rand.h 2013-02-19 20:12:54.595664876 +0100 @@ -0,0 +1,77 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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. + * + */ + +#ifndef HEADER_FIPS_RAND_H +#define HEADER_FIPS_RAND_H + +#include "des.h" + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen); +int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num); +int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen); + +int FIPS_rand_test_mode(void); +void FIPS_rand_reset(void); +int FIPS_rand_set_dt(unsigned char *dt); + +int FIPS_rand_status(void); + +const RAND_METHOD *FIPS_rand_method(void); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff -up openssl-1.0.0k/crypto/fips/fips_rand_selftest.c.fips openssl-1.0.0k/crypto/fips/fips_rand_selftest.c --- openssl-1.0.0k/crypto/fips/fips_rand_selftest.c.fips 2013-02-19 20:12:54.595664876 +0100 +++ openssl-1.0.0k/crypto/fips/fips_rand_selftest.c 2013-02-19 20:12:54.595664876 +0100 @@ -0,0 +1,373 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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 +#ifdef OPENSSL_FIPS +#include +#endif +#include +#include + +#ifdef OPENSSL_FIPS + + + +typedef struct + { + unsigned char DT[16]; + unsigned char V[16]; + unsigned char R[16]; + } AES_PRNG_TV; + +/* The following test vectors are taken directly from the RGNVS spec */ + +static unsigned char aes_128_key[16] = + {0xf3,0xb1,0x66,0x6d,0x13,0x60,0x72,0x42, + 0xed,0x06,0x1c,0xab,0xb8,0xd4,0x62,0x02}; + +static AES_PRNG_TV aes_128_tv[] = { + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xf9}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x59,0x53,0x1e,0xd1,0x3b,0xb0,0xc0,0x55, + 0x84,0x79,0x66,0x85,0xc1,0x2f,0x76,0x41} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfa}, + /* V */ + {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x7c,0x22,0x2c,0xf4,0xca,0x8f,0xa2,0x4c, + 0x1c,0x9c,0xb6,0x41,0xa9,0xf3,0x22,0x0d} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfb}, + /* V */ + {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x8a,0xaa,0x00,0x39,0x66,0x67,0x5b,0xe5, + 0x29,0x14,0x28,0x81,0xa9,0x4d,0x4e,0xc7} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfc}, + /* V */ + {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x88,0xdd,0xa4,0x56,0x30,0x24,0x23,0xe5, + 0xf6,0x9d,0xa5,0x7e,0x7b,0x95,0xc7,0x3a} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfd}, + /* V */ + {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x05,0x25,0x92,0x46,0x61,0x79,0xd2,0xcb, + 0x78,0xc4,0x0b,0x14,0x0a,0x5a,0x9a,0xc8} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x77}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe}, + /* R */ + {0x0d,0xd5,0xa0,0x36,0x7a,0x59,0x26,0xbc, + 0x48,0xd9,0x38,0xbf,0xf0,0x85,0x8f,0xea} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x78}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + /* R */ + {0xae,0x53,0x87,0xee,0x8c,0xd9,0x12,0xf5, + 0x73,0x53,0xae,0x03,0xf9,0xd5,0x13,0x33} + }, +}; + +static unsigned char aes_192_key[24] = + {0x15,0xd8,0x78,0x0d,0x62,0xd3,0x25,0x6e, + 0x44,0x64,0x10,0x13,0x60,0x2b,0xa9,0xbc, + 0x4a,0xfb,0xca,0xeb,0x4c,0x8b,0x99,0x3b}; + +static AES_PRNG_TV aes_192_tv[] = { + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4b}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x17,0x07,0xd5,0x28,0x19,0x79,0x1e,0xef, + 0xa5,0x0c,0xbf,0x25,0xe5,0x56,0xb4,0x93} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4c}, + /* V */ + {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x92,0x8d,0xbe,0x07,0xdd,0xc7,0x58,0xc0, + 0x6f,0x35,0x41,0x9b,0x17,0xc9,0xbd,0x9b} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4d}, + /* V */ + {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0xd5,0xde,0xf4,0x50,0xf3,0xb7,0x10,0x4e, + 0xb8,0xc6,0xf8,0xcf,0xe2,0xb1,0xca,0xa2} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4e}, + /* V */ + {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0xce,0x29,0x08,0x43,0xfc,0x34,0x41,0xe7, + 0x47,0x8f,0xb3,0x66,0x2b,0x46,0xb1,0xbb} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4f}, + /* V */ + {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0xb3,0x26,0x0f,0xf5,0xd6,0xca,0xa8,0xbf, + 0x89,0xb8,0x5e,0x2f,0x22,0x56,0x92,0x2f} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xc9}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe}, + /* R */ + {0x05,0xeb,0x18,0x52,0x34,0x43,0x00,0x43, + 0x6e,0x5a,0xa5,0xfe,0x7b,0x32,0xc4,0x2d} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xca}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + /* R */ + {0x15,0x3c,0xe8,0xd1,0x04,0xc7,0xad,0x50, + 0x0b,0xf0,0x07,0x16,0xe7,0x56,0x7a,0xea} + }, +}; + +static unsigned char aes_256_key[32] = + {0x6d,0x14,0x06,0x6c,0xb6,0xd8,0x21,0x2d, + 0x82,0x8d,0xfa,0xf2,0x7a,0x03,0xb7,0x9f, + 0x0c,0xc7,0x3e,0xcd,0x76,0xeb,0xee,0xb5, + 0x21,0x05,0x8c,0x4f,0x31,0x7a,0x80,0xbb}; + +static AES_PRNG_TV aes_256_tv[] = { + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x88}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x35,0xc7,0xef,0xa7,0x78,0x4d,0x29,0xbc, + 0x82,0x79,0x99,0xfb,0xd0,0xb3,0x3b,0x72} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x89}, + /* V */ + {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x6c,0xf4,0x42,0x5d,0xc7,0x04,0x1a,0x41, + 0x28,0x2a,0x78,0xa9,0xb0,0x12,0xc4,0x95} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8a}, + /* V */ + {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x16,0x90,0xa4,0xff,0x7b,0x7e,0xb9,0x30, + 0xdb,0x67,0x4b,0xac,0x2d,0xe1,0xd1,0x75} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8b}, + /* V */ + {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x14,0x6f,0xf5,0x95,0xa1,0x46,0x65,0x30, + 0xbc,0x57,0xe2,0x4a,0xf7,0x45,0x62,0x05} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8c}, + /* V */ + {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x96,0xe2,0xb4,0x1e,0x66,0x5e,0x0f,0xa4, + 0xc5,0xcd,0xa2,0x07,0xcc,0xb7,0x94,0x40} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x06}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe}, + /* R */ + {0x61,0xce,0x1d,0x6a,0x48,0x75,0x97,0x28, + 0x4b,0x41,0xde,0x18,0x44,0x4f,0x56,0xec} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x07}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + /* R */ + {0x52,0x89,0x59,0x79,0x2d,0xaa,0x28,0xb3, + 0xb0,0x8a,0x3e,0x70,0xfa,0x71,0x59,0x84} + }, +}; + + +void FIPS_corrupt_rng() + { + aes_192_tv[0].V[0]++; + } + +#define fips_rand_test(key, tv) \ + do_rand_test(key, sizeof key, tv, sizeof(tv)/sizeof(AES_PRNG_TV)) + +static int do_rand_test(unsigned char *key, int keylen, + AES_PRNG_TV *tv, int ntv) + { + unsigned char R[16]; + int i; + if (!FIPS_rand_set_key(key, keylen)) + return 0; + for (i = 0; i < ntv; i++) + { + FIPS_rand_seed(tv[i].V, 16); + FIPS_rand_set_dt(tv[i].DT); + FIPS_rand_bytes(R, 16); + if (memcmp(R, tv[i].R, 16)) + return 0; + } + return 1; + } + + +int FIPS_selftest_rng() + { + FIPS_rand_reset(); + if (!FIPS_rand_test_mode()) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED); + return 0; + } + if (!fips_rand_test(aes_128_key,aes_128_tv) + || !fips_rand_test(aes_192_key, aes_192_tv) + || !fips_rand_test(aes_256_key, aes_256_tv)) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED); + return 0; + } + FIPS_rand_reset(); + return 1; + } + +#endif diff -up openssl-1.0.0k/crypto/fips/fips_randtest.c.fips openssl-1.0.0k/crypto/fips/fips_randtest.c --- openssl-1.0.0k/crypto/fips/fips_randtest.c.fips 2013-02-19 20:12:54.595664876 +0100 +++ openssl-1.0.0k/crypto/fips/fips_randtest.c 2013-02-19 20:12:54.595664876 +0100 @@ -0,0 +1,248 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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 + +#include "e_os.h" + +#ifndef OPENSSL_FIPS +int main(int argc, char *argv[]) +{ + printf("No FIPS RAND support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +typedef struct + { + unsigned char DT[16]; + unsigned char V[16]; + unsigned char R[16]; + } AES_PRNG_MCT; + +static unsigned char aes_128_mct_key[16] = + {0x9f,0x5b,0x51,0x20,0x0b,0xf3,0x34,0xb5, + 0xd8,0x2b,0xe8,0xc3,0x72,0x55,0xc8,0x48}; + +static AES_PRNG_MCT aes_128_mct_tv = { + /* DT */ + {0x63,0x76,0xbb,0xe5,0x29,0x02,0xba,0x3b, + 0x67,0xc9,0x25,0xfa,0x70,0x1f,0x11,0xac}, + /* V */ + {0x57,0x2c,0x8e,0x76,0x87,0x26,0x47,0x97, + 0x7e,0x74,0xfb,0xdd,0xc4,0x95,0x01,0xd1}, + /* R */ + {0x48,0xe9,0xbd,0x0d,0x06,0xee,0x18,0xfb, + 0xe4,0x57,0x90,0xd5,0xc3,0xfc,0x9b,0x73} +}; + +static unsigned char aes_192_mct_key[24] = + {0xb7,0x6c,0x34,0xd1,0x09,0x67,0xab,0x73, + 0x4d,0x5a,0xd5,0x34,0x98,0x16,0x0b,0x91, + 0xbc,0x35,0x51,0x16,0x6b,0xae,0x93,0x8a}; + +static AES_PRNG_MCT aes_192_mct_tv = { + /* DT */ + {0x84,0xce,0x22,0x7d,0x91,0x5a,0xa3,0xc9, + 0x84,0x3c,0x0a,0xb3,0xa9,0x63,0x15,0x52}, + /* V */ + {0xb6,0xaf,0xe6,0x8f,0x99,0x9e,0x90,0x64, + 0xdd,0xc7,0x7a,0xc1,0xbb,0x90,0x3a,0x6d}, + /* R */ + {0xfc,0x85,0x60,0x9a,0x29,0x6f,0xef,0x21, + 0xdd,0x86,0x20,0x32,0x8a,0x29,0x6f,0x47} +}; + +static unsigned char aes_256_mct_key[32] = + {0x9b,0x05,0xc8,0x68,0xff,0x47,0xf8,0x3a, + 0xa6,0x3a,0xa8,0xcb,0x4e,0x71,0xb2,0xe0, + 0xb8,0x7e,0xf1,0x37,0xb6,0xb4,0xf6,0x6d, + 0x86,0x32,0xfc,0x1f,0x5e,0x1d,0x1e,0x50}; + +static AES_PRNG_MCT aes_256_mct_tv = { + /* DT */ + {0x31,0x6e,0x35,0x9a,0xb1,0x44,0xf0,0xee, + 0x62,0x6d,0x04,0x46,0xe0,0xa3,0x92,0x4c}, + /* V */ + {0x4f,0xcd,0xc1,0x87,0x82,0x1f,0x4d,0xa1, + 0x3e,0x0e,0x56,0x44,0x59,0xe8,0x83,0xca}, + /* R */ + {0xc8,0x87,0xc2,0x61,0x5b,0xd0,0xb9,0xe1, + 0xe7,0xf3,0x8b,0xd7,0x5b,0xd5,0xf1,0x8d} +}; + +static void dump(const unsigned char *b,int n) + { + while(n-- > 0) + { + printf(" %02x",*b++); + } + } + +static void compare(const unsigned char *result,const unsigned char *expected, + int n) + { + int i; + + for(i=0 ; i < n ; ++i) + if(result[i] != expected[i]) + { + puts("Random test failed, got:"); + dump(result,n); + puts("\n expected:"); + dump(expected,n); + putchar('\n'); + EXIT(1); + } + } + + +static void run_test(unsigned char *key, int keylen, AES_PRNG_MCT *tv) + { + unsigned char buf[16], dt[16]; + int i, j; + FIPS_rand_reset(); + FIPS_rand_test_mode(); + FIPS_rand_set_key(key, keylen); + FIPS_rand_seed(tv->V, 16); + memcpy(dt, tv->DT, 16); + for (i = 0; i < 10000; i++) + { + FIPS_rand_set_dt(dt); + FIPS_rand_bytes(buf, 16); + /* Increment DT */ + for (j = 15; j >= 0; j--) + { + dt[j]++; + if (dt[j]) + break; + } + } + + compare(buf,tv->R, 16); + } + +int main() + { + run_test(aes_128_mct_key, 16, &aes_128_mct_tv); + printf("FIPS PRNG test 1 done\n"); + run_test(aes_192_mct_key, 24, &aes_192_mct_tv); + printf("FIPS PRNG test 2 done\n"); + run_test(aes_256_mct_key, 32, &aes_256_mct_tv); + printf("FIPS PRNG test 3 done\n"); + return 0; + } + +#endif diff -up openssl-1.0.0k/crypto/fips/fips_rsa_selftest.c.fips openssl-1.0.0k/crypto/fips/fips_rsa_selftest.c --- openssl-1.0.0k/crypto/fips/fips_rsa_selftest.c.fips 2013-02-19 20:12:54.595664876 +0100 +++ openssl-1.0.0k/crypto/fips/fips_rsa_selftest.c 2013-02-19 20:12:54.595664876 +0100 @@ -0,0 +1,441 @@ +/* ==================================================================== + * Copyright (c) 2003-2007 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 + * 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 +#ifdef OPENSSL_FIPS +#include +#endif +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +static unsigned char n[] = +"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71" +"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5" +"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD" +"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80" +"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25" +"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39" +"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68" +"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD" +"\xCB"; + + +static int setrsakey(RSA *key) + { + static const unsigned char e[] = "\x11"; + + static const unsigned char d[] = +"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD" +"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41" +"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69" +"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA" +"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94" +"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A" +"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94" +"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3" +"\xC1"; + + static const unsigned char p[] = +"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60" +"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6" +"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A" +"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65" +"\x99"; + + static const unsigned char q[] = +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" +"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15" +"\x03"; + + static const unsigned char dmp1[] = +"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A" +"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E" +"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E" +"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81"; + + static const unsigned char dmq1[] = +"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9" +"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7" +"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D" +"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D"; + + static const unsigned char iqmp[] = +"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23" +"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11" +"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E" +"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39" +"\xF7"; + + key->n = BN_bin2bn(n, sizeof(n)-1, key->n); + key->e = BN_bin2bn(e, sizeof(e)-1, key->e); + key->d = BN_bin2bn(d, sizeof(d)-1, key->d); + key->p = BN_bin2bn(p, sizeof(p)-1, key->p); + key->q = BN_bin2bn(q, sizeof(q)-1, key->q); + key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); + key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); + key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); + return 1; + } + +void FIPS_corrupt_rsa() + { + n[0]++; + } + +/* Known Answer Test (KAT) data for the above RSA private key signing + * kat_tbs. + */ + +static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT"; + +static const unsigned char kat_RSA_PSS_SHA1[] = { + 0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F, + 0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB, + 0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3, + 0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C, + 0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7, + 0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5, + 0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45, + 0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31, + 0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8, + 0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84, + 0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9 +}; + +static const unsigned char kat_RSA_PSS_SHA224[] = { + 0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7, + 0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA, + 0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57, + 0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89, + 0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE, + 0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22, + 0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5, + 0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49, + 0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D, + 0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00, + 0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0 +}; + +static const unsigned char kat_RSA_PSS_SHA256[] = { + 0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89, + 0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F, + 0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28, + 0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E, + 0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05, + 0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA, + 0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6, + 0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F, + 0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D, + 0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6, + 0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C +}; + +static const unsigned char kat_RSA_PSS_SHA384[] = { + 0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2, + 0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E, + 0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD, + 0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F, + 0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C, + 0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB, + 0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F, + 0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89, + 0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F, + 0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55, + 0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1 +}; + +static const unsigned char kat_RSA_PSS_SHA512[] = { + 0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C, + 0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A, + 0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD, + 0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39, + 0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7, + 0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61, + 0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13, + 0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63, + 0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE, + 0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88, + 0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B +}; + +static const unsigned char kat_RSA_SHA1[] = { + 0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, + 0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, + 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF, + 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8, + 0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, + 0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, + 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E, + 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F, + 0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, + 0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, + 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4 +}; + +static const unsigned char kat_RSA_SHA224[] = { + 0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9, + 0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D, + 0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89, + 0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD, + 0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5, + 0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC, + 0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B, + 0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2, + 0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35, + 0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC, + 0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D +}; + +static const unsigned char kat_RSA_SHA256[] = { + 0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23, + 0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23, + 0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35, + 0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E, + 0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18, + 0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30, + 0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A, + 0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38, + 0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA, + 0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90, + 0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A +}; + +static const unsigned char kat_RSA_SHA384[] = { + 0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F, + 0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7, + 0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C, + 0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55, + 0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF, + 0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2, + 0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C, + 0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD, + 0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1, + 0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04, + 0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF +}; + +static const unsigned char kat_RSA_SHA512[] = { + 0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF, + 0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A, + 0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1, + 0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8, + 0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5, + 0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B, + 0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6, + 0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05, + 0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D, + 0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91, + 0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84 +}; + +static const unsigned char kat_RSA_X931_SHA1[] = { + 0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF, + 0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75, + 0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC, + 0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97, + 0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6, + 0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19, + 0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7, + 0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99, + 0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76, + 0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67, + 0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49 +}; + +static const unsigned char kat_RSA_X931_SHA256[] = { + 0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89, + 0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD, + 0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF, + 0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B, + 0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B, + 0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98, + 0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC, + 0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C, + 0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD, + 0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC, + 0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80 +}; + +static const unsigned char kat_RSA_X931_SHA384[] = { + 0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B, + 0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB, + 0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3, + 0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6, + 0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31, + 0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1, + 0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79, + 0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF, + 0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35, + 0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D, + 0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28 +}; + +static const unsigned char kat_RSA_X931_SHA512[] = { + 0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63, + 0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC, + 0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7, + 0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28, + 0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5, + 0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF, + 0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0, + 0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09, + 0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C, + 0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B, + 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3 +}; + + +int FIPS_selftest_rsa() + { + int ret = 0; + RSA *key; + EVP_PKEY *pk = NULL; + + if ((key=RSA_new()) == NULL) + goto err; + setrsakey(key); + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_assign_RSA(pk, key); + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA1, sizeof(kat_RSA_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA1 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA224, sizeof(kat_RSA_SHA224), + EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA224 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA256, sizeof(kat_RSA_SHA256), + EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA256 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA384, sizeof(kat_RSA_SHA384), + EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA384 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA512, sizeof(kat_RSA_SHA512), + EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA512 PKCS#1")) + goto err; + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA1 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224), + EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA224 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256), + EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA256 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384), + EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA384 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512), + EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA512 PSS")) + goto err; + + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA1 X931")) + goto err; + /* NB: SHA224 not supported in X9.31 */ + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256), + EVP_sha256(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA256 X931")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384), + EVP_sha384(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA384 X931")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512), + EVP_sha512(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA512 X931")) + goto err; + + + ret = 1; + + err: + if (pk) + EVP_PKEY_free(pk); + else if (key) + RSA_free(key); + return ret; + } + +#endif /* def OPENSSL_FIPS */ diff -up openssl-1.0.0k/crypto/fips/fips_rsa_x931g.c.fips openssl-1.0.0k/crypto/fips/fips_rsa_x931g.c --- openssl-1.0.0k/crypto/fips/fips_rsa_x931g.c.fips 2013-02-19 20:12:54.596664895 +0100 +++ openssl-1.0.0k/crypto/fips/fips_rsa_x931g.c 2013-02-19 20:12:54.596664895 +0100 @@ -0,0 +1,281 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS 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 AUTHOR OR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include +#ifdef OPENSSL_FIPS +#include + +extern int fips_check_rsa(RSA *rsa); +#endif + +/* X9.31 RSA key derivation and generation */ + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, + const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, + const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb) + { + BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL; + BN_CTX *ctx=NULL,*ctx2=NULL; + + if (!rsa) + goto err; + + ctx = BN_CTX_new(); + if (!ctx) + 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; + if (!rsa->e) + { + rsa->e = BN_dup(e); + if (!rsa->e) + goto err; + } + else + e = rsa->e; + + /* If not all parameters present only calculate what we can. + * This allows test programs to output selective parameters. + */ + + if (Xp && !rsa->p) + { + rsa->p = BN_new(); + if (!rsa->p) + goto err; + + if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, + Xp, Xp1, Xp2, e, ctx, cb)) + goto err; + } + + if (Xq && !rsa->q) + { + rsa->q = BN_new(); + if (!rsa->q) + goto err; + if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, + Xq, Xq1, Xq2, e, ctx, cb)) + goto err; + } + + if (!rsa->p || !rsa->q) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 2; + } + + /* Since both primes are set we can now calculate all remaining + * components. + */ + + /* calculate n */ + rsa->n=BN_new(); + if (rsa->n == NULL) + goto err; + 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 (!BN_gcd(r3, r1, r2, ctx)) + goto err; + + if (!BN_div(r0, NULL, r0, r3, ctx)) + goto err; /* LCM((p-1)(q-1)) */ + + ctx2 = BN_CTX_new(); + if (!ctx2) + goto err; + + rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */ + if (rsa->d == NULL) + goto err; + + /* calculate d mod (p-1) */ + rsa->dmp1=BN_new(); + if (rsa->dmp1 == NULL) + goto err; + if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) + goto err; + + /* calculate d mod (q-1) */ + rsa->dmq1=BN_new(); + if (rsa->dmq1 == NULL) + goto err; + if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) + goto err; + + /* calculate inverse of q mod p */ + rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2); + + err: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (ctx2) + BN_CTX_free(ctx2); + /* If this is set all calls successful */ + if (rsa && rsa->iqmp != NULL) + return 1; + + return 0; + + } + +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb) + { + int ok = 0; + BIGNUM *Xp = NULL, *Xq = NULL; + BN_CTX *ctx = NULL; + +#ifdef OPENSSL_FIPS + if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT); + return 0; + } + + if (bits & 0xff) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_INVALID_KEY_LENGTH); + return 0; + } + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } +#endif + + ctx = BN_CTX_new(); + if (!ctx) + goto error; + + BN_CTX_start(ctx); + Xp = BN_CTX_get(ctx); + Xq = BN_CTX_get(ctx); + if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) + goto error; + + rsa->p = BN_new(); + rsa->q = BN_new(); + if (!rsa->p || !rsa->q) + goto error; + + /* Generate two primes from Xp, Xq */ + + if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, + e, ctx, cb)) + goto error; + + if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, + e, ctx, cb)) + goto error; + + /* Since rsa->p and rsa->q are valid this call will just derive + * remaining RSA components. + */ + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) + goto error; + +#ifdef OPENSSL_FIPS + if(!fips_check_rsa(rsa)) + goto error; +#endif + + ok = 1; + + error: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (ok) + return 1; + + return 0; + + } diff -up openssl-1.0.0k/crypto/fips/fips_sha1_selftest.c.fips openssl-1.0.0k/crypto/fips/fips_sha1_selftest.c --- openssl-1.0.0k/crypto/fips/fips_sha1_selftest.c.fips 2013-02-19 20:12:54.596664895 +0100 +++ openssl-1.0.0k/crypto/fips/fips_sha1_selftest.c 2013-02-19 20:12:54.596664895 +0100 @@ -0,0 +1,99 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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 +#ifdef OPENSSL_FIPS +#include +#endif +#include +#include + +#ifdef OPENSSL_FIPS +static char test[][60]= + { + "", + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + }; + +static const unsigned char ret[][SHA_DIGEST_LENGTH]= + { + { 0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55, + 0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09 }, + { 0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e, + 0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d }, + { 0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae, + 0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1 }, + }; + +void FIPS_corrupt_sha1() + { + test[2][0]++; + } + +int FIPS_selftest_sha1() + { + int n; + + for(n=0 ; n +#include +#include +#include +#include +#include + +#ifndef FIPSCANISTER_O +int FIPS_selftest_failed() { return 0; } +void FIPS_selftest_check() {} +void OPENSSL_cleanse(void *p,size_t len) {} +#endif + +#ifdef OPENSSL_FIPS + +static void hmac_init(SHA_CTX *md_ctx,SHA_CTX *o_ctx, + const char *key) + { + size_t len=strlen(key); + int i; + unsigned char keymd[HMAC_MAX_MD_CBLOCK]; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + + if (len > SHA_CBLOCK) + { + SHA1_Init(md_ctx); + SHA1_Update(md_ctx,key,len); + SHA1_Final(keymd,md_ctx); + len=20; + } + else + memcpy(keymd,key,len); + memset(&keymd[len],'\0',HMAC_MAX_MD_CBLOCK-len); + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x36^keymd[i]; + SHA1_Init(md_ctx); + SHA1_Update(md_ctx,pad,SHA_CBLOCK); + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x5c^keymd[i]; + SHA1_Init(o_ctx); + SHA1_Update(o_ctx,pad,SHA_CBLOCK); + } + +static void hmac_final(unsigned char *md,SHA_CTX *md_ctx,SHA_CTX *o_ctx) + { + unsigned char buf[20]; + + SHA1_Final(buf,md_ctx); + SHA1_Update(o_ctx,buf,sizeof buf); + SHA1_Final(md,o_ctx); + } + +#endif + +int main(int argc,char **argv) + { +#ifdef OPENSSL_FIPS + static char key[]="etaonrishdlcupfm"; + int n,binary=0; + + if(argc < 2) + { + fprintf(stderr,"%s []+\n",argv[0]); + exit(1); + } + + n=1; + if (!strcmp(argv[n],"-binary")) + { + n++; + binary=1; /* emit binary fingerprint... */ + } + + for(; n < argc ; ++n) + { + FILE *f=fopen(argv[n],"rb"); + SHA_CTX md_ctx,o_ctx; + unsigned char md[20]; + int i; + + if(!f) + { + perror(argv[n]); + exit(2); + } + + hmac_init(&md_ctx,&o_ctx,key); + for( ; ; ) + { + char buf[1024]; + size_t l=fread(buf,1,sizeof buf,f); + + if(l == 0) + { + if(ferror(f)) + { + perror(argv[n]); + exit(3); + } + else + break; + } + SHA1_Update(&md_ctx,buf,l); + } + hmac_final(md,&md_ctx,&o_ctx); + + if (binary) + { + fwrite(md,20,1,stdout); + break; /* ... for single(!) file */ + } + + printf("HMAC-SHA1(%s)= ",argv[n]); + for(i=0 ; i < 20 ; ++i) + printf("%02x",md[i]); + printf("\n"); + } +#endif + return 0; + } + + diff -up openssl-1.0.0k/crypto/fips/fips_test_suite.c.fips openssl-1.0.0k/crypto/fips/fips_test_suite.c --- openssl-1.0.0k/crypto/fips/fips_test_suite.c.fips 2013-02-19 20:12:54.596664895 +0100 +++ openssl-1.0.0k/crypto/fips/fips_test_suite.c 2013-02-19 20:12:54.596664895 +0100 @@ -0,0 +1,588 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * + * This command is intended as a test driver for the FIPS-140 testing + * lab performing FIPS-140 validation. It demonstrates the use of the + * OpenSSL library ito perform a variety of common cryptographic + * functions. A power-up self test is demonstrated by deliberately + * pointing to an invalid executable hash + * + * Contributed by Steve Marquess. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#ifndef OPENSSL_FIPS +int main(int argc, char *argv[]) + { + printf("No FIPS support\n"); + return(0); + } +#else + +#include +#include "fips_utl.h" + +/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext +*/ +static int FIPS_aes_test(void) + { + int ret = 0; + unsigned char pltmp[16]; + unsigned char citmp[16]; + unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + unsigned char plaintext[16] = "etaonrishdlcu"; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 16); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 16); + if (memcmp(pltmp, plaintext, 16)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; + } + +static int FIPS_des3_test(void) + { + int ret = 0; + unsigned char pltmp[8]; + unsigned char citmp[8]; + unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, + 19,20,21,22,23,24}; + unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' }; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 8); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 8); + if (memcmp(pltmp, plaintext, 8)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; + } + +/* + * DSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_dsa_test(int bad) + { + DSA *dsa = NULL; + EVP_PKEY pk; + unsigned char dgst[] = "etaonrishdlc"; + unsigned char buf[60]; + unsigned int slen; + int r = 0; + EVP_MD_CTX mctx; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + dsa = DSA_new(); + if (!dsa) + goto end; + if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL)) + goto end; + if (!DSA_generate_key(dsa)) + goto end; + if (bad) + BN_add_word(dsa->pub_key, 1); + + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + + if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (dsa) + DSA_free(dsa); + if (r != 1) + return 0; + return 1; + } + +/* + * RSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_rsa_test(int bad) + { + RSA *key; + unsigned char input_ptext[] = "etaonrishdlc"; + unsigned char buf[256]; + unsigned int slen; + BIGNUM *bn; + EVP_MD_CTX mctx; + EVP_PKEY pk; + int r = 0; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + key = RSA_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024,bn,NULL)) + return 0; + BN_free(bn); + if (bad) + BN_add_word(key->n, 1); + + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = key; + + if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (key) + RSA_free(key); + if (r != 1) + return 0; + return 1; + } + +/* SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha1_test() + { + unsigned char digest[SHA_DIGEST_LENGTH] = + { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 }; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha1(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha256_test() + { + unsigned char digest[SHA256_DIGEST_LENGTH] = + {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91, + 0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57}; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA256_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha256(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha512_test() + { + unsigned char digest[SHA512_DIGEST_LENGTH] = + {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca, + 0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a, + 0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22, + 0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3}; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA512_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha512(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* HMAC-SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha1_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70, + 0xb2, 0xfb, 0xec, 0xc6}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA224: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha224_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35, + 0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha256_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87, + 0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA384: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha384_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10, + 0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08, + 0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha512_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6, + 0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1, + 0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c, + 0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + + +/* DH: generate shared parameters +*/ +static int dh_test() + { + DH *dh; + ERR_clear_error(); + dh = FIPS_dh_new(); + if (!dh) + return 0; + if (!DH_generate_parameters_ex(dh, 1024, 2, NULL)) + return 0; + FIPS_dh_free(dh); + return 1; + } + +/* Zeroize +*/ +static int Zeroize() + { + RSA *key; + BIGNUM *bn; + unsigned char userkey[16] = + { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 }; + int i, n; + + key = FIPS_rsa_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024,bn,NULL)) + return 0; + BN_free(bn); + + n = BN_num_bytes(key->d); + printf(" Generated %d byte RSA private key\n", n); + printf("\tBN key before overwriting:\n"); + do_bn_print(stdout, key->d); + BN_rand(key->d,n*8,-1,0); + printf("\tBN key after overwriting:\n"); + do_bn_print(stdout, key->d); + + printf("\tchar buffer key before overwriting: \n\t\t"); + for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); + printf("\n"); + RAND_bytes(userkey, sizeof userkey); + printf("\tchar buffer key after overwriting: \n\t\t"); + for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); + printf("\n"); + + return 1; + } + +static int Error; +const char * Fail(const char *msg) + { + do_print_errors(); + Error++; + return msg; + } + +int main(int argc,char **argv) + { + + int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0; + int bad_rsa = 0, bad_dsa = 0; + int do_rng_stick = 0; + int no_exit = 0; + + printf("\tFIPS-mode test application\n\n"); + + /* Load entropy from external file, if any */ + RAND_load_file(".rnd", 1024); + + if (argv[1]) { + /* Corrupted KAT tests */ + if (!strcmp(argv[1], "aes")) { + FIPS_corrupt_aes(); + printf("AES encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "des")) { + FIPS_corrupt_des(); + printf("DES3-ECB encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "dsa")) { + FIPS_corrupt_dsa(); + printf("DSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsa")) { + FIPS_corrupt_rsa(); + printf("RSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsakey")) { + printf("RSA key generation and signature validation with corrupted key...\n"); + bad_rsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "rsakeygen")) { + do_corrupt_rsa_keygen = 1; + no_exit = 1; + printf("RSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "dsakey")) { + printf("DSA key generation and signature validation with corrupted key...\n"); + bad_dsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "dsakeygen")) { + do_corrupt_dsa_keygen = 1; + no_exit = 1; + printf("DSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "sha1")) { + FIPS_corrupt_sha1(); + printf("SHA-1 hash with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rng")) { + FIPS_corrupt_rng(); + } else if (!strcmp(argv[1], "rngstick")) { + do_rng_stick = 1; + no_exit = 1; + printf("RNG test with stuck continuous test...\n"); + } else { + printf("Bad argument \"%s\"\n", argv[1]); + exit(1); + } + if (!no_exit) { + if (!FIPS_mode_set(1)) { + do_print_errors(); + printf("Power-up self test failed\n"); + exit(1); + } + printf("Power-up self test successful\n"); + exit(0); + } + } + + /* Non-Approved cryptographic operation + */ + printf("1. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf( dh_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* Power-up self test + */ + ERR_clear_error(); + printf("2. Automatic power-up self test..."); + if (!FIPS_mode_set(1)) + { + do_print_errors(); + printf(Fail("FAILED!\n")); + exit(1); + } + printf("successful\n"); + if (do_corrupt_dsa_keygen) + FIPS_corrupt_dsa_keygen(); + if (do_corrupt_rsa_keygen) + FIPS_corrupt_rsa_keygen(); + if (do_rng_stick) + FIPS_rng_stick(); + + /* AES encryption/decryption + */ + printf("3. AES encryption/decryption..."); + printf( FIPS_aes_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* RSA key generation and encryption/decryption + */ + printf("4. RSA key generation and encryption/decryption..."); + printf( FIPS_rsa_test(bad_rsa) ? "successful\n" : Fail("FAILED!\n") ); + + /* DES-CBC encryption/decryption + */ + printf("5. DES-ECB encryption/decryption..."); + printf( FIPS_des3_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* DSA key generation and signature validation + */ + printf("6. DSA key generation and signature validation..."); + printf( FIPS_dsa_test(bad_dsa) ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-1 hash + */ + printf("7a. SHA-1 hash..."); + printf( FIPS_sha1_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-256 hash + */ + printf("7b. SHA-256 hash..."); + printf( FIPS_sha256_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-512 hash + */ + printf("7c. SHA-512 hash..."); + printf( FIPS_sha512_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-1 hash + */ + printf("7d. HMAC-SHA-1 hash..."); + printf( FIPS_hmac_sha1_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-224 hash + */ + printf("7e. HMAC-SHA-224 hash..."); + printf( FIPS_hmac_sha224_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-256 hash + */ + printf("7f. HMAC-SHA-256 hash..."); + printf( FIPS_hmac_sha256_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-384 hash + */ + printf("7g. HMAC-SHA-384 hash..."); + printf( FIPS_hmac_sha384_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-512 hash + */ + printf("7h. HMAC-SHA-512 hash..."); + printf( FIPS_hmac_sha512_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* Non-Approved cryptographic operation + */ + printf("8. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf( dh_test() ? "successful as expected\n" + : Fail("failed INCORRECTLY!\n") ); + + /* Zeroization + */ + printf("9. Zero-ization...\n"); + printf( Zeroize() ? "\tsuccessful as expected\n" + : Fail("\tfailed INCORRECTLY!\n") ); + + printf("\nAll tests completed with %d errors\n", Error); + return Error ? 1 : 0; + } + +#endif diff -up openssl-1.0.0k/crypto/fips_locl.h.fips openssl-1.0.0k/crypto/fips_locl.h --- openssl-1.0.0k/crypto/fips_locl.h.fips 2013-02-19 20:12:54.596664895 +0100 +++ openssl-1.0.0k/crypto/fips_locl.h 2013-02-19 20:12:54.596664895 +0100 @@ -0,0 +1,72 @@ +/* ==================================================================== + * Copyright (c) 2003 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 + * 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. + * + */ + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +void fips_w_lock(void); +void fips_w_unlock(void); +void fips_r_lock(void); +void fips_r_unlock(void); +int fips_is_started(void); +void fips_set_started(void); +int fips_is_owning_thread(void); +int fips_set_owning_thread(void); +void fips_set_selftest_fail(void); +int fips_clear_owning_thread(void); + +#define FIPS_MAX_CIPHER_TEST_SIZE 16 + +#ifdef __cplusplus +} +#endif +#endif diff -up openssl-1.0.0k/crypto/fips/Makefile.fips openssl-1.0.0k/crypto/fips/Makefile --- openssl-1.0.0k/crypto/fips/Makefile.fips 2013-02-19 20:12:54.597664913 +0100 +++ openssl-1.0.0k/crypto/fips/Makefile 2013-02-19 20:12:54.597664913 +0100 @@ -0,0 +1,81 @@ +# +# OpenSSL/crypto/fips/Makefile +# + +DIR= fips +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=fips_test_suite.c fips_randtest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_aes_selftest.c fips_des_selftest.c fips_hmac_selftest.c fips_rand_selftest.c \ + fips_rsa_selftest.c fips_sha1_selftest.c fips.c fips_dsa_selftest.c fips_rand.c \ + fips_rsa_x931g.c + +LIBOBJ=fips_aes_selftest.o fips_des_selftest.o fips_hmac_selftest.o fips_rand_selftest.o \ + fips_rsa_selftest.o fips_sha1_selftest.o fips.o fips_dsa_selftest.o fips_rand.o \ + fips_rsa_x931g.o + +SRC= $(LIBSRC) fips_standalone_sha1.c + +EXHEADER= fips.h fips_rand.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + @headerlist="$(EXHEADER)"; for i in $$headerlist ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + diff -up openssl-1.0.0k/crypto/hmac/hmac.c.fips openssl-1.0.0k/crypto/hmac/hmac.c --- openssl-1.0.0k/crypto/hmac/hmac.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/hmac/hmac.c 2013-02-19 20:12:54.597664913 +0100 @@ -77,6 +77,13 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const vo if (key != NULL) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS) + && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))) + goto err; +#endif reset=1; j=EVP_MD_block_size(md); OPENSSL_assert(j <= (int)sizeof(ctx->key)); diff -up openssl-1.0.0k/crypto/Makefile.fips openssl-1.0.0k/crypto/Makefile --- openssl-1.0.0k/crypto/Makefile.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/Makefile 2013-02-19 20:12:54.597664913 +0100 @@ -34,14 +34,14 @@ GENERAL=Makefile README crypto-lib.com i LIB= $(TOP)/libcrypto.a SHARED_LIB= libcrypto$(SHLIB_EXT) -LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c -LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o $(CPUID_OBJ) +LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c o_init.c fips_err.c +LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o o_init.o fips_err.o $(CPUID_OBJ) SRC= $(LIBSRC) EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \ ossl_typ.h -HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER) +HEADER= cryptlib.h buildinf.h fips_locl.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER) ALL= $(GENERAL) $(SRC) $(HEADER) diff -up openssl-1.0.0k/crypto/md2/md2_dgst.c.fips openssl-1.0.0k/crypto/md2/md2_dgst.c --- openssl-1.0.0k/crypto/md2/md2_dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/md2/md2_dgst.c 2013-02-19 20:12:54.597664913 +0100 @@ -62,6 +62,11 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif + +#include const char MD2_version[]="MD2" OPENSSL_VERSION_PTEXT; @@ -116,7 +121,7 @@ const char *MD2_options(void) return("md2(int)"); } -int MD2_Init(MD2_CTX *c) +FIPS_NON_FIPS_MD_Init(MD2) { c->num=0; memset(c->state,0,sizeof c->state); diff -up openssl-1.0.0k/crypto/md2/md2.h.fips openssl-1.0.0k/crypto/md2/md2.h --- openssl-1.0.0k/crypto/md2/md2.h.fips 2013-02-19 20:12:54.348660189 +0100 +++ openssl-1.0.0k/crypto/md2/md2.h 2013-02-19 20:12:54.597664913 +0100 @@ -81,6 +81,9 @@ typedef struct MD2state_st } MD2_CTX; const char *MD2_options(void); +#ifdef OPENSSL_FIPS +int private_MD2_Init(MD2_CTX *c); +#endif int MD2_Init(MD2_CTX *c); int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len); int MD2_Final(unsigned char *md, MD2_CTX *c); diff -up openssl-1.0.0k/crypto/md4/md4_dgst.c.fips openssl-1.0.0k/crypto/md4/md4_dgst.c --- openssl-1.0.0k/crypto/md4/md4_dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/md4/md4_dgst.c 2013-02-19 20:12:54.598664931 +0100 @@ -59,6 +59,11 @@ #include #include "md4_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT; @@ -70,7 +75,7 @@ const char MD4_version[]="MD4" OPENSSL_V #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -int MD4_Init(MD4_CTX *c) +FIPS_NON_FIPS_MD_Init(MD4) { memset (c,0,sizeof(*c)); c->A=INIT_DATA_A; diff -up openssl-1.0.0k/crypto/md4/md4.h.fips openssl-1.0.0k/crypto/md4/md4.h --- openssl-1.0.0k/crypto/md4/md4.h.fips 2013-02-19 20:12:54.268658671 +0100 +++ openssl-1.0.0k/crypto/md4/md4.h 2013-02-19 20:12:54.598664931 +0100 @@ -105,6 +105,9 @@ typedef struct MD4state_st unsigned int num; } MD4_CTX; +#ifdef OPENSSL_FIPS +int private_MD4_Init(MD4_CTX *c); +#endif int MD4_Init(MD4_CTX *c); int MD4_Update(MD4_CTX *c, const void *data, size_t len); int MD4_Final(unsigned char *md, MD4_CTX *c); diff -up openssl-1.0.0k/crypto/md5/md5_dgst.c.fips openssl-1.0.0k/crypto/md5/md5_dgst.c --- openssl-1.0.0k/crypto/md5/md5_dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/md5/md5_dgst.c 2013-02-19 20:12:54.598664931 +0100 @@ -59,6 +59,11 @@ #include #include "md5_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT; @@ -70,7 +75,7 @@ const char MD5_version[]="MD5" OPENSSL_V #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -int MD5_Init(MD5_CTX *c) +FIPS_NON_FIPS_MD_Init(MD5) { memset (c,0,sizeof(*c)); c->A=INIT_DATA_A; diff -up openssl-1.0.0k/crypto/md5/md5.h.fips openssl-1.0.0k/crypto/md5/md5.h --- openssl-1.0.0k/crypto/md5/md5.h.fips 2013-02-19 20:12:54.012653813 +0100 +++ openssl-1.0.0k/crypto/md5/md5.h 2013-02-19 20:12:54.598664931 +0100 @@ -105,6 +105,9 @@ typedef struct MD5state_st unsigned int num; } MD5_CTX; +#ifdef OPENSSL_FIPS +int private_MD5_Init(MD5_CTX *c); +#endif int MD5_Init(MD5_CTX *c); int MD5_Update(MD5_CTX *c, const void *data, size_t len); int MD5_Final(unsigned char *md, MD5_CTX *c); diff -up openssl-1.0.0k/crypto/mdc2/mdc2dgst.c.fips openssl-1.0.0k/crypto/mdc2/mdc2dgst.c --- openssl-1.0.0k/crypto/mdc2/mdc2dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/mdc2/mdc2dgst.c 2013-02-19 20:12:54.597664913 +0100 @@ -61,6 +61,11 @@ #include #include #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + #undef c2l #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ @@ -75,7 +80,7 @@ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); -int MDC2_Init(MDC2_CTX *c) +FIPS_NON_FIPS_MD_Init(MDC2) { c->num=0; c->pad_type=1; diff -up openssl-1.0.0k/crypto/mdc2/mdc2.h.fips openssl-1.0.0k/crypto/mdc2/mdc2.h --- openssl-1.0.0k/crypto/mdc2/mdc2.h.fips 2013-02-19 20:12:54.061654741 +0100 +++ openssl-1.0.0k/crypto/mdc2/mdc2.h 2013-02-19 20:12:54.597664913 +0100 @@ -80,7 +80,9 @@ typedef struct mdc2_ctx_st int pad_type; /* either 1 or 2, default 1 */ } MDC2_CTX; - +#ifdef OPENSSL_FIPS +int private_MDC2_Init(MDC2_CTX *c); +#endif int MDC2_Init(MDC2_CTX *c); int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); int MDC2_Final(unsigned char *md, MDC2_CTX *c); diff -up openssl-1.0.0k/crypto/mem.c.fips openssl-1.0.0k/crypto/mem.c --- openssl-1.0.0k/crypto/mem.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/mem.c 2013-02-19 20:12:54.598664931 +0100 @@ -101,7 +101,7 @@ static void (*free_locked_func)(void *) /* may be changed as long as 'allow_customize_debug' is set */ /* XXX use correct function pointer types */ -#ifdef CRYPTO_MDEBUG +#if defined(CRYPTO_MDEBUG) && !defined(OPENSSL_FIPS) /* use default functions from mem_dbg.c */ static void (*malloc_debug_func)(void *,int,const char *,int,int) = CRYPTO_dbg_malloc; diff -up openssl-1.0.0k/crypto/o_init.c.fips openssl-1.0.0k/crypto/o_init.c --- openssl-1.0.0k/crypto/o_init.c.fips 2013-02-19 20:12:54.598664931 +0100 +++ openssl-1.0.0k/crypto/o_init.c 2013-02-19 20:12:54.598664931 +0100 @@ -0,0 +1,80 @@ +/* o_init.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2007 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 + * 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +/* Perform any essential OpenSSL initialization operations. + * Currently only sets FIPS callbacks + */ + +void OPENSSL_init_library(void) + { +#ifdef OPENSSL_FIPS + static int done = 0; + if (!done) + { +#ifdef CRYPTO_MDEBUG + CRYPTO_malloc_debug_init(); +#endif + done = 1; + } +#endif + } + + diff -up openssl-1.0.0k/crypto/opensslconf.h.in.fips openssl-1.0.0k/crypto/opensslconf.h.in --- openssl-1.0.0k/crypto/opensslconf.h.in.fips 2013-02-05 12:47:28.000000000 +0100 +++ openssl-1.0.0k/crypto/opensslconf.h.in 2013-02-19 20:12:54.599664950 +0100 @@ -1,5 +1,20 @@ /* crypto/opensslconf.h.in */ +#ifdef OPENSSL_DOING_MAKEDEPEND + +/* Include any symbols here that have to be explicitly set to enable a feature + * that should be visible to makedepend. + * + * [Our "make depend" doesn't actually look at this, we use actual build settings + * instead; we want to make it easy to remove subdirectories with disabled algorithms.] + */ + +#ifndef OPENSSL_FIPS +#define OPENSSL_FIPS +#endif + +#endif + /* Generate 80386 code? */ #undef I386_ONLY diff -up openssl-1.0.0k/crypto/pkcs12/p12_crt.c.fips openssl-1.0.0k/crypto/pkcs12/p12_crt.c --- openssl-1.0.0k/crypto/pkcs12/p12_crt.c.fips 2013-02-05 12:47:28.000000000 +0100 +++ openssl-1.0.0k/crypto/pkcs12/p12_crt.c 2013-02-19 20:12:54.599664950 +0100 @@ -59,6 +59,10 @@ #include #include "cryptlib.h" #include +#ifdef OPENSSL_FIPS +#include +#endif + static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); @@ -90,11 +94,18 @@ PKCS12 *PKCS12_create(char *pass, char * /* Set defaults */ if (!nid_cert) + { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + else +#endif #ifdef OPENSSL_NO_RC2 nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; #else nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; #endif + } if (!nid_key) nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; if (!iter) diff -up openssl-1.0.0k/crypto/rand/md_rand.c.fips openssl-1.0.0k/crypto/rand/md_rand.c --- openssl-1.0.0k/crypto/rand/md_rand.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rand/md_rand.c 2013-02-19 20:12:54.599664950 +0100 @@ -126,6 +126,10 @@ #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #ifdef BN_DEBUG # define PREDICT @@ -342,6 +346,14 @@ static int ssleay_rand_bytes(unsigned ch #endif int do_stir_pool = 0; +#ifdef OPENSSL_FIPS + if(FIPS_mode()) + { + FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD); + return 0; + } +#endif + #ifdef PREDICT if (rand_predictable) { diff -up openssl-1.0.0k/crypto/rand/rand_err.c.fips openssl-1.0.0k/crypto/rand/rand_err.c --- openssl-1.0.0k/crypto/rand/rand_err.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rand/rand_err.c 2013-02-19 20:12:54.599664950 +0100 @@ -70,6 +70,13 @@ static ERR_STRING_DATA RAND_str_functs[]= { +{ERR_FUNC(RAND_F_ENG_RAND_GET_RAND_METHOD), "ENG_RAND_GET_RAND_METHOD"}, +{ERR_FUNC(RAND_F_FIPS_RAND), "FIPS_RAND"}, +{ERR_FUNC(RAND_F_FIPS_RAND_BYTES), "FIPS_RAND_BYTES"}, +{ERR_FUNC(RAND_F_FIPS_RAND_SET_DT), "FIPS_RAND_SET_DT"}, +{ERR_FUNC(RAND_F_FIPS_SET_DT), "FIPS_SET_DT"}, +{ERR_FUNC(RAND_F_FIPS_SET_PRNG_SEED), "FIPS_SET_PRNG_SEED"}, +{ERR_FUNC(RAND_F_FIPS_SET_TEST_MODE), "FIPS_SET_TEST_MODE"}, {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, {0,NULL} @@ -77,7 +84,17 @@ static ERR_STRING_DATA RAND_str_functs[] static ERR_STRING_DATA RAND_str_reasons[]= { +{ERR_REASON(RAND_R_NON_FIPS_METHOD) ,"non fips method"}, +{ERR_REASON(RAND_R_NOT_IN_TEST_MODE) ,"not in test mode"}, +{ERR_REASON(RAND_R_NO_KEY_SET) ,"no key set"}, +{ERR_REASON(RAND_R_PRNG_ASKING_FOR_TOO_MUCH),"prng asking for too much"}, +{ERR_REASON(RAND_R_PRNG_ERROR) ,"prng error"}, +{ERR_REASON(RAND_R_PRNG_KEYED) ,"prng keyed"}, +{ERR_REASON(RAND_R_PRNG_NOT_REKEYED) ,"prng not rekeyed"}, +{ERR_REASON(RAND_R_PRNG_NOT_RESEEDED) ,"prng not reseeded"}, {ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"}, +{ERR_REASON(RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY),"prng seed must not match key"}, +{ERR_REASON(RAND_R_PRNG_STUCK) ,"prng stuck"}, {0,NULL} }; diff -up openssl-1.0.0k/crypto/rand/rand.h.fips openssl-1.0.0k/crypto/rand/rand.h --- openssl-1.0.0k/crypto/rand/rand.h.fips 2013-02-19 20:12:54.071654932 +0100 +++ openssl-1.0.0k/crypto/rand/rand.h 2013-02-19 20:12:54.599664950 +0100 @@ -128,11 +128,28 @@ void ERR_load_RAND_strings(void); /* Error codes for the RAND functions. */ /* Function codes. */ +#define RAND_F_ENG_RAND_GET_RAND_METHOD 108 +#define RAND_F_FIPS_RAND 103 +#define RAND_F_FIPS_RAND_BYTES 102 +#define RAND_F_FIPS_RAND_SET_DT 106 +#define RAND_F_FIPS_SET_DT 104 +#define RAND_F_FIPS_SET_PRNG_SEED 107 +#define RAND_F_FIPS_SET_TEST_MODE 105 #define RAND_F_RAND_GET_RAND_METHOD 101 #define RAND_F_SSLEAY_RAND_BYTES 100 /* Reason codes. */ +#define RAND_R_NON_FIPS_METHOD 105 +#define RAND_R_NOT_IN_TEST_MODE 106 +#define RAND_R_NO_KEY_SET 107 +#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101 +#define RAND_R_PRNG_ERROR 108 +#define RAND_R_PRNG_KEYED 109 +#define RAND_R_PRNG_NOT_REKEYED 102 +#define RAND_R_PRNG_NOT_RESEEDED 103 #define RAND_R_PRNG_NOT_SEEDED 100 +#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110 +#define RAND_R_PRNG_STUCK 104 #ifdef __cplusplus } diff -up openssl-1.0.0k/crypto/rand/rand_lib.c.fips openssl-1.0.0k/crypto/rand/rand_lib.c --- openssl-1.0.0k/crypto/rand/rand_lib.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rand/rand_lib.c 2013-02-19 20:12:54.599664950 +0100 @@ -60,6 +60,12 @@ #include #include "cryptlib.h" #include +#include "rand_lcl.h" +#ifdef OPENSSL_FIPS +#include +#include +#endif + #ifndef OPENSSL_NO_ENGINE #include #endif @@ -102,8 +108,19 @@ const RAND_METHOD *RAND_get_rand_method( funct_ref = e; else #endif +#ifdef OPENSSL_FIPS + default_RAND_meth = FIPS_mode() ? FIPS_rand_method() : RAND_SSLeay(); + } + if (FIPS_mode() + && default_RAND_meth != FIPS_rand_check()) + { + RANDerr(RAND_F_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD); + return 0; + } +#else default_RAND_meth = RAND_SSLeay(); } +#endif return default_RAND_meth; } diff -up openssl-1.0.0k/crypto/rc2/rc2.h.fips openssl-1.0.0k/crypto/rc2/rc2.h --- openssl-1.0.0k/crypto/rc2/rc2.h.fips 2013-02-19 20:12:54.216657683 +0100 +++ openssl-1.0.0k/crypto/rc2/rc2.h 2013-02-19 20:12:54.599664950 +0100 @@ -79,7 +79,9 @@ typedef struct rc2_key_st RC2_INT data[64]; } RC2_KEY; - +#ifdef OPENSSL_FIPS +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); +#endif void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits); void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key, int enc); diff -up openssl-1.0.0k/crypto/rc2/rc2_skey.c.fips openssl-1.0.0k/crypto/rc2/rc2_skey.c --- openssl-1.0.0k/crypto/rc2/rc2_skey.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rc2/rc2_skey.c 2013-02-19 20:12:54.600664970 +0100 @@ -57,6 +57,11 @@ */ #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + #include "rc2_locl.h" static const unsigned char key_table[256]={ @@ -94,8 +99,20 @@ static const unsigned char key_table[256 * BSAFE uses the 'retarded' version. What I previously shipped is * the same as specifying 1024 for the 'bits' parameter. Bsafe uses * a version where the bits parameter is the same as len*8 */ + +#ifdef OPENSSL_FIPS void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) { + if (FIPS_mode()) + FIPS_BAD_ABORT(RC2) + private_RC2_set_key(key, len, data, bits); + } +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, + int bits) +#else +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) +#endif + { int i,j; unsigned char *k; RC2_INT *ki; diff -up openssl-1.0.0k/crypto/rc4/asm/rc4-586.pl.fips openssl-1.0.0k/crypto/rc4/asm/rc4-586.pl --- openssl-1.0.0k/crypto/rc4/asm/rc4-586.pl.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rc4/asm/rc4-586.pl 2013-02-19 20:12:54.600664970 +0100 @@ -166,8 +166,12 @@ $idx="edx"; &external_label("OPENSSL_ia32cap_P"); +$setkeyfunc = "RC4_set_key"; +$setkeyfunc = "private_RC4_set_key" if ($ENV{FIPS} ne ""); + + # void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data); -&function_begin("RC4_set_key"); +&function_begin($setkeyfunc); &mov ($out,&wparam(0)); # load key &mov ($idi,&wparam(1)); # load len &mov ($inp,&wparam(2)); # load data @@ -245,7 +249,7 @@ $idx="edx"; &xor ("eax","eax"); &mov (&DWP(-8,$out),"eax"); # key->x=0; &mov (&DWP(-4,$out),"eax"); # key->y=0; -&function_end("RC4_set_key"); +&function_end($setkeyfunc); # const char *RC4_options(void); &function_begin_B("RC4_options"); diff -up openssl-1.0.0k/crypto/rc4/asm/rc4-s390x.pl.fips openssl-1.0.0k/crypto/rc4/asm/rc4-s390x.pl --- openssl-1.0.0k/crypto/rc4/asm/rc4-s390x.pl.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rc4/asm/rc4-s390x.pl 2013-02-19 20:12:54.600664970 +0100 @@ -202,4 +202,6 @@ RC4_options: .string "rc4(8x,char)" ___ +$code =~ s/RC4_set_key/private_RC4_set_key/g if ($ENV{FIPS} ne ""); + print $code; diff -up openssl-1.0.0k/crypto/rc4/asm/rc4-x86_64.pl.fips openssl-1.0.0k/crypto/rc4/asm/rc4-x86_64.pl --- openssl-1.0.0k/crypto/rc4/asm/rc4-x86_64.pl.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rc4/asm/rc4-x86_64.pl 2013-02-19 20:12:54.600664970 +0100 @@ -499,6 +499,8 @@ ___ $code =~ s/#([bwd])/$1/gm; +$code =~ s/RC4_set_key/private_RC4_set_key/g if ($ENV{FIPS} ne ""); + print $code; close STDOUT; diff -up openssl-1.0.0k/crypto/rc4/Makefile.fips openssl-1.0.0k/crypto/rc4/Makefile --- openssl-1.0.0k/crypto/rc4/Makefile.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rc4/Makefile 2013-02-19 20:12:54.600664970 +0100 @@ -21,8 +21,8 @@ TEST=rc4test.c APPS= LIB=$(TOP)/libcrypto.a -LIBSRC=rc4_skey.c rc4_enc.c -LIBOBJ=$(RC4_ENC) +LIBSRC=rc4_skey.c rc4_enc.c rc4_fblk.c +LIBOBJ=$(RC4_ENC) rc4_fblk.o SRC= $(LIBSRC) diff -up openssl-1.0.0k/crypto/rc4/rc4_fblk.c.fips openssl-1.0.0k/crypto/rc4/rc4_fblk.c --- openssl-1.0.0k/crypto/rc4/rc4_fblk.c.fips 2013-02-19 20:12:54.601664990 +0100 +++ openssl-1.0.0k/crypto/rc4/rc4_fblk.c 2013-02-19 20:12:54.601664990 +0100 @@ -0,0 +1,75 @@ +/* crypto/rc4/rc4_fblk.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 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. + * ==================================================================== + */ + + +#include +#include "rc4_locl.h" +#include +#include +#ifdef OPENSSL_FIPS +#include +#endif + +/* FIPS mode blocking for RC4 has to be done separately since RC4_set_key + * may be implemented in an assembly language file. + */ + +#ifdef OPENSSL_FIPS +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) + { + if (FIPS_mode()) + FIPS_BAD_ABORT(RC4) + private_RC4_set_key(key, len, data); + } +#endif + diff -up openssl-1.0.0k/crypto/rc4/rc4.h.fips openssl-1.0.0k/crypto/rc4/rc4.h --- openssl-1.0.0k/crypto/rc4/rc4.h.fips 2013-02-19 20:12:53.860650927 +0100 +++ openssl-1.0.0k/crypto/rc4/rc4.h 2013-02-19 20:12:54.601664990 +0100 @@ -78,6 +78,9 @@ typedef struct rc4_key_st const char *RC4_options(void); +#ifdef OPENSSL_FIPS +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +#endif void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, unsigned char *outdata); diff -up openssl-1.0.0k/crypto/rc4/rc4_skey.c.fips openssl-1.0.0k/crypto/rc4/rc4_skey.c --- openssl-1.0.0k/crypto/rc4/rc4_skey.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rc4/rc4_skey.c 2013-02-19 20:12:54.601664990 +0100 @@ -59,6 +59,11 @@ #include #include "rc4_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT; @@ -85,7 +90,11 @@ const char *RC4_options(void) * Date: Wed, 14 Sep 1994 06:35:31 GMT */ +#ifdef OPENSSL_FIPS +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +#else void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +#endif { register RC4_INT tmp; register int id1,id2; @@ -126,7 +135,12 @@ void RC4_set_key(RC4_KEY *key, int len, * module... * */ +#ifdef OPENSSL_FIPS + unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc(); + if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) { +#else if (OPENSSL_ia32cap_P & (1<<28)) { +#endif unsigned char *cp=(unsigned char *)d; for (i=0;i<256;i++) cp[i]=i; diff -up openssl-1.0.0k/crypto/ripemd/ripemd.h.fips openssl-1.0.0k/crypto/ripemd/ripemd.h --- openssl-1.0.0k/crypto/ripemd/ripemd.h.fips 2013-02-19 20:12:54.170656810 +0100 +++ openssl-1.0.0k/crypto/ripemd/ripemd.h 2013-02-19 20:12:54.601664990 +0100 @@ -91,6 +91,9 @@ typedef struct RIPEMD160state_st unsigned int num; } RIPEMD160_CTX; +#ifdef OPENSSL_FIPS +int private_RIPEMD160_Init(RIPEMD160_CTX *c); +#endif int RIPEMD160_Init(RIPEMD160_CTX *c); int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); diff -up openssl-1.0.0k/crypto/ripemd/rmd_dgst.c.fips openssl-1.0.0k/crypto/ripemd/rmd_dgst.c --- openssl-1.0.0k/crypto/ripemd/rmd_dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/ripemd/rmd_dgst.c 2013-02-19 20:12:54.601664990 +0100 @@ -59,6 +59,11 @@ #include #include "rmd_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT; @@ -69,7 +74,7 @@ const char RMD160_version[]="RIPE-MD160" void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num); # endif -int RIPEMD160_Init(RIPEMD160_CTX *c) +FIPS_NON_FIPS_MD_Init(RIPEMD160) { memset (c,0,sizeof(*c)); c->A=RIPEMD160_A; diff -up openssl-1.0.0k/crypto/rsa/rsa_eay.c.fips openssl-1.0.0k/crypto/rsa/rsa_eay.c --- openssl-1.0.0k/crypto/rsa/rsa_eay.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rsa/rsa_eay.c 2013-02-19 20:12:54.601664990 +0100 @@ -114,6 +114,10 @@ #include #include #include +#include +#ifdef OPENSSL_FIPS +#include +#endif #ifndef RSA_NULL @@ -138,7 +142,7 @@ static RSA_METHOD rsa_pkcs1_eay_meth={ BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */ RSA_eay_init, RSA_eay_finish, - 0, /* flags */ + RSA_FLAG_FIPS_METHOD, /* flags */ NULL, 0, /* rsa_sign */ 0, /* rsa_verify */ @@ -150,6 +154,16 @@ const RSA_METHOD *RSA_PKCS1_SSLeay(void) return(&rsa_pkcs1_eay_meth); } +/* Usage example; + * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + */ +#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \ + if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \ + !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \ + CRYPTO_LOCK_RSA, \ + (rsa)->m, (ctx))) \ + err_instr + static int RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { @@ -158,6 +172,23 @@ static int RSA_eay_public_encrypt(int fl unsigned char *buf=NULL; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if(FIPS_mode()) + { + if (FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); @@ -223,9 +254,7 @@ static int RSA_eay_public_encrypt(int fl goto err; } - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) - goto err; + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -361,6 +390,23 @@ static int RSA_eay_private_encrypt(int f BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -444,9 +490,7 @@ static int RSA_eay_private_encrypt(int f else d= rsa->d; - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) - goto err; + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -504,6 +548,23 @@ static int RSA_eay_private_decrypt(int f BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -577,9 +638,7 @@ static int RSA_eay_private_decrypt(int f else d = rsa->d; - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) - goto err; + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -639,6 +698,23 @@ static int RSA_eay_public_decrypt(int fl unsigned char *buf=NULL; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + { + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +#endif + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); @@ -689,9 +765,7 @@ static int RSA_eay_public_decrypt(int fl goto err; } - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) - goto err; + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; @@ -739,6 +813,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c BIGNUM *r1,*m1,*vrfy; BIGNUM local_dmp1,local_dmq1,local_c,local_r1; BIGNUM *dmp1,*dmq1,*c,*pr1; + int bn_flags; int ret=0; BN_CTX_start(ctx); @@ -746,41 +821,31 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); - { - BIGNUM local_p, local_q; - BIGNUM *p = NULL, *q = NULL; - - /* Make sure BN_mod_inverse in Montgomery intialization uses the - * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) - */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) - { - BN_init(&local_p); - p = &local_p; - BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); - - BN_init(&local_q); - q = &local_q; - BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); - } - else - { - p = rsa->p; - q = rsa->q; - } + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->p->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->p->flags |= BN_FLG_CONSTTIME; + } + MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->p->flags = bn_flags; - if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) - { - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx)) - goto err; - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx)) - goto err; - } - } + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->q->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->q->flags |= BN_FLG_CONSTTIME; + } + MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->q->flags = bn_flags; - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) - goto err; + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); /* compute I mod q */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) @@ -897,6 +962,9 @@ err: static int RSA_eay_init(RSA *rsa) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE; return(1); } diff -up openssl-1.0.0k/crypto/rsa/rsa_err.c.fips openssl-1.0.0k/crypto/rsa/rsa_err.c --- openssl-1.0.0k/crypto/rsa/rsa_err.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rsa/rsa_err.c 2013-02-19 20:12:54.602665009 +0100 @@ -111,8 +111,12 @@ static ERR_STRING_DATA RSA_str_functs[]= {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, {ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"}, {ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"}, +{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, +{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, +{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"}, +{ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"}, {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"}, {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, @@ -155,10 +159,12 @@ static ERR_STRING_DATA RSA_str_reasons[] {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(RSA_R_LAST_OCTET_INVALID) ,"last octet invalid"}, {ERR_REASON(RSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, +{ERR_REASON(RSA_R_NON_FIPS_METHOD) ,"non fips method"}, {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT) ,"no public exponent"}, {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"}, {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q) ,"n does not equal p q"}, {ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"}, +{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"}, {ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"}, {ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"}, {ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"}, diff -up openssl-1.0.0k/crypto/rsa/rsa_gen.c.fips openssl-1.0.0k/crypto/rsa/rsa_gen.c --- openssl-1.0.0k/crypto/rsa/rsa_gen.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rsa/rsa_gen.c 2013-02-19 20:12:54.602665009 +0100 @@ -67,6 +67,82 @@ #include "cryptlib.h" #include #include +#ifdef OPENSSL_FIPS +#include +#include +#include +#include "fips_locl.h" + +static int fips_rsa_pairwise_fail = 0; + +void FIPS_corrupt_rsa_keygen(void) + { + fips_rsa_pairwise_fail = 1; + } + +int fips_check_rsa(RSA *rsa) + { + const unsigned char tbs[] = "RSA Pairwise Check Data"; + unsigned char *ctbuf = NULL, *ptbuf = NULL; + int len, ret = 0; + EVP_PKEY *pk; + + if ((pk=EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_set1_RSA(pk, rsa); + + /* Perform pairwise consistency signature test */ + if (!fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, NULL) + || !fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, NULL) + || !fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, NULL)) + goto err; + /* Now perform pairwise consistency encrypt/decrypt test */ + ctbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!ctbuf) + goto err; + + len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING); + if (len <= 0) + goto err; + /* Check ciphertext doesn't match plaintext */ + if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len)) + 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 != (sizeof(tbs) - 1)) + goto err; + if (memcmp(ptbuf, tbs, len)) + goto err; + + ret = 1; + + if (!ptbuf) + goto err; + + err: + if (ret == 0) + { + fips_set_selftest_fail(); + FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); + } + + if (ctbuf) + OPENSSL_free(ctbuf); + if (ptbuf) + OPENSSL_free(ptbuf); + if (pk) + EVP_PKEY_free(pk); + + return ret; + } +#endif static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); @@ -90,6 +166,23 @@ static int rsa_builtin_keygen(RSA *rsa, int bitsp,bitsq,ok= -1,n=0; BN_CTX *ctx=NULL; +#ifdef OPENSSL_FIPS + if (FIPS_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; + } + } +#endif + ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); @@ -201,6 +294,17 @@ 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_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.0k/crypto/rsa/rsa.h.fips openssl-1.0.0k/crypto/rsa/rsa.h --- openssl-1.0.0k/crypto/rsa/rsa.h.fips 2013-02-19 20:12:54.354660303 +0100 +++ openssl-1.0.0k/crypto/rsa/rsa.h 2013-02-19 20:12:54.602665009 +0100 @@ -74,6 +74,21 @@ #error RSA is disabled. #endif +/* If this flag is set the RSA method is FIPS compliant and can be used + * in FIPS mode. This is set in the validated module method. If an + * application sets this flag in its own methods it is its reposibility + * to ensure the result is compliant. + */ + +#define RSA_FLAG_FIPS_METHOD 0x0400 + +/* If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +#define RSA_FLAG_NON_FIPS_ALLOW 0x0400 + #ifdef __cplusplus extern "C" { #endif @@ -164,6 +179,8 @@ struct rsa_st # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif +#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 #endif @@ -267,6 +284,11 @@ RSA * RSA_generate_key(int bits, unsigne /* New version */ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, + const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, + const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb); int RSA_check_key(const RSA *); /* next 4 return -1 on error */ @@ -438,8 +460,12 @@ void ERR_load_RSA_strings(void); #define RSA_F_RSA_PRINT_FP 116 #define RSA_F_RSA_PRIV_DECODE 137 #define RSA_F_RSA_PRIV_ENCODE 138 +#define RSA_F_RSA_PRIVATE_ENCRYPT 148 #define RSA_F_RSA_PUB_DECODE 139 +#define RSA_F_RSA_PUBLIC_DECRYPT 149 #define RSA_F_RSA_SETUP_BLINDING 136 +#define RSA_F_RSA_SET_DEFAULT_METHOD 150 +#define RSA_F_RSA_SET_METHOD 151 #define RSA_F_RSA_SIGN 117 #define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 #define RSA_F_RSA_VERIFY 119 @@ -479,10 +505,12 @@ void ERR_load_RSA_strings(void); #define RSA_R_KEY_SIZE_TOO_SMALL 120 #define RSA_R_LAST_OCTET_INVALID 134 #define RSA_R_MODULUS_TOO_LARGE 105 +#define RSA_R_NON_FIPS_METHOD 149 #define RSA_R_NO_PUBLIC_EXPONENT 140 #define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 #define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 #define RSA_R_OAEP_DECODING_ERROR 121 +#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 150 #define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 #define RSA_R_PADDING_CHECK_FAILED 114 #define RSA_R_P_NOT_PRIME 128 diff -up openssl-1.0.0k/crypto/rsa/rsa_lib.c.fips openssl-1.0.0k/crypto/rsa/rsa_lib.c --- openssl-1.0.0k/crypto/rsa/rsa_lib.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rsa/rsa_lib.c 2013-02-19 20:12:54.602665009 +0100 @@ -80,6 +80,13 @@ RSA *RSA_new(void) void RSA_set_default_method(const RSA_METHOD *meth) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) + { + RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD); + return; + } +#endif default_RSA_meth = meth; } @@ -111,6 +118,13 @@ int RSA_set_method(RSA *rsa, const RSA_M /* NB: The caller is specifically setting a method, so it's not up to us * to deal with which ENGINE it comes from. */ const RSA_METHOD *mtmp; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) + { + RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_METHOD); + return 0; + } +#endif mtmp = rsa->meth; if (mtmp->finish) mtmp->finish(rsa); #ifndef OPENSSL_NO_ENGINE @@ -163,6 +177,18 @@ RSA *RSA_new_method(ENGINE *engine) } } #endif +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD)) + { + RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD); +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return NULL; + } +#endif ret->pad=0; ret->version=0; @@ -294,6 +320,13 @@ int RSA_public_encrypt(int flen, const u int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { + RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); } @@ -306,6 +339,13 @@ int RSA_private_decrypt(int flen, const int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { +#ifdef OPENSSL_FIPS + if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { + RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return 0; + } +#endif return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); } diff -up openssl-1.0.0k/crypto/rsa/rsa_sign.c.fips openssl-1.0.0k/crypto/rsa/rsa_sign.c --- openssl-1.0.0k/crypto/rsa/rsa_sign.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/rsa/rsa_sign.c 2013-02-19 20:12:54.603665028 +0100 @@ -130,7 +130,8 @@ int RSA_sign(int type, const unsigned ch i2d_X509_SIG(&sig,&p); s=tmps; } - i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING); + /* NB: call underlying method directly to avoid FIPS blocking */ + i = rsa->meth->rsa_priv_enc ? rsa->meth->rsa_priv_enc(i,s,sigret,rsa,RSA_PKCS1_PADDING) : 0; if (i <= 0) ret=0; else @@ -161,8 +162,8 @@ int int_rsa_verify(int dtype, const unsi if((dtype == NID_md5_sha1) && rm) { - i = RSA_public_decrypt((int)siglen, - sigbuf,rm,rsa,RSA_PKCS1_PADDING); + i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen, + sigbuf,rm,rsa,RSA_PKCS1_PADDING) : 0; if (i <= 0) return 0; *prm_len = i; @@ -179,7 +180,8 @@ int int_rsa_verify(int dtype, const unsi RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; } - i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); + /* NB: call underlying method directly to avoid FIPS blocking */ + i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING) : 0; if (i <= 0) goto err; diff -up openssl-1.0.0k/crypto/seed/seed.c.fips openssl-1.0.0k/crypto/seed/seed.c --- openssl-1.0.0k/crypto/seed/seed.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/seed/seed.c 2013-02-19 20:12:54.603665028 +0100 @@ -34,6 +34,9 @@ #include #include "seed_locl.h" +#ifdef OPENSSL_FIPS +#include +#endif static const seed_word SS[4][256] = { { 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124, @@ -193,7 +196,18 @@ static const seed_word KC[] = { KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15 }; #endif +#ifdef OPENSSL_FIPS +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks) + { + if (FIPS_mode()) + FIPS_BAD_ABORT(SEED) + private_SEED_set_key(rawkey, ks); + } + +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks) +#else void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks) +#endif { seed_word x1, x2, x3, x4; seed_word t0, t1; diff -up openssl-1.0.0k/crypto/seed/seed.h.fips openssl-1.0.0k/crypto/seed/seed.h --- openssl-1.0.0k/crypto/seed/seed.h.fips 2013-02-19 20:12:54.022654004 +0100 +++ openssl-1.0.0k/crypto/seed/seed.h 2013-02-19 20:12:54.603665028 +0100 @@ -117,6 +117,9 @@ typedef struct seed_key_st { } SEED_KEY_SCHEDULE; +#ifdef OPENSSL_FIPS +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks); +#endif void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], SEED_KEY_SCHEDULE *ks); void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], unsigned char d[SEED_BLOCK_SIZE], const SEED_KEY_SCHEDULE *ks); diff -up openssl-1.0.0k/crypto/sha/sha1dgst.c.fips openssl-1.0.0k/crypto/sha/sha1dgst.c --- openssl-1.0.0k/crypto/sha/sha1dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/sha/sha1dgst.c 2013-02-19 20:12:54.604665047 +0100 @@ -63,6 +63,10 @@ #define SHA_1 #include +#ifdef OPENSSL_FIPS +#include +#endif + const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT; diff -up openssl-1.0.0k/crypto/sha/sha256.c.fips openssl-1.0.0k/crypto/sha/sha256.c --- openssl-1.0.0k/crypto/sha/sha256.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/sha/sha256.c 2013-02-19 20:12:54.604665047 +0100 @@ -12,12 +12,19 @@ #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #include const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; int SHA224_Init (SHA256_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif memset (c,0,sizeof(*c)); c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; @@ -29,6 +36,9 @@ int SHA224_Init (SHA256_CTX *c) int SHA256_Init (SHA256_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif memset (c,0,sizeof(*c)); c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; diff -up openssl-1.0.0k/crypto/sha/sha512.c.fips openssl-1.0.0k/crypto/sha/sha512.c --- openssl-1.0.0k/crypto/sha/sha512.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/sha/sha512.c 2013-02-19 20:12:54.604665047 +0100 @@ -5,6 +5,10 @@ * ==================================================================== */ #include +#ifdef OPENSSL_FIPS +#include +#endif + #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) /* * IMPLEMENTATION NOTES. @@ -61,6 +65,9 @@ const char SHA512_version[]="SHA-512" OP int SHA384_Init (SHA512_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif #if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) /* maintain dword order required by assembler module */ unsigned int *h = (unsigned int *)c->h; @@ -90,6 +97,9 @@ int SHA384_Init (SHA512_CTX *c) int SHA512_Init (SHA512_CTX *c) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif #if defined(SHA512_ASM) && (defined(__arm__) || defined(__arm)) /* maintain dword order required by assembler module */ unsigned int *h = (unsigned int *)c->h; diff -up openssl-1.0.0k/crypto/sha/sha_dgst.c.fips openssl-1.0.0k/crypto/sha/sha_dgst.c --- openssl-1.0.0k/crypto/sha/sha_dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/sha/sha_dgst.c 2013-02-19 20:12:54.603665028 +0100 @@ -57,6 +57,12 @@ */ #include +#include +#ifdef OPENSSL_FIPS +#include +#endif + +#include #if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA) #undef SHA_1 diff -up openssl-1.0.0k/crypto/sha/sha.h.fips openssl-1.0.0k/crypto/sha/sha.h --- openssl-1.0.0k/crypto/sha/sha.h.fips 2013-02-19 20:12:53.892651535 +0100 +++ openssl-1.0.0k/crypto/sha/sha.h 2013-02-19 20:12:54.603665028 +0100 @@ -106,6 +106,9 @@ typedef struct SHAstate_st } SHA_CTX; #ifndef OPENSSL_NO_SHA0 +#ifdef OPENSSL_FIPS +int private_SHA_Init(SHA_CTX *c); +#endif int SHA_Init(SHA_CTX *c); int SHA_Update(SHA_CTX *c, const void *data, size_t len); int SHA_Final(unsigned char *md, SHA_CTX *c); diff -up openssl-1.0.0k/crypto/sha/sha_locl.h.fips openssl-1.0.0k/crypto/sha/sha_locl.h --- openssl-1.0.0k/crypto/sha/sha_locl.h.fips 2013-02-19 20:12:53.897651631 +0100 +++ openssl-1.0.0k/crypto/sha/sha_locl.h 2013-02-19 20:12:54.603665028 +0100 @@ -122,8 +122,15 @@ void sha1_block_data_order (SHA_CTX *c, #define INIT_DATA_h3 0x10325476UL #define INIT_DATA_h4 0xc3d2e1f0UL +#if defined(SHA_0) && defined(OPENSSL_FIPS) +FIPS_NON_FIPS_MD_Init(SHA) +#else int HASH_INIT (SHA_CTX *c) +#endif { +#if defined(SHA_1) && defined(OPENSSL_FIPS) + FIPS_selftest_check(); +#endif memset (c,0,sizeof(*c)); c->h0=INIT_DATA_h0; c->h1=INIT_DATA_h1; diff -up openssl-1.0.0k/crypto/whrlpool/whrlpool.h.fips openssl-1.0.0k/crypto/whrlpool/whrlpool.h --- openssl-1.0.0k/crypto/whrlpool/whrlpool.h.fips 2013-02-19 20:12:54.187657134 +0100 +++ openssl-1.0.0k/crypto/whrlpool/whrlpool.h 2013-02-19 20:12:54.604665047 +0100 @@ -24,6 +24,9 @@ typedef struct { } WHIRLPOOL_CTX; #ifndef OPENSSL_NO_WHIRLPOOL +#ifdef OPENSSL_FIPS +int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +#endif int WHIRLPOOL_Init (WHIRLPOOL_CTX *c); int WHIRLPOOL_Update (WHIRLPOOL_CTX *c,const void *inp,size_t bytes); void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *inp,size_t bits); diff -up openssl-1.0.0k/crypto/whrlpool/wp_dgst.c.fips openssl-1.0.0k/crypto/whrlpool/wp_dgst.c --- openssl-1.0.0k/crypto/whrlpool/wp_dgst.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/crypto/whrlpool/wp_dgst.c 2013-02-19 20:12:54.604665047 +0100 @@ -53,8 +53,12 @@ #include "wp_locl.h" #include +#include +#ifdef OPENSSL_FIPS +#include +#endif -int WHIRLPOOL_Init (WHIRLPOOL_CTX *c) +FIPS_NON_FIPS_MD_Init(WHIRLPOOL) { memset (c,0,sizeof(*c)); return(1); diff -up openssl-1.0.0k/Makefile.org.fips openssl-1.0.0k/Makefile.org --- openssl-1.0.0k/Makefile.org.fips 2013-02-19 20:12:54.544663908 +0100 +++ openssl-1.0.0k/Makefile.org 2013-02-19 20:12:54.604665047 +0100 @@ -110,6 +110,9 @@ LIBKRB5= ZLIB_INCLUDE= LIBZLIB= +# Non-empty if FIPS enabled +FIPS= + DIRS= crypto ssl engines apps test tools ENGDIRS= ccgost SHLIBDIRS= crypto ssl @@ -122,7 +125,7 @@ SDIRS= \ bn ec rsa dsa ecdsa dh ecdh dso engine \ buffer bio stack lhash rand err \ evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ - cms pqueue ts jpake store + cms pqueue ts jpake store fips # keep in mind that the above list is adjusted by ./Configure # according to no-xxx arguments... @@ -206,6 +209,7 @@ BUILDENV= PLATFORM='$(PLATFORM)' PROCESS RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)' \ WP_ASM_OBJ='$(WP_ASM_OBJ)' \ PERLASM_SCHEME='$(PERLASM_SCHEME)' \ + FIPS="$${FIPS:-$(FIPS)}" \ THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES= # MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors, # which in turn eliminates ambiguities in variable treatment with -e. diff -up openssl-1.0.0k/ssl/s23_clnt.c.fips openssl-1.0.0k/ssl/s23_clnt.c --- openssl-1.0.0k/ssl/s23_clnt.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/s23_clnt.c 2013-02-19 20:12:54.607665104 +0100 @@ -334,6 +334,14 @@ static int ssl23_client_hello(SSL *s) version_major = TLS1_VERSION_MAJOR; version_minor = TLS1_VERSION_MINOR; } +#ifdef OPENSSL_FIPS + else if(FIPS_mode()) + { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif else if (version == SSL3_VERSION) { version_major = SSL3_VERSION_MAJOR; @@ -617,6 +625,14 @@ static int ssl23_get_server_hello(SSL *s if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { +#ifdef OPENSSL_FIPS + if(FIPS_mode()) + { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +#endif s->version=SSL3_VERSION; s->method=SSLv3_client_method(); } diff -up openssl-1.0.0k/ssl/s23_srvr.c.fips openssl-1.0.0k/ssl/s23_srvr.c --- openssl-1.0.0k/ssl/s23_srvr.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/s23_srvr.c 2013-02-19 20:12:54.607665104 +0100 @@ -393,6 +393,15 @@ int ssl23_get_client_hello(SSL *s) } } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (s->version < TLS1_VERSION)) + { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +#endif + if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { /* we have SSLv3/TLSv1 in an SSLv2 header diff -up openssl-1.0.0k/ssl/s3_clnt.c.fips openssl-1.0.0k/ssl/s3_clnt.c --- openssl-1.0.0k/ssl/s3_clnt.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/s3_clnt.c 2013-02-19 20:12:54.608665123 +0100 @@ -156,6 +156,10 @@ #include #include #include +#ifdef OPENSSL_FIPS +#include +#endif + #ifndef OPENSSL_NO_DH #include #endif @@ -1559,6 +1563,8 @@ int ssl3_get_key_exchange(SSL *s) q=md_buf; for (num=2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); diff -up openssl-1.0.0k/ssl/s3_enc.c.fips openssl-1.0.0k/ssl/s3_enc.c --- openssl-1.0.0k/ssl/s3_enc.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/s3_enc.c 2013-02-19 20:12:54.609665142 +0100 @@ -170,6 +170,7 @@ static int ssl3_generate_key_block(SSL * #endif k=0; EVP_MD_CTX_init(&m5); + EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_MD_CTX_init(&s1); for (i=0; (int)is3->tmp.new_cipher->algorithm2) && md) { s->s3->handshake_dgst[i]=EVP_MD_CTX_create(); + EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(s->s3->handshake_dgst[i],md,NULL); EVP_DigestUpdate(s->s3->handshake_dgst[i],hdata,hdatalen); } @@ -665,6 +668,7 @@ static int ssl3_handshake_mac(SSL *s, in return 0; } EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_MD_CTX_copy_ex(&ctx,d); n=EVP_MD_CTX_size(&ctx); if (n < 0) diff -up openssl-1.0.0k/ssl/s3_srvr.c.fips openssl-1.0.0k/ssl/s3_srvr.c --- openssl-1.0.0k/ssl/s3_srvr.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/s3_srvr.c 2013-02-19 20:12:54.609665142 +0100 @@ -1779,6 +1779,8 @@ int ssl3_send_server_key_exchange(SSL *s j=0; for (num=2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); EVP_DigestInit_ex(&md_ctx,(num == 2) ?s->ctx->md5:s->ctx->sha1, NULL); EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); diff -up openssl-1.0.0k/ssl/ssl_ciph.c.fips openssl-1.0.0k/ssl/ssl_ciph.c --- openssl-1.0.0k/ssl/ssl_ciph.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/ssl_ciph.c 2013-02-19 20:12:54.605665066 +0100 @@ -728,6 +728,9 @@ static void ssl_cipher_collect_ciphers(c !(c->algorithm_auth & disabled_auth) && !(c->algorithm_enc & disabled_enc) && !(c->algorithm_mac & disabled_mac) && +#ifdef OPENSSL_FIPS + (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) && +#endif !(c->algorithm_ssl & disabled_ssl)) { co_list[co_list_num].cipher = c; @@ -1423,7 +1426,11 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_ */ for (curr = head; curr != NULL; curr = curr->next) { +#ifdef OPENSSL_FIPS + if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) +#else if (curr->active) +#endif { sk_SSL_CIPHER_push(cipherstack, curr->cipher); #ifdef CIPHER_DEBUG diff -up openssl-1.0.0k/ssl/ssl_lib.c.fips openssl-1.0.0k/ssl/ssl_lib.c --- openssl-1.0.0k/ssl/ssl_lib.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/ssl_lib.c 2013-02-19 20:12:54.605665066 +0100 @@ -1526,6 +1526,14 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m return(NULL); } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (meth->version < TLS1_VERSION)) + { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return NULL; + } +#endif + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); diff -up openssl-1.0.0k/ssl/ssltest.c.fips openssl-1.0.0k/ssl/ssltest.c --- openssl-1.0.0k/ssl/ssltest.c.fips 2013-02-19 20:12:54.542663869 +0100 +++ openssl-1.0.0k/ssl/ssltest.c 2013-02-19 20:12:54.606665085 +0100 @@ -268,6 +268,9 @@ static void sv_usage(void) { fprintf(stderr,"usage: ssltest [args ...]\n"); fprintf(stderr,"\n"); +#ifdef OPENSSL_FIPS + fprintf(stderr,"-F - run test in FIPS mode\n"); +#endif fprintf(stderr," -server_auth - check server certificate\n"); fprintf(stderr," -client_auth - do client authentication\n"); fprintf(stderr," -proxy - allow proxy certificates\n"); @@ -487,6 +490,9 @@ int main(int argc, char *argv[]) #endif STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; int test_cipherlist = 0; +#ifdef OPENSSL_FIPS + int fips_mode=0; +#endif verbose = 0; debug = 0; @@ -518,7 +524,16 @@ int main(int argc, char *argv[]) while (argc >= 1) { - if (strcmp(*argv,"-server_auth") == 0) + if(!strcmp(*argv,"-F")) + { +#ifdef OPENSSL_FIPS + fips_mode=1; +#else + fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n"); + EXIT(0); +#endif + } + else if (strcmp(*argv,"-server_auth") == 0) server_auth=1; else if (strcmp(*argv,"-client_auth") == 0) client_auth=1; @@ -714,6 +729,20 @@ bad: EXIT(1); } +#ifdef OPENSSL_FIPS + if(fips_mode) + { + if(!FIPS_mode_set(1)) + { + ERR_load_crypto_strings(); + ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); + EXIT(1); + } + else + fprintf(stderr,"*** IN FIPS MODE ***\n"); + } +#endif + if (print_time) { if (!bio_pair) @@ -2153,12 +2182,12 @@ static int MS_CALLBACK app_verify_callba } #ifndef OPENSSL_NO_X509_VERIFY -# ifdef OPENSSL_FIPS +# if 0 if(s->version == TLS1_VERSION) FIPS_allow_md5(1); # endif ok = X509_verify_cert(ctx); -# ifdef OPENSSL_FIPS +# if 0 if(s->version == TLS1_VERSION) FIPS_allow_md5(0); # endif diff -up openssl-1.0.0k/ssl/t1_enc.c.fips openssl-1.0.0k/ssl/t1_enc.c --- openssl-1.0.0k/ssl/t1_enc.c.fips 2013-02-05 12:58:46.000000000 +0100 +++ openssl-1.0.0k/ssl/t1_enc.c 2013-02-19 20:12:54.610665161 +0100 @@ -170,6 +170,8 @@ static int tls1_P_hash(const EVP_MD *md, HMAC_CTX_init(&ctx); HMAC_CTX_init(&ctx_tmp); + HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); if (!HMAC_Init_ex(&ctx,sec,sec_len,md, NULL)) goto err; if (!HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL))