summaryrefslogtreecommitdiffstats
path: root/lib/libssl/src/fips/dsa
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2005-04-29 05:36:57 +0000
committerdjm <djm@openbsd.org>2005-04-29 05:36:57 +0000
commit9f93b617b0dfd35e8a6c7bdafd5ceb0c4f598802 (patch)
treed40545e143b8d4b6786e65eee7d019efe7f1d738 /lib/libssl/src/fips/dsa
parentsync (diff)
downloadwireguard-openbsd-9f93b617b0dfd35e8a6c7bdafd5ceb0c4f598802.tar.xz
wireguard-openbsd-9f93b617b0dfd35e8a6c7bdafd5ceb0c4f598802.zip
import of openssl-0.9.7g; tested on platforms from alpha to zaurus, ok deraadt@
Diffstat (limited to 'lib/libssl/src/fips/dsa')
-rw-r--r--lib/libssl/src/fips/dsa/Makefile158
-rw-r--r--lib/libssl/src/fips/dsa/fingerprint.sha13
-rw-r--r--lib/libssl/src/fips/dsa/fips_dsa_gen.c374
-rw-r--r--lib/libssl/src/fips/dsa/fips_dsa_ossl.c387
-rw-r--r--lib/libssl/src/fips/dsa/fips_dsa_selftest.c168
-rw-r--r--lib/libssl/src/fips/dsa/fips_dsatest.c257
-rw-r--r--lib/libssl/src/fips/dsa/fips_dssvs.c306
7 files changed, 1653 insertions, 0 deletions
diff --git a/lib/libssl/src/fips/dsa/Makefile b/lib/libssl/src/fips/dsa/Makefile
new file mode 100644
index 00000000000..0cc5704ed13
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/Makefile
@@ -0,0 +1,158 @@
+#
+# SSLeay/fips/dsa/Makefile
+#
+
+DIR= dsa
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=fips_dsatest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_dsa_ossl.c fips_dsa_gen.c fips_dsa_selftest.c
+LIBOBJ=fips_dsa_ossl.o fips_dsa_gen.o fips_dsa_selftest.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
+
+all: check lib
+
+lib: $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
+ $(RANLIB) $(LIB) || echo Never mind.
+ @sleep 2; touch lib
+
+check:
+ TOP=`pwd`/$(TOP) ../fips_check_sha1 fingerprint.sha1 $(SRC) $(HEADER)
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @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:
+
+top_fips_dssvs:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) TARGET=fips_dssvs sub_target)
+
+fips_dssvs: fips_dssvs.o $(TOP)/libcrypto.a
+ $(CC) $(CFLAGS) -o fips_dssvs fips_dssvs.o $(PEX_LIBS) $(TOP)/libcrypto.a $(EX_LIBS)
+ TOP=$(TOP) $(TOP)/fips/openssl_fips_fingerprint $(TOP)/libcrypto.a fips_dssvs
+
+Q=../testvectors/dsa/req
+A=../testvectors/dsa/rsp
+
+fips_test: top_fips_dssvs
+ -rm -rf $A
+ mkdir $A
+ ./fips_dssvs pqg < $Q/PQGGen.req > $A/PQGGen.rsp
+ ./fips_dssvs keypair < $Q/KeyPair.req > $A/KeyPair.rsp
+ ./fips_dssvs siggen < $Q/SigGen.req > $A/SigGen.rsp
+ ./fips_dssvs sigver < $Q/SigVer.req > $A/SigVer.rsp
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+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.
+
+fips_dsa_gen.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_dsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
+fips_dsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/cast.h
+fips_dsa_gen.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+fips_dsa_gen.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
+fips_dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_gen.o: ../../include/openssl/fips.h ../../include/openssl/idea.h
+fips_dsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
+fips_dsa_gen.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
+fips_dsa_gen.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
+fips_dsa_gen.o: ../../include/openssl/objects.h
+fips_dsa_gen.o: ../../include/openssl/opensslconf.h
+fips_dsa_gen.o: ../../include/openssl/opensslv.h
+fips_dsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_dsa_gen.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h
+fips_dsa_gen.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h
+fips_dsa_gen.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+fips_dsa_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_dsa_gen.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+fips_dsa_gen.o: ../../include/openssl/ui_compat.h fips_dsa_gen.c
+fips_dsa_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_ossl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_ossl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+fips_dsa_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
+fips_dsa_ossl.o: ../../include/openssl/err.h ../../include/openssl/fips.h
+fips_dsa_ossl.o: ../../include/openssl/lhash.h
+fips_dsa_ossl.o: ../../include/openssl/opensslconf.h
+fips_dsa_ossl.o: ../../include/openssl/opensslv.h
+fips_dsa_ossl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_dsa_ossl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+fips_dsa_ossl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_dsa_ossl.o: ../../include/openssl/ui.h fips_dsa_ossl.c
+fips_dsa_selftest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dsa_selftest.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+fips_dsa_selftest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/fips.h
+fips_dsa_selftest.o: ../../include/openssl/lhash.h
+fips_dsa_selftest.o: ../../include/openssl/opensslconf.h
+fips_dsa_selftest.o: ../../include/openssl/opensslv.h
+fips_dsa_selftest.o: ../../include/openssl/ossl_typ.h
+fips_dsa_selftest.o: ../../include/openssl/safestack.h
+fips_dsa_selftest.o: ../../include/openssl/stack.h
+fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c
+fips_dsatest.o: ../../e_os.h ../../include/openssl/asn1.h
+fips_dsatest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dsatest.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+fips_dsatest.o: ../../include/openssl/des_old.h ../../include/openssl/dh.h
+fips_dsatest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsatest.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+fips_dsatest.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_dsatest.o: ../../include/openssl/lhash.h
+fips_dsatest.o: ../../include/openssl/opensslconf.h
+fips_dsatest.o: ../../include/openssl/opensslv.h
+fips_dsatest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_dsatest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+fips_dsatest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_dsatest.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fips_dsatest.o: fips_dsatest.c
diff --git a/lib/libssl/src/fips/dsa/fingerprint.sha1 b/lib/libssl/src/fips/dsa/fingerprint.sha1
new file mode 100644
index 00000000000..4a89db5cf33
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/fingerprint.sha1
@@ -0,0 +1,3 @@
+HMAC-SHA1(fips_dsa_ossl.c)= d5f718695397fe56d6bb46f7c410794cb895e206
+HMAC-SHA1(fips_dsa_gen.c)= c252db14699f3ff641db052311da7d7521569c53
+HMAC-SHA1(fips_dsa_selftest.c)= 4bfc5d3a6b977527b053f3a03d0760a822a26135
diff --git a/lib/libssl/src/fips/dsa/fips_dsa_gen.c b/lib/libssl/src/fips/dsa/fips_dsa_gen.c
new file mode 100644
index 00000000000..21fa3d1783c
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/fips_dsa_gen.c
@@ -0,0 +1,374 @@
+/* crypto/dsa/dsa_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.]
+ */
+
+#undef GENUINE_DSA
+
+#ifdef GENUINE_DSA
+/* Parameter generation follows the original release of FIPS PUB 186,
+ * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
+#define HASH EVP_sha()
+#else
+/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
+ * FIPS PUB 180-1) */
+#define HASH EVP_sha1()
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+/*#include "cryptlib.h"*/
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_RAND
+#include <openssl/rand.h>
+#endif
+#ifndef OPENSSL_NO_SHA
+#include <openssl/sha.h>
+#endif
+#include <openssl/fips.h>
+#include <openssl/err.h>
+
+#ifndef OPENSSL_NO_DSA
+#ifdef OPENSSL_FIPS
+
+static int fips_check_dsa(DSA *dsa)
+ {
+ static const unsigned char str1[]="12345678901234567890";
+ unsigned char sig[256];
+ unsigned int siglen;
+
+ DSA_sign(0, str1, 20, sig, &siglen, dsa);
+ if(DSA_verify(0, str1, 20, sig, siglen, dsa) != 1)
+ {
+ FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
+ return 0;
+ }
+ return 1;
+ }
+
+DSA *DSA_generate_parameters(FIPS_DSA_SIZE_T bits,
+ unsigned char *seed_in, FIPS_DSA_SIZE_T seed_len,
+ int *counter_ret, unsigned long *h_ret,
+ void (*callback)(int, int, void *),
+ void *cb_arg)
+ {
+ int ok=0;
+ unsigned char seed[SHA_DIGEST_LENGTH];
+ unsigned char md[SHA_DIGEST_LENGTH];
+ unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
+ BIGNUM *r0,*W,*X,*c,*test;
+ BIGNUM *g=NULL,*q=NULL,*p=NULL;
+ BN_MONT_CTX *mont=NULL;
+ int k,n=0,i,b,m=0;
+ int counter=0;
+ int r=0;
+ BN_CTX *ctx=NULL,*ctx2=NULL,*ctx3=NULL;
+ unsigned int h=2;
+ DSA *ret=NULL;
+ unsigned char *seed_out=seed_in;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_DSA_GENERATE_PARAMETERS,
+ FIPS_R_FIPS_SELFTEST_FAILED);
+ goto err;
+ }
+
+ if (bits < 512) bits=512;
+ bits=(bits+63)/64*64;
+
+ if (seed_len < 20)
+ seed_in = NULL; /* seed buffer too small -- ignore */
+ if (seed_len > 20)
+ seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
+ * but our internal buffers are restricted to 160 bits*/
+ if ((seed_in != NULL) && (seed_len == 20))
+ memcpy(seed,seed_in,seed_len);
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ if ((ctx2=BN_CTX_new()) == NULL) goto err;
+ if ((ctx3=BN_CTX_new()) == NULL) goto err;
+ if ((ret=DSA_new()) == NULL) goto err;
+
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+
+ BN_CTX_start(ctx2);
+ r0 = BN_CTX_get(ctx2);
+ g = BN_CTX_get(ctx2);
+ W = BN_CTX_get(ctx2);
+ q = BN_CTX_get(ctx2);
+ X = BN_CTX_get(ctx2);
+ c = BN_CTX_get(ctx2);
+ p = BN_CTX_get(ctx2);
+ test = BN_CTX_get(ctx2);
+
+ BN_lshift(test,BN_value_one(),bits-1);
+
+ for (;;)
+ {
+ for (;;) /* find q */
+ {
+ int seed_is_random;
+
+ /* step 1 */
+ if (callback != NULL) callback(0,m++,cb_arg);
+
+ if (!seed_len)
+ {
+ if(RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH) < 0)
+ goto err;
+ seed_is_random = 1;
+ }
+ else
+ {
+ seed_is_random = 0;
+ seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
+ }
+ memcpy(buf,seed,SHA_DIGEST_LENGTH);
+ memcpy(buf2,seed,SHA_DIGEST_LENGTH);
+ /* precompute "SEED + 1" for step 7: */
+ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+ {
+ buf[i]++;
+ if (buf[i] != 0) break;
+ }
+
+ /* step 2 */
+ EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
+ EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL);
+ for (i=0; i<SHA_DIGEST_LENGTH; i++)
+ md[i]^=buf2[i];
+
+ /* step 3 */
+ md[0]|=0x80;
+ md[SHA_DIGEST_LENGTH-1]|=0x01;
+ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;
+
+ /* step 4 */
+ r = BN_is_prime_fasttest(q, DSS_prime_checks, callback, ctx3, cb_arg, seed_is_random);
+ if (r > 0)
+ break;
+ if (r != 0)
+ goto err;
+
+ /* do a callback call */
+ /* step 5 */
+ }
+
+ if (callback != NULL) callback(2,0,cb_arg);
+ if (callback != NULL) callback(3,0,cb_arg);
+
+ /* step 6 */
+ counter=0;
+ /* "offset = 2" */
+
+ n=(bits-1)/160;
+ b=(bits-1)-n*160;
+
+ for (;;)
+ {
+ if (callback != NULL && counter != 0)
+ callback(0,counter,cb_arg);
+
+ /* step 7 */
+ BN_zero(W);
+ /* now 'buf' contains "SEED + offset - 1" */
+ for (k=0; k<=n; k++)
+ {
+ /* obtain "SEED + offset + k" by incrementing: */
+ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+ {
+ buf[i]++;
+ if (buf[i] != 0) break;
+ }
+
+ EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
+
+ /* step 8 */
+ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0))
+ goto err;
+ BN_lshift(r0,r0,160*k);
+ BN_add(W,W,r0);
+ }
+
+ /* more of step 8 */
+ BN_mask_bits(W,bits-1);
+ BN_copy(X,W); /* this should be ok */
+ BN_add(X,X,test); /* this should be ok */
+
+ /* step 9 */
+ BN_lshift1(r0,q);
+ BN_mod(c,X,r0,ctx);
+ BN_sub(r0,c,BN_value_one());
+ BN_sub(p,X,r0);
+
+ /* step 10 */
+ if (BN_cmp(p,test) >= 0)
+ {
+ /* step 11 */
+ r = BN_is_prime_fasttest(p, DSS_prime_checks, callback, ctx3, cb_arg, 1);
+ if (r > 0)
+ goto end; /* found it */
+ if (r != 0)
+ goto err;
+ }
+
+ /* step 13 */
+ counter++;
+ /* "offset = offset + n + 1" */
+
+ /* step 14 */
+ if (counter >= 4096) break;
+ }
+ }
+end:
+ if (callback != NULL) callback(2,1,cb_arg);
+
+ /* We now need to generate g */
+ /* Set r0=(p-1)/q */
+ BN_sub(test,p,BN_value_one());
+ BN_div(r0,NULL,test,q,ctx);
+
+ BN_set_word(test,h);
+ BN_MONT_CTX_set(mont,p,ctx);
+
+ for (;;)
+ {
+ /* g=test^r0%p */
+ BN_mod_exp_mont(g,test,r0,p,ctx,mont);
+ if (!BN_is_one(g)) break;
+ BN_add(test,test,BN_value_one());
+ h++;
+ }
+
+ if (callback != NULL) callback(3,1,cb_arg);
+
+ ok=1;
+err:
+ if (!ok)
+ {
+ if (ret != NULL) DSA_free(ret);
+ }
+ else
+ {
+ ret->p=BN_dup(p);
+ ret->q=BN_dup(q);
+ ret->g=BN_dup(g);
+ if(seed_out != NULL) memcpy(seed_out,seed,20);
+ if (counter_ret != NULL) *counter_ret=counter;
+ if (h_ret != NULL) *h_ret=h;
+ }
+ if (ctx != NULL) BN_CTX_free(ctx);
+ if (ctx2 != NULL)
+ {
+ BN_CTX_end(ctx2);
+ BN_CTX_free(ctx2);
+ }
+ if (ctx3 != NULL) BN_CTX_free(ctx3);
+ if (mont != NULL) BN_MONT_CTX_free(mont);
+ return(ok?ret:NULL);
+ }
+
+int DSA_generate_key(DSA *dsa)
+ {
+ int ok=0;
+ BN_CTX *ctx=NULL;
+ BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if (dsa->priv_key == NULL)
+ {
+ if ((priv_key=BN_new()) == NULL) goto err;
+ }
+ else
+ priv_key=dsa->priv_key;
+
+ do
+ if (!BN_rand_range(priv_key,dsa->q)) goto err;
+ while (BN_is_zero(priv_key));
+
+ if (dsa->pub_key == NULL)
+ {
+ if ((pub_key=BN_new()) == NULL) goto err;
+ }
+ else
+ pub_key=dsa->pub_key;
+
+ if (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err;
+
+ dsa->priv_key=priv_key;
+ dsa->pub_key=pub_key;
+
+ if(!fips_check_dsa(dsa))
+ goto err;
+
+ ok=1;
+
+err:
+ if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);
+ if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ return(ok);
+ }
+#endif
+#endif
diff --git a/lib/libssl/src/fips/dsa/fips_dsa_ossl.c b/lib/libssl/src/fips/dsa/fips_dsa_ossl.c
new file mode 100644
index 00000000000..0ae5eb4b9e1
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/fips_dsa_ossl.c
@@ -0,0 +1,387 @@
+/* crypto/dsa/dsa_ossl.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.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/fips.h>
+
+#ifdef OPENSSL_FIPS
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig,
+ DSA *dsa);
+static int dsa_init(DSA *dsa);
+static int dsa_finish(DSA *dsa);
+static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+ BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont);
+static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+
+static DSA_METHOD openssl_dsa_meth = {
+"OpenSSL FIPS DSA method",
+dsa_do_sign,
+dsa_sign_setup,
+dsa_do_verify,
+dsa_mod_exp,
+dsa_bn_mod_exp,
+dsa_init,
+dsa_finish,
+0,
+NULL
+};
+
+int FIPS_dsa_check(struct dsa_st *dsa)
+ {
+ if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign
+ || dsa->meth->dsa_sign_setup != dsa_sign_setup
+ || dsa->meth->dsa_mod_exp != dsa_mod_exp
+ || dsa->meth->bn_mod_exp != dsa_bn_mod_exp
+ || dsa->meth->init != dsa_init
+ || dsa->meth->finish != dsa_finish)
+ {
+ FIPSerr(FIPS_F_FIPS_DSA_CHECK,FIPS_R_NON_FIPS_METHOD);
+ return 0;
+ }
+ return 1;
+ }
+
+const DSA_METHOD *DSA_OpenSSL(void)
+{
+ return &openssl_dsa_meth;
+}
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa)
+ {
+ BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
+ BIGNUM m;
+ BIGNUM xr;
+ BN_CTX *ctx=NULL;
+ int i,reason=ERR_R_BN_LIB;
+ DSA_SIG *ret=NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED);
+ return NULL;
+ }
+
+ BN_init(&m);
+ BN_init(&xr);
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ reason=DSA_R_MISSING_PARAMETERS;
+ goto err;
+ }
+
+ s=BN_new();
+ if (s == NULL) goto err;
+
+ i=BN_num_bytes(dsa->q); /* should be 20 */
+ if ((dlen > i) || (dlen > 50))
+ {
+ reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
+ goto err;
+ }
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+
+ if ((dsa->kinv == NULL) || (dsa->r == NULL))
+ {
+ if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+ }
+ else
+ {
+ kinv=dsa->kinv;
+ dsa->kinv=NULL;
+ r=dsa->r;
+ dsa->r=NULL;
+ }
+
+ if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
+
+ /* Compute s = inv(k) (m + xr) mod q */
+ if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
+ if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
+ if (BN_cmp(s,dsa->q) > 0)
+ BN_sub(s,s,dsa->q);
+ if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
+
+ ret=DSA_SIG_new();
+ if (ret == NULL) goto err;
+ ret->r = r;
+ ret->s = s;
+
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_DO_SIGN,reason);
+ BN_free(r);
+ BN_free(s);
+ }
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_clear_free(&m);
+ BN_clear_free(&xr);
+ if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
+ BN_clear_free(kinv);
+ return(ret);
+ }
+
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+ {
+ BN_CTX *ctx;
+ BIGNUM k,*kinv=NULL,*r=NULL;
+ int ret=0;
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ BN_init(&k);
+
+ if (ctx_in == NULL)
+ {
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ }
+ else
+ ctx=ctx_in;
+
+ if ((r=BN_new()) == NULL) goto err;
+ kinv=NULL;
+
+ /* Get random k */
+ do
+ if (!BN_rand_range(&k, dsa->q)) goto err;
+ while (BN_is_zero(&k));
+
+ if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+ {
+ if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+ if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
+ dsa->p,ctx)) goto err;
+ }
+
+ /* Compute r = (g^k mod p) mod q */
+ if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx,
+ (BN_MONT_CTX *)dsa->method_mont_p)) goto err;
+ if (!BN_mod(r,r,dsa->q,ctx)) goto err;
+
+ /* Compute part of 's = inv(k) (m + xr) mod q' */
+ if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
+
+ if (*kinvp != NULL) BN_clear_free(*kinvp);
+ *kinvp=kinv;
+ kinv=NULL;
+ if (*rp != NULL) BN_clear_free(*rp);
+ *rp=r;
+ ret=1;
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
+ if (kinv != NULL) BN_clear_free(kinv);
+ if (r != NULL) BN_clear_free(r);
+ }
+ if (ctx_in == NULL) BN_CTX_free(ctx);
+ if (kinv != NULL) BN_clear_free(kinv);
+ BN_clear_free(&k);
+ return(ret);
+ }
+
+static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig,
+ DSA *dsa)
+ {
+ BN_CTX *ctx;
+ BIGNUM u1,u2,t1;
+ BN_MONT_CTX *mont=NULL;
+ int ret = -1;
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
+ return -1;
+ }
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED);
+ return -1;
+ }
+
+ BN_init(&u1);
+ BN_init(&u2);
+ BN_init(&t1);
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
+ {
+ ret = 0;
+ goto err;
+ }
+ if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
+ {
+ ret = 0;
+ goto err;
+ }
+
+ /* Calculate W = inv(S) mod Q
+ * save W in u2 */
+ if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
+
+ /* save M in u1 */
+ if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
+
+ /* u1 = M * w mod q */
+ if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
+
+ /* u2 = r * w mod q */
+ if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
+
+ if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+ {
+ if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
+ if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
+ dsa->p,ctx)) goto err;
+ }
+ mont=(BN_MONT_CTX *)dsa->method_mont_p;
+
+#if 0
+ {
+ BIGNUM t2;
+
+ BN_init(&t2);
+ /* v = ( g^u1 * y^u2 mod p ) mod q */
+ /* let t1 = g ^ u1 mod p */
+ if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err;
+ /* let t2 = y ^ u2 mod p */
+ if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err;
+ /* let u1 = t1 * t2 mod p */
+ if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn;
+ BN_free(&t2);
+ }
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
+#else
+ {
+ if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
+ dsa->p,ctx,mont)) goto err;
+ /* BN_copy(&u1,&t1); */
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
+ }
+#endif
+ /* V is now in u1. If the signature is correct, it will be
+ * equal to R. */
+ ret=(BN_ucmp(&u1, sig->r) == 0);
+
+ err:
+ if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_free(&u1);
+ BN_free(&u2);
+ BN_free(&t1);
+ return(ret);
+ }
+
+static int dsa_init(DSA *dsa)
+{
+ dsa->flags|=DSA_FLAG_CACHE_MONT_P;
+ return(1);
+}
+
+static int dsa_finish(DSA *dsa)
+{
+ if(dsa->method_mont_p)
+ BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p);
+ return(1);
+}
+
+static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+ BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont)
+{
+ return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont);
+}
+
+static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+{
+ return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
+
+#else /* ndef OPENSSL_FIPS */
+
+static void *dummy=&dummy;
+
+#endif /* ndef OPENSSL_FIPS */
diff --git a/lib/libssl/src/fips/dsa/fips_dsa_selftest.c b/lib/libssl/src/fips/dsa/fips_dsa_selftest.c
new file mode 100644
index 00000000000..2c88f0af441
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/fips_dsa_selftest.c
@@ -0,0 +1,168 @@
+/* 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 <string.h>
+#include <openssl/crypto.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+
+#ifdef OPENSSL_FIPS
+
+/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
+ * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
+static unsigned char seed[20]={
+ 0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
+ 0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
+ };
+
+static unsigned char out_p[]={
+ 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
+ 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
+ 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+ 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
+ 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
+ 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
+ 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
+ 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91,
+ };
+
+static unsigned char out_q[]={
+ 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
+ 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
+ 0xda,0xce,0x91,0x5f,
+ };
+
+static unsigned char out_g[]={
+ 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
+ 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
+ 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
+ 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
+ 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
+ 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
+ 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
+ 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02,
+ };
+
+static const unsigned char str1[]="12345678901234567890";
+
+void FIPS_corrupt_dsa()
+ {
+ ++seed[0];
+ }
+
+int FIPS_selftest_dsa()
+ {
+ DSA *dsa=NULL;
+ int counter,i,j;
+ unsigned char buf[256];
+ unsigned long h;
+ unsigned char sig[256];
+ unsigned int siglen;
+
+ dsa=DSA_generate_parameters(512,seed,20,&counter,&h,NULL,NULL);
+
+ if(dsa == NULL)
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ if (counter != 105)
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ if (h != 2)
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ i=BN_bn2bin(dsa->q,buf);
+ j=sizeof(out_q);
+ if (i != j || memcmp(buf,out_q,i) != 0)
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+
+ i=BN_bn2bin(dsa->p,buf);
+ j=sizeof(out_p);
+ if (i != j || memcmp(buf,out_p,i) != 0)
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+
+ i=BN_bn2bin(dsa->g,buf);
+ j=sizeof(out_g);
+ if (i != j || memcmp(buf,out_g,i) != 0)
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ DSA_generate_key(dsa);
+ DSA_sign(0, str1, 20, sig, &siglen, dsa);
+ if(DSA_verify(0, str1, 20, sig, siglen, dsa) != 1)
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ DSA_free(dsa);
+ return 1;
+ }
+#endif
diff --git a/lib/libssl/src/fips/dsa/fips_dsatest.c b/lib/libssl/src/fips/dsa/fips_dsatest.c
new file mode 100644
index 00000000000..7215940edec
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/fips_dsatest.c
@@ -0,0 +1,257 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+
+#if defined(OPENSSL_NO_DSA) || !defined(OPENSSL_FIPS)
+int main(int argc, char *argv[])
+{
+ printf("No FIPS DSA support\n");
+ return(0);
+}
+#else
+#include <openssl/dsa.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK _far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+static void MS_CALLBACK dsa_cb(int p, int n, void *arg);
+
+/* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to
+ * FIPS PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */
+static unsigned char seed[20]={
+ 0xd5,0x01,0x4e,0x4b,0x60,0xef,0x2b,0xa8,0xb6,0x21,0x1b,0x40,
+ 0x62,0xba,0x32,0x24,0xe0,0x42,0x7d,0xd3,
+ };
+
+static unsigned char out_p[]={
+ 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa,
+ 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb,
+ 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7,
+ 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5,
+ 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf,
+ 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac,
+ 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2,
+ 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91,
+ };
+
+static unsigned char out_q[]={
+ 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee,
+ 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e,
+ 0xda,0xce,0x91,0x5f,
+ };
+
+static unsigned char out_g[]={
+ 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13,
+ 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00,
+ 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb,
+ 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e,
+ 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf,
+ 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c,
+ 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c,
+ 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02,
+ };
+
+static const unsigned char str1[]="12345678901234567890";
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+static const unsigned char rnd_key1[]="12345678";
+static const unsigned char rnd_key2[]="abcdefgh";
+
+static BIO *bio_err=NULL;
+
+int main(int argc, char **argv)
+ {
+ DSA *dsa=NULL;
+ int counter,ret=0,i,j;
+ unsigned char buf[256];
+ unsigned long h;
+ unsigned char sig[256];
+ unsigned int siglen;
+
+ if (bio_err == NULL)
+ bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+
+#ifdef OPENSSL_FIPS
+ if(!FIPS_mode_set(1,argv[0]))
+ {
+ ERR_print_errors(bio_err);
+ EXIT(1);
+ }
+#endif
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ ERR_load_crypto_strings();
+ FIPS_set_prng_key(rnd_key1,rnd_key2);
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+
+ BIO_printf(bio_err,"test generation of DSA parameters\n");
+
+ dsa=DSA_generate_parameters(512,seed,20,&counter,&h,dsa_cb,bio_err);
+
+ BIO_printf(bio_err,"seed\n");
+ for (i=0; i<20; i+=4)
+ {
+ BIO_printf(bio_err,"%02X%02X%02X%02X ",
+ seed[i],seed[i+1],seed[i+2],seed[i+3]);
+ }
+ BIO_printf(bio_err,"\ncounter=%d h=%d\n",counter,h);
+
+ if (dsa == NULL) goto end;
+ DSA_print(bio_err,dsa,0);
+ if (counter != 105)
+ {
+ BIO_printf(bio_err,"counter should be 105\n");
+ goto end;
+ }
+ if (h != 2)
+ {
+ BIO_printf(bio_err,"h should be 2\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->q,buf);
+ j=sizeof(out_q);
+ if ((i != j) || (memcmp(buf,out_q,i) != 0))
+ {
+ BIO_printf(bio_err,"q value is wrong\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->p,buf);
+ j=sizeof(out_p);
+ if ((i != j) || (memcmp(buf,out_p,i) != 0))
+ {
+ BIO_printf(bio_err,"p value is wrong\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->g,buf);
+ j=sizeof(out_g);
+ if ((i != j) || (memcmp(buf,out_g,i) != 0))
+ {
+ BIO_printf(bio_err,"g value is wrong\n");
+ goto end;
+ }
+ DSA_generate_key(dsa);
+ DSA_sign(0, str1, 20, sig, &siglen, dsa);
+ if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
+ ret=1;
+end:
+ if (!ret)
+ ERR_print_errors(bio_err);
+ if (dsa != NULL) DSA_free(dsa);
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_state(0);
+ ERR_free_strings();
+ CRYPTO_mem_leaks(bio_err);
+ if (bio_err != NULL)
+ {
+ BIO_free(bio_err);
+ bio_err = NULL;
+ }
+ EXIT(!ret);
+ return(!ret);
+ }
+
+static int cb_exit(int ec)
+ {
+ EXIT(ec);
+ return(0); /* To keep some compilers quiet */
+ }
+
+static void MS_CALLBACK dsa_cb(int p, int n, void *arg)
+ {
+ char c='*';
+ static int ok=0,num=0;
+
+ if (p == 0) { c='.'; num++; };
+ if (p == 1) c='+';
+ if (p == 2) { c='*'; ok++; }
+ if (p == 3) c='\n';
+ BIO_write(arg,&c,1);
+ (void)BIO_flush(arg);
+
+ if (!ok && (p == 0) && (num > 1))
+ {
+ BIO_printf((BIO *)arg,"error in dsatest\n");
+ cb_exit(1);
+ }
+ }
+#endif
diff --git a/lib/libssl/src/fips/dsa/fips_dssvs.c b/lib/libssl/src/fips/dsa/fips_dssvs.c
new file mode 100644
index 00000000000..50a4d969865
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/fips_dssvs.c
@@ -0,0 +1,306 @@
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <string.h>
+
+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;
+ }
+
+BIGNUM *hex2bn(const char *in)
+ {
+ BIGNUM *p=BN_new();
+
+ BN_hex2bn(&p,in);
+
+ 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);
+ }
+
+void pbn(const char *tag,const BIGNUM *val)
+ {
+ printf("%s = %s\n",tag,BN_bn2hex(val));
+ }
+
+void primes()
+ {
+ char buf[10240];
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ fputs(buf,stdout);
+ if(!strncmp(buf,"Prime= ",7))
+ {
+ BIGNUM *pp;
+
+ pp=BN_new();
+ BN_hex2bn(&pp,buf+7);
+ printf("result= %c\n",
+ BN_is_prime(pp,20,NULL,NULL,NULL) ? 'P' : 'F');
+ }
+ }
+ }
+
+void pqg()
+ {
+ char buf[1024];
+ int nmod=0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ nmod=atoi(buf+7);
+ else if(!strncmp(buf,"N = ",4))
+ {
+ int n=atoi(buf+4);
+
+ printf("[mod = %d]\n\n",nmod);
+
+ while(n--)
+ {
+ unsigned char seed[20];
+ DSA *dsa;
+ int counter;
+ unsigned long h;
+
+ dsa=DSA_generate_parameters(nmod,seed,0,&counter,&h,NULL,NULL);
+ printf("P = %s\n",BN_bn2hex(dsa->p));
+ printf("Q = %s\n",BN_bn2hex(dsa->q));
+ printf("G = %s\n",BN_bn2hex(dsa->g));
+ pv("Seed",seed,20);
+ printf("c = %d\n",counter);
+ printf("H = %lx\n",h);
+ putc('\n',stdout);
+ }
+ }
+ else
+ fputs(buf,stdout);
+ }
+ }
+
+void keypair()
+ {
+ char buf[1024];
+ int nmod=0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ nmod=atoi(buf+7);
+ else if(!strncmp(buf,"N = ",4))
+ {
+ DSA *dsa;
+ int n=atoi(buf+4);
+
+ printf("[mod = %d]\n\n",nmod);
+
+ dsa=DSA_generate_parameters(nmod,NULL,0,NULL,NULL,NULL,NULL);
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+
+ while(n--)
+ {
+ DSA_generate_key(dsa);
+
+ pbn("X",dsa->priv_key);
+ pbn("Y",dsa->pub_key);
+ putc('\n',stdout);
+ }
+ }
+ }
+ }
+
+void siggen()
+ {
+ char buf[1024];
+ int nmod=0;
+ DSA *dsa=NULL;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ {
+ nmod=atoi(buf+7);
+ printf("[mod = %d]\n\n",nmod);
+
+ dsa=DSA_generate_parameters(nmod,NULL,0,NULL,NULL,NULL,NULL);
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+ }
+ else if(!strncmp(buf,"Msg = ",6))
+ {
+ unsigned char msg[1024];
+ unsigned char hash[20];
+ int n;
+ DSA_SIG *sig;
+
+ n=hex2bin(buf+6,msg);
+ pv("Msg",msg,n);
+
+ DSA_generate_key(dsa);
+ pbn("Y",dsa->pub_key);
+
+ SHA1(msg,n,hash);
+ sig=DSA_do_sign(hash,sizeof hash,dsa);
+ pbn("R",sig->r);
+ pbn("S",sig->s);
+ putc('\n',stdout);
+ }
+ }
+ }
+
+void sigver()
+ {
+ DSA *dsa=NULL;
+ char buf[1024];
+ int nmod=0;
+ unsigned char hash[20];
+ DSA_SIG *sig=DSA_SIG_new();
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ {
+ nmod=atoi(buf+7);
+ if(dsa)
+ DSA_free(dsa);
+ dsa=DSA_new();
+ }
+ else if(!strncmp(buf,"P = ",4))
+ dsa->p=hex2bn(buf+4);
+ else if(!strncmp(buf,"Q = ",4))
+ dsa->q=hex2bn(buf+4);
+ else if(!strncmp(buf,"G = ",4))
+ {
+ dsa->g=hex2bn(buf+4);
+
+ printf("[mod = %d]\n\n",nmod);
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+ }
+ else if(!strncmp(buf,"Msg = ",6))
+ {
+ unsigned char msg[1024];
+ int n;
+
+ n=hex2bin(buf+6,msg);
+ pv("Msg",msg,n);
+ SHA1(msg,n,hash);
+ }
+ else if(!strncmp(buf,"Y = ",4))
+ dsa->pub_key=hex2bn(buf+4);
+ else if(!strncmp(buf,"R = ",4))
+ sig->r=hex2bn(buf+4);
+ else if(!strncmp(buf,"S = ",4))
+ {
+ sig->s=hex2bn(buf+4);
+
+ pbn("Y",dsa->pub_key);
+ pbn("R",sig->r);
+ pbn("S",sig->s);
+ printf("Result = %c\n",DSA_do_verify(hash,sizeof hash,sig,dsa)
+ ? 'P' : 'F');
+ putc('\n',stdout);
+ }
+ }
+ }
+
+int main(int argc,char **argv)
+ {
+ if(argc != 2)
+ {
+ fprintf(stderr,"%s [prime|pqg]\n",argv[0]);
+ exit(1);
+ }
+ if(!FIPS_mode_set(1,argv[0]))
+ {
+ ERR_load_crypto_strings();
+ ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+ exit(1);
+ }
+ if(!strcmp(argv[1],"prime"))
+ primes();
+ else if(!strcmp(argv[1],"pqg"))
+ pqg();
+ else if(!strcmp(argv[1],"keypair"))
+ keypair();
+ 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;
+ }