RSA *rsa=NULL;
int i,num=DEFBITS;
long l;
+#ifdef OPENSSL_FIPS
+ int use_x931 = 0;
+#endif
const EVP_CIPHER *enc=NULL;
unsigned long f4=RSA_F4;
char *outfile=NULL;
f4=3;
else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0)
f4=RSA_F4;
+#ifdef OPENSSL_FIPS
+ else if (strcmp(*argv,"-x931") == 0)
+ use_x931 = 1;
+#endif
#ifndef OPENSSL_NO_ENGINE
else if (strcmp(*argv,"-engine") == 0)
{
BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
num);
- rsa=RSA_generate_key(num,f4,genrsa_cb,bio_err);
+#ifdef OPENSSL_FIPS
+ if (use_x931)
+ {
+ BIGNUM *pubexp;
+ pubexp = BN_new();
+ BN_set_word(pubexp, f4);
+ rsa = RSA_X931_generate_key(num, pubexp, genrsa_cb, bio_err);
+ BN_free(pubexp);
+ }
+ else
+#endif
+ rsa=RSA_generate_key(num,f4,genrsa_cb,bio_err);
app_RAND_write_file(NULL, bio_err);
- if (rsa == NULL) goto err;
+ if (rsa == NULL)
+ {
+ BIO_printf(bio_err, "Key Generation error\n");
+
+ goto err;
+ }
/* We need to do the following for when the base number size is <
* long, esp windows 3.1 :-(. */
LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
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_recp.c bn_mont.c bn_mpi.c bn_exp2.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_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_x931p.o
SRC= $(LIBSRC)
void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
int do_trial_division);
+#ifdef OPENSSL_FIPS
+int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ void (*cb)(int, int, void *), void *cb_arg,
+ const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
+ const BIGNUM *e, BN_CTX *ctx);
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
+int BN_X931_generate_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ BIGNUM *Xp1, BIGNUM *Xp2,
+ const BIGNUM *Xp,
+ const BIGNUM *e, BN_CTX *ctx,
+ void (*cb)(int, int, void *), void *cb_arg);
+#endif
+
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,
--- /dev/null
+/* bn_x931p.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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 <stdio.h>
+#include <openssl/bn.h>
+
+/* 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,
+ void (*cb)(int, int, void *), void *cb_arg)
+ {
+ int i = 0;
+ if (!BN_copy(pi, Xpi))
+ return 0;
+ if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
+ return 0;
+ for(;;)
+ {
+ i++;
+ if (cb)
+ cb(0, i, cb_arg);
+ /* NB 27 MR is specificed in X9.31 */
+ if (BN_is_prime_fasttest(pi, 27, cb, ctx, cb_arg, 1))
+ break;
+ if (!BN_add_word(pi, 2))
+ return 0;
+ }
+ if (cb)
+ cb(2, i, cb_arg);
+ 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(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ void (*cb)(int, int, void *), void *cb_arg,
+ const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
+ const BIGNUM *e, BN_CTX *ctx)
+ {
+ 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, cb_arg))
+ goto err;
+
+ if (!bn_x931_derive_pi(p2, Xp2, ctx, cb, cb_arg))
+ 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;
+ if (cb)
+ cb(0, i++, cb_arg);
+ 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(p, 50, cb, ctx, cb_arg, 1))
+ break;
+ if (!BN_add(p, p, p1p2))
+ goto err;
+ }
+
+ if (cb)
+ cb(3, 0, cb_arg);
+
+ 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(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ BIGNUM *Xp1, BIGNUM *Xp2,
+ const BIGNUM *Xp,
+ const BIGNUM *e, BN_CTX *ctx,
+ void (*cb)(int, int, void *), void *cb_arg)
+ {
+ 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(p, p1, p2, cb, cb_arg,
+ Xp, Xp1, Xp2, e, ctx))
+ goto error;
+
+ ret = 1;
+
+ error:
+ BN_CTX_end(ctx);
+
+ return ret;
+
+ }
+
RSA * RSA_generate_key(int bits, unsigned long e,void
(*callback)(int,int,void *),void *cb_arg);
int RSA_check_key(const RSA *);
+#ifndef FIPS
+int RSA_X931_derive(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
+ void (*cb)(int, int, void *), void *cb_arg,
+ const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
+ const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
+ const BIGNUM *e);
+RSA *RSA_X931_generate_key(int bits, const BIGNUM *e,
+ void (*cb)(int,int,void *), void *cb_arg);
+#endif
/* next 4 return -1 on error */
int RSA_public_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
#define FIPS_F_HASH_FINAL 100
#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT 114
#define FIPS_F_RSA_GENERATE_KEY 113
+#define FIPS_F_RSA_X931_GENERATE_KEY 119
#define FIPS_F_SSLEAY_RAND_BYTES 101
/* Reason codes. */
#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH 105
#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_SELFTEST_FAILED 101
-#define FIPS_R_KEY_TOO_SHORT 108
#ifdef __cplusplus
}
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RNG), "FIPS_selftest_rng"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RSA), "FIPS_selftest_rsa"},
-{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA), "FIPS_selftest_sha"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA), "FIPS_SELFTEST_SHA"},
{ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"},
{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"},
{ERR_FUNC(FIPS_F_RSA_GENERATE_KEY), "RSA_generate_key"},
+{ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY), "RSA_X931_generate_key"},
{ERR_FUNC(FIPS_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
{0,NULL}
};
{ERR_REASON(FIPS_R_EXE_DIGEST_DOES_NOT_MATCH),"exe digest does not match"},
{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_SELFTEST_FAILED) ,"selftest failed"},
void ERR_load_FIPS_strings(void)
{
- static int init;
+ static int init=1;
- if (!init)
+ if (init)
{
- init=1;
+ init=0;
#ifndef OPENSSL_NO_ERR
ERR_load_strings(0,FIPS_str_functs);
ERR_load_strings(0,FIPS_str_reasons);
const char * const FIPS_source_hashes[] = {
"HMAC-SHA1(fips.c)= 7cbbda3b9e8aec46ee31797179cb72faeef80712",
"HMAC-SHA1(fips_err_wrapper.c)= d3e2be316062510312269e98f964cb87e7577898",
-"HMAC-SHA1(fips.h)= e85fdc2fe6ad2dbf0662691e87af4b6b240da62e",
-"HMAC-SHA1(fips_err.h)= 0b2bd6999ee5792fec3739689cde5f352789e63a",
+"HMAC-SHA1(fips.h)= 9e8d77f438eabc36273e2046aa209e6e78515103",
+"HMAC-SHA1(fips_err.h)= fec567f1abe0f8d53a208b7f24b992dda2db3e4d",
"HMAC-SHA1(aes/fips_aes_core.c)= b70bbbd675efe0613da0d57055310926a0104d55",
"HMAC-SHA1(aes/asm/fips-ax86-elf.s)= f797b524a79196e7f59458a5b223432fcfd4a868",
"HMAC-SHA1(aes/fips_aes_selftest.c)= 98b01502221e7fe529fd981222f2cbb52eb4cbe0",
"HMAC-SHA1(rand/fips_rand.h)= bf009ea8963e79b1e414442ede9ae7010a03160b",
"HMAC-SHA1(rand/fips_rand_selftest.c)= d9c8985e08feecefafe667ad0119d444b42f807c",
"HMAC-SHA1(rsa/fips_rsa_eay.c)= 2512f849a220daa083f346b10effdb2ee96d4395",
-"HMAC-SHA1(rsa/fips_rsa_gen.c)= af83b857d2be13d59e7f1516e6b1a25edd6369c3",
+"HMAC-SHA1(rsa/fips_rsa_gen.c)= 577466931c054d99caf4ac2aefff0e35efd94024",
"HMAC-SHA1(rsa/fips_rsa_selftest.c)= a9dc47bd1001f795d1565111d26433c300101e06",
+"HMAC-SHA1(rsa/fips_rsa_x931g.c)= 62ecb2622cf61010561d5800ba2c74f54a3d2526",
"HMAC-SHA1(sha/fips_sha1dgst.c)= 26e529d630b5e754b4a29bd1bb697e991e7fdc04",
"HMAC-SHA1(sha/fips_standalone_sha1.c)= faae95bc36cc80f5be6a0cde02ebab0f63d4fd97",
"HMAC-SHA1(sha/fips_sha1_selftest.c)= a08f9c1e2c0f63b9aa96b927c0333a03b020749f",
CFLAGS= $(INCLUDES) $(CFLAG)
GENERAL=Makefile
-TEST= fips_rsavtest.c fips_rsastest.c
+TEST= fips_rsavtest.c fips_rsastest.c fips_rsagtest.c
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_rsa_eay.c fips_rsa_gen.c fips_rsa_selftest.c
-LIBOBJ=fips_rsa_eay.o fips_rsa_gen.o fips_rsa_selftest.o
+LIBSRC=fips_rsa_eay.c fips_rsa_gen.c fips_rsa_selftest.c fips_rsa_x931g.c
+LIBOBJ=fips_rsa_eay.o fips_rsa_gen.o fips_rsa_selftest.o fips_rsa_x931g.o
SRC= $(LIBSRC)
top_fips_rsavtest:
(cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) TARGET=fips_rsavtest sub_target)
+top_fips_rsagtest:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) TARGET=fips_rsagtest sub_target)
+
fips_rsastest: fips_rsastest.o $(TOP)/libcrypto.a
$(CC) $(CFLAGS) -o fips_rsastest fips_rsastest.o $(PEX_LIBS) $(TOP)/libcrypto.a $(EX_LIBS)
TOP=$(TOP) $(TOP)/fips/openssl_fips_fingerprint $(TOP)/libcrypto.a fips_rsastest
$(CC) $(CFLAGS) -o fips_rsavtest fips_rsavtest.o $(PEX_LIBS) $(TOP)/libcrypto.a $(EX_LIBS)
TOP=$(TOP) $(TOP)/fips/openssl_fips_fingerprint $(TOP)/libcrypto.a fips_rsavtest
+fips_rsagtest: fips_rsagtest.o $(TOP)/libcrypto.a
+ $(CC) $(CFLAGS) -o fips_rsagtest fips_rsagtest.o $(PEX_LIBS) $(TOP)/libcrypto.a $(EX_LIBS)
+ TOP=$(TOP) $(TOP)/fips/openssl_fips_fingerprint $(TOP)/libcrypto.a fips_rsagtest
+
Q=../testvectors/rsa/req
A=../testvectors/rsa/rsp
-fips_test: top top_fips_rsastest top_fips_rsavtest
+fips_test: top top_fips_rsastest top_fips_rsavtest top_fips_rsagtest
-rm -rf $(A)
mkdir $(A)
./fips_rsastest < $(Q)/SigGen15.req > $(A)/SigGen15.rsp
#ifdef OPENSSL_FIPS
-static int fips_check_rsa(RSA *rsa)
+int fips_check_rsa(RSA *rsa)
{
int n, ret = 0;
unsigned char tctext[256], *ctext = tctext;
--- /dev/null
+/* 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 <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/fips.h>
+
+extern int fips_check_rsa(RSA *rsa);
+
+
+/* X9.31 RSA key derivation and generation */
+
+int RSA_X931_derive(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
+ void (*cb)(int, int, void *), void *cb_arg,
+ const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
+ const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
+ const BIGNUM *e)
+ {
+ BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL;
+ BN_CTX *ctx=NULL,*ctx2=NULL;
+
+ if (!rsa)
+ goto err;
+
+ ctx = BN_CTX_new();
+ BN_CTX_start(ctx);
+ if (!ctx)
+ goto err;
+
+ 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(rsa->p, p1, p2, cb, cb_arg,
+ Xp, Xp1, Xp2, e, ctx))
+ goto err;
+ }
+
+ if (Xq && !rsa->q)
+ {
+ rsa->q = BN_new();
+ if (!rsa->q)
+ goto err;
+ if (!BN_X931_derive_prime(rsa->q, q1, q2, cb, cb_arg,
+ Xq, Xq1, Xq2, e, ctx))
+ 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->iqmp != NULL)
+ return 1;
+
+ return 0;
+
+ }
+
+RSA *RSA_X931_generate_key(FIPS_RSA_SIZE_T bits, const BIGNUM *e,
+ void (*cb)(int,int,void *), void *cb_arg)
+ {
+ RSA *rsa = NULL;
+ int ok = 0;
+ BIGNUM *Xp = NULL, *Xq = NULL;
+ BN_CTX *ctx = NULL;
+
+ if (bits < 1024)
+ {
+ FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY,FIPS_R_KEY_TOO_SHORT);
+ return NULL;
+ }
+
+ if (bits & 0xff)
+ {
+ FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY,FIPS_R_INVALID_KEY_LENGTH);
+ return NULL;
+ }
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY,FIPS_R_FIPS_SELFTEST_FAILED);
+ return NULL;
+ }
+
+ 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 = RSA_new();
+ if (!rsa)
+ 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(rsa->p, NULL, NULL, NULL, NULL, Xp,
+ e, ctx, cb, cb_arg))
+ goto error;
+
+ if (!BN_X931_generate_prime(rsa->q, NULL, NULL, NULL, NULL, Xq,
+ e, ctx, cb, cb_arg))
+ goto error;
+
+ /* Since rsa->p and rsa->q are valid this call will just derive
+ * remaining RSA components.
+ */
+
+ if (!RSA_X931_derive(rsa, NULL, NULL, NULL, NULL, cb, cb_arg,
+ NULL, NULL, NULL, NULL, NULL, NULL, e))
+ goto error;
+
+ if(!fips_check_rsa(rsa))
+ goto error;
+
+ ok = 1;
+
+ error:
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ if (ok)
+ return rsa;
+
+ if (rsa)
+ RSA_free(rsa);
+
+ return NULL;
+
+ }
+
--- /dev/null
+/* fips_rsagtest.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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 <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS RSA support\n");
+ return(0);
+}
+
+#else
+
+extern int RSA_X931_derive(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
+ void (*cb)(int, int, void *), void *cb_arg,
+ const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
+ const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
+ const BIGNUM *e);
+
+int rsa_test(BIO *err, BIO *out, BIO *in);
+static int rsa_printkey1(BIO *err, BIO *out, RSA *rsa,
+ BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
+ BIGNUM *e);
+static int rsa_printkey2(BIO *err, BIO *out, RSA *rsa,
+ BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq);
+
+int main(int argc, char **argv)
+ {
+ BIO *in = NULL, *out = NULL, *err = NULL;
+
+ int ret = 1;
+ ERR_load_crypto_strings();
+
+ err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ if (!err)
+ {
+ fprintf(stderr, "FATAL stderr initialization error\n");
+ goto end;
+ }
+
+ if(!FIPS_mode_set(1,argv[0]))
+ {
+ ERR_print_errors(err);
+ goto end;
+ }
+
+ if (argc == 1)
+ in = BIO_new_fp(stdin, BIO_NOCLOSE);
+ else
+ in = BIO_new_file(argv[1], "r");
+
+ if (argc < 2)
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ else
+ out = BIO_new_file(argv[2], "w");
+
+ if (!in)
+ {
+ BIO_printf(err, "FATAL input initialization error\n");
+ goto end;
+ }
+
+ if (!out)
+ {
+ fprintf(stderr, "FATAL output initialization error\n");
+ goto end;
+ }
+
+ if (!rsa_test(err, out, in))
+ {
+ fprintf(stderr, "FATAL RSAVTEST file processing error\n");
+ goto end;
+ }
+ else
+ ret = 0;
+
+ end:
+
+ if (ret && err)
+ ERR_print_errors(err);
+
+ if (in)
+ BIO_free(in);
+ if (out)
+ BIO_free(out);
+ if (err)
+ BIO_free(err);
+
+ return ret;
+
+ }
+
+
+static void do_bn_print(BIO *out, const char *name, BIGNUM *b)
+ {
+ char *htmp, *p;
+ /* Can't use BN_print_fp because it uses upper case so
+ * use BN_bn2hex() and convert.
+ */
+ htmp = BN_bn2hex(b);
+ for(p = htmp; *p; p++)
+ {
+ if (isupper(*p))
+ *p = tolower(*p);
+ }
+ BIO_printf(out, "%s = %s\n", name, htmp);
+ OPENSSL_free(htmp);
+ }
+
+#define RSA_TEST_MAXLINELEN 10240
+
+int rsa_test(BIO *err, BIO *out, BIO *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 (BIO_gets(in, olinebuf, RSA_TEST_MAXLINELEN) > 0)
+ {
+ 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 (!BIO_puts(out, olinebuf))
+ goto error;
+ continue;
+ }
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 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 || !BN_hex2bn(&Xp1,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "xp2"))
+ {
+ if (Xp2 || !BN_hex2bn(&Xp2,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Xp"))
+ {
+ if (Xp || !BN_hex2bn(&Xp,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "xq1"))
+ {
+ if (Xq1 || !BN_hex2bn(&Xq1,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "xq2"))
+ {
+ if (Xq2 || !BN_hex2bn(&Xq2,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Xq"))
+ {
+ if (Xq || !BN_hex2bn(&Xq,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "e"))
+ {
+ if (e || !BN_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;
+
+ BIO_puts(out, olinebuf);
+
+ if (e && Xp1 && Xp2 && Xp)
+ {
+ rsa = RSA_new();
+ if (!rsa)
+ goto error;
+ if (!rsa_printkey1(err, 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(err, out, rsa, Xq1, Xq2, Xq))
+ goto error;
+ BN_free(Xq1);
+ Xq1 = NULL;
+ BN_free(Xq2);
+ Xq2 = NULL;
+ BN_free(Xq);
+ Xq = NULL;
+ 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)
+ RSA_free(rsa);
+
+ return ret;
+
+ parse_error:
+
+ BIO_printf(err, "FATAL parse error processing line %d\n", lnum);
+
+ goto error;
+
+ }
+
+static int rsa_printkey1(BIO *err, BIO *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(rsa, p1, p2, NULL, NULL, 0, NULL, Xp1, Xp2, Xp,
+ NULL, NULL, NULL, e))
+ goto error;
+
+ do_bn_print(out, "p1", p1);
+ do_bn_print(out, "p2", p2);
+ do_bn_print(out, "p", rsa->p);
+
+ ret = 1;
+
+ error:
+ if (p1)
+ BN_free(p1);
+ if (p2)
+ BN_free(p2);
+
+ return ret;
+ }
+
+static int rsa_printkey2(BIO *err, BIO *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(rsa, NULL, NULL, q1, q2, 0, NULL, NULL, NULL, NULL,
+ Xq1, Xq2, Xq, NULL))
+ goto error;
+
+ do_bn_print(out, "q1", q1);
+ do_bn_print(out, "q2", q2);
+ do_bn_print(out, "q", rsa->q);
+ do_bn_print(out, "n", rsa->n);
+ do_bn_print(out, "d", rsa->d);
+
+ ret = 1;
+
+ error:
+ if (q1)
+ BN_free(q1);
+ if (q2)
+ BN_free(q2);
+
+ return ret;
+ }
+
+#endif
FIPS_HMACTEST= fips_hmactest
FIPS_RSAVTEST= fips_rsavtest
FIPS_RSASTEST= fips_rsastest
+FIPS_RSAGTEST= fips_rsagtest
TESTS= alltests
$(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) $(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(FIPS_DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \
$(EVPTEST)$(EXE_EXT) $(FIPS_AESTEST)$(EXE_EXT) \
$(FIPS_HMACTEST)$(EXE_EXT) $(FIPS_RSAVTEST)$(EXE_EXT) \
- $(FIPS_RSASTEST)$(EXE_EXT)
+ $(FIPS_RSASTEST)$(EXE_EXT) $(FIPS_RSAGTEST)$(EXE_EXT)
# $(METHTEST)$(EXE_EXT)
$(RANDTEST).o $(FIPS_RANDTEST).o $(DHTEST).o $(ENGINETEST).o $(CASTTEST).o \
$(BFTEST).o $(SSLTEST).o $(DSATEST).o $(FIPS_DSATEST).o $(EXPTEST).o $(RSATEST).o \
$(EVPTEST).o $(FIPS_AESTEST).o $(FIPS_HMACTEST).o $(FIPS_RSAVTEST).o \
- $(FIPS_RSASTEST).o
+ $(FIPS_RSASTEST).o $(FIPS_RSAGTEST).o
SRC= $(BNTEST).c $(ECTEST).c $(IDEATEST).c $(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \
$(HMACTEST).c \
$(RC2TEST).c $(RC4TEST).c $(RC5TEST).c \
$(RANDTEST).c $(FIPS_RANDTEST).c $(DHTEST).c $(ENGINETEST).c $(CASTTEST).c \
$(BFTEST).c $(SSLTEST).c $(DSATEST).c $(FIPS_DSATEST).c $(EXPTEST).c $(RSATEST).c \
$(EVPTEST).c $(FIPS_AESTEST).c $(FIPS_HMACTEST).c $(FIPS_RSAVTEST).c \
- $(FIPS_RSASTEST).c
+ $(FIPS_RSASTEST).c $(FIPS_RSAGTEST).c
EXHEADER=
HEADER= $(EXHEADER)
TOP=$(TOP) $(TOP)/fips/openssl_fips_fingerprint $(TOP)/libcrypto.a $(FIPS_RSASTEST); \
fi
+$(FIPS_RSAGTEST)$(EXE_EXT): $(FIPS_RSAGTEST).o $(DLIBCRYPTO)
+ @target=$(FIPS_RSAGTEST); $(BUILD_CMD)
+ if egrep 'define OPENSSL_FIPS' $(TOP)/include/openssl/opensslconf.h > /dev/null; then \
+ TOP=$(TOP) $(TOP)/fips/openssl_fips_fingerprint $(TOP)/libcrypto.a $(FIPS_RSAGTEST); \
+ fi
+
$(RSATEST)$(EXE_EXT): $(RSATEST).o $(DLIBCRYPTO)
@target=$(RSATEST); $(BUILD_CMD)