File openssl-fips_add_cavs_tests.patch of Package openssl-1_0_0

Index: openssl-1.0.2j/crypto/fips/Makefile
===================================================================
--- openssl-1.0.2j.orig/crypto/fips/Makefile	2017-03-16 17:27:29.296989039 +0100
+++ openssl-1.0.2j/crypto/fips/Makefile	2017-03-16 17:32:20.165572290 +0100
@@ -19,7 +19,20 @@ APPS=
 PROGRAM= fips_standalone_hmac
 EXE= $(PROGRAM)$(EXE_EXT)
 
+CAVS_PROGRAMS= fips_aesavs fips_cmactest fips_desmovs fips_dhvs fips_drbgvs \
+fips_ecdhvs fips_ecdsavs fips_rngvs fips_rsagtest fips_rsastest \
+fips_rsavtest fips_shatest fips_gcmtest fips_dssvs fips_tlsvs fips_hmactest
+
+CAVS_SRC= fips_aesavs.c fips_cmactest.c fips_desmovs.c fips_dhvs.c fips_drbgvs.c fips_dssvs.c \
+fips_ecdhvs.c fips_ecdsavs.c fips_gcmtest.c fips_rngvs.c fips_rsagtest.c fips_rsastest.c \
+fips_rsavtest.c fips_shatest.c fips_tlsvs.c fips_hmactest.c
+
+CAVS_OBJ= fips_aesavs.o fips_cmactest.o fips_desmovs.o fips_dhvs.o fips_drbgvs.o \
+fips_ecdhvs.o fips_ecdsavs.o fips_gcmtest.o fips_rngvs.o fips_rsagtest.o fips_rsastest.o \
+fips_rsavtest.o fips_shatest.o fips_dssvs.o fips_tlsvs.o fips_hmactest.o
+
 LIB=$(TOP)/libcrypto.a
+SSLLIB=$(TOP)/libssl.a
 LIBSRC=fips_aes_selftest.c fips_des_selftest.c fips_hmac_selftest.c fips_rand_selftest.c \
     fips_rsa_selftest.c fips_sha_selftest.c fips.c fips_dsa_selftest.c  fips_rand.c \
     fips_rsa_x931g.c fips_post.c fips_drbg_ctr.c fips_drbg_hash.c fips_drbg_hmac.c \
@@ -34,19 +47,21 @@ LIBOBJ=fips_aes_selftest.o fips_des_self
     fips_cmac_selftest.o fips_ecdh_selftest.o fips_ecdsa_selftest.o fips_enc.o fips_md.o \
     fips_dh_selftest.o
 
-LIBCRYPTO=-L.. -lcrypto
+SRC= $(LIBSRC) fips_standalone_hmac.c fips_err.c $(CAVS_SRC)
 
-SRC= $(LIBSRC) fips_standalone_hmac.c
 
 EXHEADER= fips.h fips_rand.h
 HEADER=	$(EXHEADER)
 
 ALL=    $(GENERAL) $(SRC) $(HEADER)
 
+$(SSLLIB):
+	(cd ../..; $(MAKE) DIRS=ssl all)
+
 top:
 	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
 
-all:	lib exe
+all:	lib exe $(CAVS_PROGRAMS)
 
 lib:	$(LIBOBJ)
 	$(AR) $(LIB) $(LIBOBJ)
@@ -95,7 +110,8 @@ $(EXE): $(PROGRAM).o
 	for i in $(CPUID_OBJ); do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../$$i" ; done; \
 	$(CC) -o $@ $(CFLAGS) $(PROGRAM).o $$FIPS_SHA_ASM
 
-# DO NOT DELETE THIS LINE -- make depend depends on it.
+$(CAVS_PROGRAMS): $(CAVS_OBJ) fips_ecdsa_lib.o fips_rsa_lib.o fips_dsa_lib.o fips_dsa_sign.o fips_err.o $(SSLLIB) $(LIB)
+	$(CC) -o $@ $(CFLAGS) $@.o fips_rsa_lib.o fips_ecdsa_lib.o fips_dsa_lib.o fips_dsa_sign.o fips_err.o $(SSLLIB) $(LIB) -ldl -lz
 
 fips.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
 fips.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
@@ -280,6 +296,26 @@ fips_ecdsa_selftest.o: ../../include/ope
 fips_ecdsa_selftest.o: ../../include/openssl/safestack.h
 fips_ecdsa_selftest.o: ../../include/openssl/stack.h
 fips_ecdsa_selftest.o: ../../include/openssl/symhacks.h fips_ecdsa_selftest.c
+fips_dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h
+fips_dsa_lib.o: ../../include/openssl/opensslconf.h
+fips_dsa_lib.o: ../../include/openssl/opensslv.h
+fips_dsa_lib.o: ../../include/openssl/ossl_typ.h
+fips_dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dsa_lib.o: ../../include/openssl/symhacks.h fips_dsa_lib.c
+fips_dsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_sign.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_dsa_sign.o: ../../include/openssl/objects.h
+fips_dsa_sign.o: ../../include/openssl/opensslconf.h
+fips_dsa_sign.o: ../../include/openssl/opensslv.h
+fips_dsa_sign.o: ../../include/openssl/ossl_typ.h
+fips_dsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_dsa_sign.o: fips_dsa_sign.c
 fips_enc.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 fips_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 fips_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
@@ -405,3 +441,450 @@ fips_sha_selftest.o: ../../include/opens
 fips_sha_selftest.o: ../../include/openssl/safestack.h
 fips_sha_selftest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 fips_sha_selftest.o: ../../include/openssl/symhacks.h fips_sha_selftest.c
+fips_aesavs.o: ../../e_os.h ../../include/openssl/aes.h
+fips_aesavs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_aesavs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_aesavs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_aesavs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_aesavs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_aesavs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_aesavs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_aesavs.o: ../../include/openssl/opensslconf.h
+fips_aesavs.o: ../../include/openssl/opensslv.h
+fips_aesavs.o: ../../include/openssl/ossl_typ.h
+fips_aesavs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_aesavs.o: ../../include/openssl/symhacks.h fips_utl.h fips_aesavs.c
+fips_gcmtest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_gcmtest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_gcmtest.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_gcmtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_gcmtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_gcmtest.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_gcmtest.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_gcmtest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_gcmtest.o: ../../include/openssl/opensslconf.h
+fips_gcmtest.o: ../../include/openssl/opensslv.h
+fips_gcmtest.o: ../../include/openssl/ossl_typ.h
+fips_gcmtest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_gcmtest.o: ../../include/openssl/symhacks.h fips_utl.h fips_gcmtest.c
+fips_cmactest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_cmactest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_cmactest.o: ../../include/openssl/cmac.h ../../include/openssl/crypto.h
+fips_cmactest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_cmactest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_cmactest.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_cmactest.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_cmactest.o: ../../include/openssl/obj_mac.h
+fips_cmactest.o: ../../include/openssl/objects.h
+fips_cmactest.o: ../../include/openssl/opensslconf.h
+fips_cmactest.o: ../../include/openssl/opensslv.h
+fips_cmactest.o: ../../include/openssl/ossl_typ.h
+fips_cmactest.o: ../../include/openssl/safestack.h
+fips_cmactest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_cmactest.o: fips_utl.h fips_cmactest.c
+fips_hmactest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_hmactest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_hmactest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_hmactest.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_hmactest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_hmactest.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_hmactest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_hmactest.o: ../../include/openssl/objects.h
+fips_hmactest.o: ../../include/openssl/opensslconf.h
+fips_hmactest.o: ../../include/openssl/opensslv.h
+fips_hmactest.o: ../../include/openssl/ossl_typ.h
+fips_hmactest.o: ../../include/openssl/safestack.h
+fips_hmactest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_hmactest.o: fips_utl.h fips_hmactest.c
+fips_desmovs.o: ../../e_os.h ../../include/openssl/aes.h
+fips_desmovs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_desmovs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_desmovs.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_desmovs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_desmovs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_desmovs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_desmovs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_desmovs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_desmovs.o: ../../include/openssl/opensslconf.h
+fips_desmovs.o: ../../include/openssl/opensslv.h
+fips_desmovs.o: ../../include/openssl/ossl_typ.h
+fips_desmovs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_desmovs.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+fips_desmovs.o: ../../include/openssl/ui_compat.h fips_utl.h fips_desmovs.c
+fips_dh_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+fips_dh_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h
+fips_dh_lib.o: ../../include/openssl/opensslconf.h
+fips_dh_lib.o: ../../include/openssl/opensslv.h
+fips_dh_lib.o: ../../include/openssl/ossl_typ.h
+fips_dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dh_lib.o: ../../include/openssl/symhacks.h fips_dh_lib.c
+fips_dhvs.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_dhvs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dhvs.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+fips_dhvs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_dhvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dhvs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_dhvs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_dhvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_dhvs.o: ../../include/openssl/opensslconf.h
+fips_dhvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_dhvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dhvs.o: ../../include/openssl/symhacks.h fips_utl.h fips_dhvs.c
+fips_dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h
+fips_dsa_lib.o: ../../include/openssl/opensslconf.h
+fips_dsa_lib.o: ../../include/openssl/opensslv.h
+fips_dsa_lib.o: ../../include/openssl/ossl_typ.h
+fips_dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dsa_lib.o: ../../include/openssl/symhacks.h fips_dsa_lib.c
+fips_dsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_sign.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_dsa_sign.o: ../../include/openssl/objects.h
+fips_dsa_sign.o: ../../include/openssl/opensslconf.h
+fips_dsa_sign.o: ../../include/openssl/opensslv.h
+fips_dsa_sign.o: ../../include/openssl/ossl_typ.h
+fips_dsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_dsa_sign.o: fips_dsa_sign.c
+fips_dsatest.o: ../../e_os.h ../../include/openssl/aes.h
+fips_dsatest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsatest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsatest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsatest.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_dsatest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_dsatest.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_dsatest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_dsatest.o: ../../include/openssl/objects.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/safestack.h ../../include/openssl/stack.h
+fips_dsatest.o: ../../include/openssl/symhacks.h fips_utl.h fips_dsatest.c
+fips_dssvs.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_dssvs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dssvs.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_dssvs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_dssvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dssvs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_dssvs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_dssvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_dssvs.o: ../../include/openssl/opensslconf.h
+fips_dssvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_dssvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dssvs.o: ../../include/openssl/symhacks.h fips_utl.h fips_dssvs.c
+fips_ecdhvs.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_ecdhvs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_ecdhvs.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_ecdhvs.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+fips_ecdhvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_ecdhvs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_ecdhvs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_ecdhvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_ecdhvs.o: ../../include/openssl/opensslconf.h
+fips_ecdhvs.o: ../../include/openssl/opensslv.h
+fips_ecdhvs.o: ../../include/openssl/ossl_typ.h
+fips_ecdhvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_ecdhvs.o: ../../include/openssl/symhacks.h fips_utl.h fips_ecdhvs.c
+fips_ecdsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_ecdsa_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_ecdsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_ecdsa_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/fips.h
+fips_ecdsa_lib.o: ../../include/openssl/opensslconf.h
+fips_ecdsa_lib.o: ../../include/openssl/opensslv.h
+fips_ecdsa_lib.o: ../../include/openssl/ossl_typ.h
+fips_ecdsa_lib.o: ../../include/openssl/safestack.h
+fips_ecdsa_lib.o: ../../include/openssl/stack.h
+fips_ecdsa_lib.o: ../../include/openssl/symhacks.h fips_ecdsa_lib.c
+fips_ecdsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_ecdsa_sign.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_ecdsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_ecdsa_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+fips_ecdsa_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+fips_ecdsa_sign.o: ../../include/openssl/obj_mac.h
+fips_ecdsa_sign.o: ../../include/openssl/objects.h
+fips_ecdsa_sign.o: ../../include/openssl/opensslconf.h
+fips_ecdsa_sign.o: ../../include/openssl/opensslv.h
+fips_ecdsa_sign.o: ../../include/openssl/ossl_typ.h
+fips_ecdsa_sign.o: ../../include/openssl/safestack.h
+fips_ecdsa_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_ecdsa_sign.o: ../../include/openssl/symhacks.h fips_ecdsa_sign.c
+fips_ecdsavs.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_ecdsavs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_ecdsavs.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_ecdsavs.o: ../../include/openssl/ec.h ../../include/openssl/ecdsa.h
+fips_ecdsavs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_ecdsavs.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_ecdsavs.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_ecdsavs.o: ../../include/openssl/objects.h
+fips_ecdsavs.o: ../../include/openssl/opensslconf.h
+fips_ecdsavs.o: ../../include/openssl/opensslv.h
+fips_ecdsavs.o: ../../include/openssl/ossl_typ.h
+fips_ecdsavs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_ecdsavs.o: ../../include/openssl/symhacks.h fips_utl.h fips_ecdsavs.c
+fips_hmactest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_hmactest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_hmactest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_hmactest.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_hmactest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_hmactest.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_hmactest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_hmactest.o: ../../include/openssl/objects.h
+fips_hmactest.o: ../../include/openssl/opensslconf.h
+fips_hmactest.o: ../../include/openssl/opensslv.h
+fips_hmactest.o: ../../include/openssl/ossl_typ.h
+fips_hmactest.o: ../../include/openssl/safestack.h
+fips_hmactest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_hmactest.o: fips_utl.h fips_hmactest.c
+fips_drbg_ctr.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_ctr.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_ctr.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_drbg_ctr.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_drbg_ctr.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_drbg_ctr.o: ../../include/openssl/obj_mac.h
+fips_drbg_ctr.o: ../../include/openssl/objects.h
+fips_drbg_ctr.o: ../../include/openssl/opensslconf.h
+fips_drbg_ctr.o: ../../include/openssl/opensslv.h
+fips_drbg_ctr.o: ../../include/openssl/ossl_typ.h
+fips_drbg_ctr.o: ../../include/openssl/safestack.h
+fips_drbg_ctr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_drbg_ctr.o: fips_drbg_ctr.c fips_rand_lcl.h
+fips_drbg_ec.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_ec.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_drbg_ec.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_drbg_ec.o: ../../include/openssl/ec.h ../../include/openssl/evp.h
+fips_drbg_ec.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_drbg_ec.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
+fips_drbg_ec.o: ../../include/openssl/objects.h
+fips_drbg_ec.o: ../../include/openssl/opensslconf.h
+fips_drbg_ec.o: ../../include/openssl/opensslv.h
+fips_drbg_ec.o: ../../include/openssl/ossl_typ.h
+fips_drbg_ec.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_drbg_ec.o: ../../include/openssl/symhacks.h fips_drbg_ec.c fips_rand_lcl.h
+fips_drbg_hash.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_hash.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_hash.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_drbg_hash.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_drbg_hash.o: ../../include/openssl/fips_rand.h
+fips_drbg_hash.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
+fips_drbg_hash.o: ../../include/openssl/objects.h
+fips_drbg_hash.o: ../../include/openssl/opensslconf.h
+fips_drbg_hash.o: ../../include/openssl/opensslv.h
+fips_drbg_hash.o: ../../include/openssl/ossl_typ.h
+fips_drbg_hash.o: ../../include/openssl/safestack.h
+fips_drbg_hash.o: ../../include/openssl/stack.h
+fips_drbg_hash.o: ../../include/openssl/symhacks.h fips_drbg_hash.c
+fips_drbg_hash.o: fips_rand_lcl.h
+fips_drbg_hmac.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_hmac.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_drbg_hmac.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_drbg_hmac.o: ../../include/openssl/fips_rand.h
+fips_drbg_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
+fips_drbg_hmac.o: ../../include/openssl/objects.h
+fips_drbg_hmac.o: ../../include/openssl/opensslconf.h
+fips_drbg_hmac.o: ../../include/openssl/opensslv.h
+fips_drbg_hmac.o: ../../include/openssl/ossl_typ.h
+fips_drbg_hmac.o: ../../include/openssl/safestack.h
+fips_drbg_hmac.o: ../../include/openssl/stack.h
+fips_drbg_hmac.o: ../../include/openssl/symhacks.h fips_drbg_hmac.c
+fips_drbg_hmac.o: fips_rand_lcl.h
+fips_drbg_lib.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_lib.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_drbg_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_drbg_lib.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_drbg_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_drbg_lib.o: ../../include/openssl/objects.h
+fips_drbg_lib.o: ../../include/openssl/opensslconf.h
+fips_drbg_lib.o: ../../include/openssl/opensslv.h
+fips_drbg_lib.o: ../../include/openssl/ossl_typ.h
+fips_drbg_lib.o: ../../include/openssl/safestack.h
+fips_drbg_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_drbg_lib.o: fips_drbg_lib.c fips_rand_lcl.h
+fips_drbg_rand.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbg_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_drbg_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_drbg_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_drbg_rand.o: ../../include/openssl/fips_rand.h
+fips_drbg_rand.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_drbg_rand.o: ../../include/openssl/obj_mac.h
+fips_drbg_rand.o: ../../include/openssl/objects.h
+fips_drbg_rand.o: ../../include/openssl/opensslconf.h
+fips_drbg_rand.o: ../../include/openssl/opensslv.h
+fips_drbg_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_drbg_rand.o: ../../include/openssl/safestack.h
+fips_drbg_rand.o: ../../include/openssl/stack.h
+fips_drbg_rand.o: ../../include/openssl/symhacks.h fips_drbg_rand.c
+fips_drbg_rand.o: fips_rand_lcl.h
+fips_drbgvs.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_drbgvs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_drbgvs.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_drbgvs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_drbgvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_drbgvs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_drbgvs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_drbgvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_drbgvs.o: ../../include/openssl/opensslconf.h
+fips_drbgvs.o: ../../include/openssl/opensslv.h
+fips_drbgvs.o: ../../include/openssl/ossl_typ.h
+fips_drbgvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_drbgvs.o: ../../include/openssl/symhacks.h fips_utl.h fips_drbgvs.c
+fips_rand_lib.o: ../../e_os.h ../../include/openssl/aes.h
+fips_rand_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_rand_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rand_lib.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rand_lib.o: ../../include/openssl/objects.h
+fips_rand_lib.o: ../../include/openssl/opensslconf.h
+fips_rand_lib.o: ../../include/openssl/opensslv.h
+fips_rand_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_rand_lib.o: ../../include/openssl/safestack.h
+fips_rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rand_lib.o: fips_rand_lib.c
+fips_randtest.o: ../../e_os.h ../../include/openssl/aes.h
+fips_randtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_randtest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_randtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_randtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_randtest.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_randtest.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_randtest.o: ../../include/openssl/obj_mac.h
+fips_randtest.o: ../../include/openssl/objects.h
+fips_randtest.o: ../../include/openssl/opensslconf.h
+fips_randtest.o: ../../include/openssl/opensslv.h
+fips_randtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_randtest.o: ../../include/openssl/safestack.h
+fips_randtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_randtest.o: fips_utl.h fips_randtest.c
+fips_rngvs.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_rngvs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_rngvs.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_rngvs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_rngvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rngvs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_rngvs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_rngvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_rngvs.o: ../../include/openssl/opensslconf.h
+fips_rngvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_rngvs.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+fips_rngvs.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rngvs.o: fips_utl.h fips_rngvs.c
+fips_rsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsa_lib.o: ../../include/openssl/objects.h
+fips_rsa_lib.o: ../../include/openssl/opensslconf.h
+fips_rsa_lib.o: ../../include/openssl/opensslv.h
+fips_rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_rsa_lib.o: ../../include/openssl/symhacks.h fips_rsa_lib.c
+fips_rsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_rsa_sign.o: ../../include/openssl/obj_mac.h
+fips_rsa_sign.o: ../../include/openssl/objects.h
+fips_rsa_sign.o: ../../include/openssl/opensslconf.h
+fips_rsa_sign.o: ../../include/openssl/opensslv.h
+fips_rsa_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rsa_sign.o: fips_rsa_sign.c
+fips_rsagtest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_rsagtest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_rsagtest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rsagtest.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_rsagtest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsagtest.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_rsagtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsagtest.o: ../../include/openssl/objects.h
+fips_rsagtest.o: ../../include/openssl/opensslconf.h
+fips_rsagtest.o: ../../include/openssl/opensslv.h
+fips_rsagtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsagtest.o: ../../include/openssl/safestack.h
+fips_rsagtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rsagtest.o: fips_utl.h fips_rsagtest.c
+fips_rsastest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_rsastest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_rsastest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rsastest.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_rsastest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsastest.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_rsastest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsastest.o: ../../include/openssl/objects.h
+fips_rsastest.o: ../../include/openssl/opensslconf.h
+fips_rsastest.o: ../../include/openssl/opensslv.h
+fips_rsastest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsastest.o: ../../include/openssl/safestack.h
+fips_rsastest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rsastest.o: fips_utl.h fips_rsastest.c
+fips_rsavtest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_rsavtest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_rsavtest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rsavtest.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_rsavtest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsavtest.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_rsavtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsavtest.o: ../../include/openssl/objects.h
+fips_rsavtest.o: ../../include/openssl/opensslconf.h
+fips_rsavtest.o: ../../include/openssl/opensslv.h
+fips_rsavtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsavtest.o: ../../include/openssl/safestack.h
+fips_rsavtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rsavtest.o: fips_utl.h fips_rsavtest.c
+fips_shatest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_shatest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_shatest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_shatest.o: ../../include/openssl/ec.h ../../include/openssl/err.h
+fips_shatest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_shatest.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h
+fips_shatest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_shatest.o: ../../include/openssl/objects.h
+fips_shatest.o: ../../include/openssl/opensslconf.h
+fips_shatest.o: ../../include/openssl/opensslv.h
+fips_shatest.o: ../../include/openssl/ossl_typ.h
+fips_shatest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_shatest.o: ../../include/openssl/symhacks.h fips_utl.h fips_shatest.c
+fips_standalone_sha1.o: ../../include/openssl/asn1.h
+fips_standalone_sha1.o: ../../include/openssl/bio.h
+fips_standalone_sha1.o: ../../include/openssl/crypto.h
+fips_standalone_sha1.o: ../../include/openssl/e_os2.h
+fips_standalone_sha1.o: ../../include/openssl/evp.h
+fips_standalone_sha1.o: ../../include/openssl/fips.h
+fips_standalone_sha1.o: ../../include/openssl/hmac.h
+fips_standalone_sha1.o: ../../include/openssl/obj_mac.h
+fips_standalone_sha1.o: ../../include/openssl/objects.h
+fips_standalone_sha1.o: ../../include/openssl/opensslconf.h
+fips_standalone_sha1.o: ../../include/openssl/opensslv.h
+fips_standalone_sha1.o: ../../include/openssl/ossl_typ.h
+fips_standalone_sha1.o: ../../include/openssl/safestack.h
+fips_standalone_sha1.o: ../../include/openssl/sha.h
+fips_standalone_sha1.o: ../../include/openssl/stack.h
+fips_standalone_sha1.o: ../../include/openssl/symhacks.h fips_standalone_sha1.c
+fips_tlsvs.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
+fips_tlsvs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_tlsvs.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_tlsvs.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+fips_tlsvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_tlsvs.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_tlsvs.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+fips_tlsvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_tlsvs.o: ../../include/openssl/opensslconf.h
+fips_tlsvs.o: ../../include/openssl/opensslv.h
+fips_tlsvs.o: ../../ssl/ssl.h
+fips_tlsvs.o: ../../include/openssl/opensslv.h
+fips_tlsvs.o: ../../include/openssl/ossl_typ.h
+fips_tlsvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_tlsvs.o: ../../include/openssl/symhacks.h fips_utl.h fips_tlsvs.c
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
Index: openssl-1.0.2j/crypto/fips/fips_aesavs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_aesavs.c	2017-03-16 17:50:12.010613586 +0100
@@ -0,0 +1,936 @@
+/* ====================================================================
+ * 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.
+  ----------------------------------------------*/
+
+#define OPENSSL_FIPSAPI
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+#include <openssl/err.h>
+#include "e_os.h"
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+    printf("No FIPS AES support\n");
+    return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+#define AES_BLOCK_SIZE 16
+
+#define VERBOSE 0
+
+/*-----------------------------------------------*/
+
+static 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 (fips_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 (fips_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 (fips_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 (fips_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(!fips_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(!fips_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 (FIPS_cipherinit(ctx, cipher, aKey, iVec, dir) <= 0)
+	return 0;
+    if(!fips_strcasecmp(amode,"CFB1"))
+	M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
+    if (dir)
+		FIPS_cipher(ctx, ciphertext, plaintext, len);
+	else
+		FIPS_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)))
+
+static 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;
+    FIPS_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" RESP_EOL ,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)
+			{
+			FIPS_cipher(&ctx, ctext[j], ptext[j], len);
+			memcpy(ptext[j+1], ctext[j], len);
+			}
+		    else
+			{
+			FIPS_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)
+			{
+			FIPS_cipher(&ctx, ctext[j], ptext[j], len);
+			memcpy(ptext[j+1], ctext[j-1], len);
+			}
+		    else
+			{
+			FIPS_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)
+			FIPS_cipher(&ctx, ctext[j], ptext[j], len);
+		    else
+			FIPS_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)
+			FIPS_cipher(&ctx, ctext[j], ptext[j], len);
+		    else
+			FIPS_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, RESP_EOL);  /* 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;
+		}
+	    }
+	}
+    FIPS_cipher_ctx_cleanup(&ctx);
+    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
+  ----------------------------*/
+
+static int proc_file(char *rqfile, char *rspfile)
+    {
+    char afn[256], rfn[256];
+    FILE *afp = NULL, *rfp = NULL;
+    char ibuf[2048];
+    char tbuf[2048];
+    int len;
+    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;
+    FIPS_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);
+	/*      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
+		    {
+		    copy_line(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)
+		    {
+		    copy_line(ibuf, rfp);
+		    }
+		else
+		    {
+		    copy_line(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 (fips_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] == '[')
+		{
+		copy_line(ibuf, rfp);
+		++step;
+		if (fips_strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
+		    dir = 1;
+		else if (fips_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 */
+	    copy_line(ibuf, rfp);
+	    if(*ibuf == '\n')
+		break;
+	    if(!fips_strncasecmp(ibuf,"COUNT = ",8))
+		break;
+
+	    if (fips_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 */
+	    copy_line(ibuf, rfp);
+	    if (fips_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 */
+	    copy_line(ibuf, rfp);
+	    if (fips_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 >= (int)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)
+			err = 1;
+		    }
+		else
+		    {
+		    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 */
+	    copy_line(ibuf, rfp);
+	    if (fips_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
+		    {
+		    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 */
+		copy_line(ibuf, rfp);
+		}
+	    step = 1;
+	    break;
+	    }
+	}
+    if (rfp)
+	fclose(rfp);
+    if (afp)
+	fclose(afp);
+    FIPS_cipher_ctx_cleanup(&ctx);
+    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
+--------------------------------------------------*/
+#ifdef FIPS_ALGVS
+int fips_aesavs_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+    {
+    char *rqlist = "req.txt", *rspfile = NULL;
+    FILE *fp = NULL;
+    char fn[250] = "", rfn[256] = "";
+    int d_opt = 1;
+    fips_algtest_init();
+
+    if (argc > 1)
+	{
+	if (fips_strcasecmp(argv[1], "-d") == 0)
+	    {
+	    d_opt = 1;
+	    }
+	else if (fips_strcasecmp(argv[1], "-f") == 0)
+	    {
+	    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);
+		return 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);
+	    }
+	}
+    return 0;
+    }
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_cmactest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_cmactest.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,522 @@
+/* fips_cmactest.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).
+ *
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+    printf("No FIPS CMAC support\n");
+    return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+static int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in,
+	int mode, int Klen_counts_keys, int known_keylen);
+static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
+		unsigned char *Key, int Klen,
+		unsigned char *Msg, int Msglen,
+		int Tlen);
+static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
+		unsigned char *Key, int Klen,
+		unsigned char *Msg, int Msglen,
+		unsigned char *Mac, int Maclen,
+		int Tlen);
+
+#ifdef FIPS_ALGVS
+int fips_cmactest_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+	{
+	FILE *in = NULL, *out = NULL;
+	int mode = 0;		/* 0 => Generate, 1 => Verify */
+	int Klen_counts_keys = 0; /* 0 => Klen is size of one key
+				     1 => Klen is amount of keys
+				  */
+	int known_keylen = 0;	/* Only set when Klen_counts_keys = 1 */
+	const EVP_CIPHER *cipher = 0;
+	int ret = 1;
+	fips_algtest_init_nofips();
+	if(!FIPS_mode_set(1)) {
+		fprintf(stderr, "Can't set FIPS mode\n");
+		exit(1);
+	}
+
+
+	while (argc > 1 && argv[1][0] == '-')
+		{
+		switch (argv[1][1])
+			{
+		case 'a':
+			{
+			char *p = &argv[1][2];
+			if (*p == '\0')
+				{
+				if (argc <= 2)
+					{
+					fprintf(stderr, "Option %s needs a value\n", argv[1]);
+					goto end;
+					}
+				argv++;
+				argc--;
+				p = &argv[1][0];
+				}
+			if (!strcmp(p, "aes128"))
+				cipher = EVP_aes_128_cbc();
+			else if (!strcmp(p, "aes192"))
+				cipher = EVP_aes_192_cbc();
+			else if (!strcmp(p, "aes256"))
+				cipher = EVP_aes_256_cbc();
+			else if (!strcmp(p, "tdea3") || !strcmp(p, "tdes3"))
+				{
+				cipher = EVP_des_ede3_cbc();
+				Klen_counts_keys = 1;
+				known_keylen = 8;
+				}
+			else
+				{
+				fprintf(stderr, "Unknown algorithm %s\n", p);
+				goto end;
+				}
+			}
+			break;
+		case 'g':
+			mode = 0;
+			break;
+		case 'v':
+			mode = 1;
+			break;
+		default:
+			fprintf(stderr, "Unknown option %s\n", argv[1]);
+			goto end;
+			}
+		argv++;
+		argc--;
+		}
+	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 (!cmac_test(cipher, out, in, mode,
+			Klen_counts_keys, known_keylen))
+		{
+		fprintf(stderr, "FATAL cmac file processing error\n");
+		goto end;
+		}
+	else
+		ret = 0;
+
+	end:
+
+	if (in && (in != stdin))
+		fclose(in);
+	if (out && (out != stdout))
+		fclose(out);
+
+	return ret;
+
+	}
+
+#define CMAC_TEST_MAXLINELEN	150000
+
+int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in,
+	int mode, int Klen_counts_keys, int known_keylen)
+	{
+	char *linebuf, *olinebuf, *p, *q;
+	char *keyword, *value;
+	unsigned char **Keys = NULL, *Msg = NULL, *Mac = NULL;
+	unsigned char *Key = NULL;
+	int Count, Klen, Mlen, Tlen;
+	long Keylen, Msglen, Maclen;
+	int ret = 0;
+	int lnum = 0;
+
+	olinebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
+	linebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
+
+	if (!linebuf || !olinebuf)
+		goto error;
+
+	Count = -1;
+	Klen = -1;
+	Mlen = -1;
+	Tlen = -1;
+
+	while (fgets(olinebuf, CMAC_TEST_MAXLINELEN, in))
+		{
+		lnum++;
+		strcpy(linebuf, olinebuf);
+		keyword = linebuf;
+		/* Skip leading space */
+		while (isspace((unsigned char)*keyword))
+			keyword++;
+
+		/* Skip comments */
+		if (keyword[0] == '#')
+			{
+			if (fputs(olinebuf, out) < 0)
+				goto error;
+			continue;
+			}
+
+		/* Look for = sign */
+		p = strchr(linebuf, '=');
+
+		/* If no = or starts with [ (for [L=20] line) 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;
+
+		if (!strcmp(keyword, "Count"))
+			{
+			if (Count != -1)
+				goto parse_error;
+			Count = atoi(value);
+			if (Count < 0)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Klen"))
+			{
+			if (Klen != -1)
+				goto parse_error;
+			Klen = atoi(value);
+			if (Klen < 0)
+				goto parse_error;
+			if (Klen_counts_keys)
+				{
+				Keys = OPENSSL_malloc(sizeof(*Keys) * Klen);
+				memset(Keys, '\0', sizeof(*Keys) * Klen);
+				}
+			else
+				{
+				Keys = OPENSSL_malloc(sizeof(*Keys));
+				memset(Keys, '\0', sizeof(*Keys));
+				}
+			}
+		else if (!strcmp(keyword, "Mlen"))
+			{
+			if (Mlen != -1)
+				goto parse_error;
+			Mlen = atoi(value);
+			if (Mlen < 0)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Tlen"))
+			{
+			if (Tlen != -1)
+				goto parse_error;
+			Tlen = atoi(value);
+			if (Tlen < 0)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Key") && !Klen_counts_keys)
+			{
+			if (Keys[0])
+				goto parse_error;
+			Keys[0] = hex2bin_m(value, &Keylen);
+			if (!Keys[0])
+				goto parse_error;
+			}
+		else if (!strncmp(keyword, "Key", 3) && Klen_counts_keys)
+			{
+			int keynum = atoi(keyword + 3);
+			if (!keynum || keynum > Klen || Keys[keynum-1])
+				goto parse_error;
+			Keys[keynum-1] = hex2bin_m(value, &Keylen);
+			if (!Keys[keynum-1])
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Msg"))
+			{
+			if (Msg)
+				goto parse_error;
+			Msg = hex2bin_m(value, &Msglen);
+			if (!Msg)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Mac"))
+			{
+			if (mode == 0)
+				continue;
+			if (Mac)
+				goto parse_error;
+			Mac = hex2bin_m(value, &Maclen);
+			if (!Mac)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Result"))
+			{
+			if (mode == 1)
+				continue;
+			goto parse_error;
+			}
+		else
+			goto parse_error;
+
+		fputs(olinebuf, out);
+
+		if (Keys && Msg && (!mode || Mac) && (Tlen > 0) && (Klen > 0))
+			{
+			if (Klen_counts_keys)
+				{
+				int x;
+				Key = OPENSSL_malloc(Klen * known_keylen);
+				for (x = 0; x < Klen; x++)
+					{
+					memcpy(Key + x * known_keylen,
+						Keys[x], known_keylen);
+					OPENSSL_free(Keys[x]);
+					}
+				Klen *= known_keylen;
+				}
+			else
+				{
+				Key = OPENSSL_malloc(Klen);
+				memcpy(Key, Keys[0], Klen);
+				OPENSSL_free(Keys[0]);
+				}
+			OPENSSL_free(Keys);
+
+			switch(mode)
+				{
+			case 0:
+				if (!print_cmac_gen(cipher, out,
+						Key, Klen,
+						Msg, Mlen,
+						Tlen))
+					goto error;
+				break;
+			case 1:
+				if (!print_cmac_ver(cipher, out,
+						Key, Klen,
+						Msg, Mlen,
+						Mac, Maclen,
+						Tlen))
+					goto error;
+				break;
+				}
+
+			OPENSSL_free(Key);
+			Key = NULL;
+			OPENSSL_free(Msg);
+			Msg = NULL;
+			OPENSSL_free(Mac);
+			Mac = NULL;
+			Klen = -1;
+			Mlen = -1;
+			Tlen = -1;
+			Count = -1;
+			}
+		}
+
+
+	ret = 1;
+
+
+	error:
+
+	if (olinebuf)
+		OPENSSL_free(olinebuf);
+	if (linebuf)
+		OPENSSL_free(linebuf);
+	if (Key)
+		OPENSSL_free(Key);
+	if (Msg)
+		OPENSSL_free(Msg);
+	if (Mac)
+		OPENSSL_free(Mac);
+
+	return ret;
+
+	parse_error:
+
+	fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
+
+	goto error;
+
+	}
+
+static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
+		unsigned char *Key, int Klen,
+		unsigned char *Msg, int Mlen,
+		int Tlen)
+	{
+	int rc, i;
+	size_t reslen;
+	unsigned char res[128];
+	CMAC_CTX *cmac_ctx = CMAC_CTX_new();
+
+	CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
+	CMAC_Update(cmac_ctx, Msg, Mlen);
+	if (!CMAC_Final(cmac_ctx, res, &reslen))
+		{
+		fputs("Error calculating CMAC\n", stderr);
+		rc = 0;
+		}
+	else if (Tlen > (int)reslen)
+		{
+		fputs("Parameter error, Tlen > CMAC length\n", stderr);
+		rc = 0;
+		}
+	else
+		{
+		fputs("Mac = ", out);
+		for (i = 0; i < Tlen; i++)
+			fprintf(out, "%02x", res[i]);
+		fputs(RESP_EOL, out);
+		rc = 1;
+		}
+	CMAC_CTX_free(cmac_ctx);
+	return rc;
+	}
+
+static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
+		unsigned char *Key, int Klen,
+		unsigned char *Msg, int Mlen,
+		unsigned char *Mac, int Maclen,
+		int Tlen)
+	{
+	int rc = 1;
+	size_t reslen;
+	unsigned char res[128];
+	CMAC_CTX *cmac_ctx = CMAC_CTX_new();
+
+	CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
+	CMAC_Update(cmac_ctx, Msg, Mlen);
+	if (!CMAC_Final(cmac_ctx, res, &reslen))
+		{
+		fputs("Error calculating CMAC\n", stderr);
+		rc = 0;
+		}
+	else if (Tlen > (int)reslen)
+		{
+		fputs("Parameter error, Tlen > CMAC length\n", stderr);
+		rc = 0;
+		}
+	else if (Tlen != Maclen)
+		{
+		fputs("Parameter error, Tlen != resulting Mac length\n", stderr);
+		rc = 0;
+		}
+	else
+		{
+		if (!memcmp(Mac, res, Maclen))
+			fputs("Result = P" RESP_EOL, out);
+		else
+			fputs("Result = F" RESP_EOL, out);
+		}
+	CMAC_CTX_free(cmac_ctx);
+	return rc;
+	}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_desmovs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_desmovs.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,704 @@
+/* ====================================================================
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#include <openssl/des.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+#include <openssl/err.h>
+#include "e_os.h"
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+    printf("No FIPS DES support\n");
+    return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#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
Index: openssl-1.0.2j/crypto/fips/fips_dhvs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_dhvs.c	2017-03-17 14:15:25.151327074 +0100
@@ -0,0 +1,338 @@
+/* fips/dh/fips_dhvs.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#define OPENSSL_FIPSAPI
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("No FIPS DH support\n");
+    return(0);
+}
+#else
+
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "fips_utl.h"
+
+/* Minimal FIPS versions of FIPS_dh_new() and FIPS_dh_free(): to
+ * reduce external dependencies.
+ */
+
+DH *FIPS_dh_new(void)
+	{
+	DH *ret;
+	ret = OPENSSL_malloc(sizeof(DH));
+	if (!ret)
+		return NULL;
+	memset(ret, 0, sizeof(DH));
+	ret->meth = DH_OpenSSL();
+	if (ret->meth->init)
+		ret->meth->init(ret);
+	return ret;
+	}
+
+void FIPS_dh_free(DH *r)
+	{
+	if (!r)
+		return;
+	if (r->meth->finish)
+		r->meth->finish(r);
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->g != NULL) BN_clear_free(r->g);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->j != NULL) BN_clear_free(r->j);
+	if (r->seed) OPENSSL_free(r->seed);
+	if (r->counter != NULL) BN_clear_free(r->counter);
+	if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+	if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+	OPENSSL_free(r);
+	}
+
+static const EVP_MD *parse_md(char *line)
+	{
+	char *p;
+	if (line[0] != '[' || line[1] != 'F')
+		return NULL;
+	p = strchr(line, '-');
+	if (!p)
+		return NULL;
+	line = p + 1;
+	p = strchr(line, ']');
+	if (!p)
+		return NULL;
+	*p = 0;
+	p = line;
+	while(isspace(*p))
+		p++;
+	if (!strcmp(p, "SHA1"))
+		return EVP_sha1();
+	else if (!strcmp(p, "SHA224"))
+		return EVP_sha224();
+	else if (!strcmp(p, "SHA256"))
+		return EVP_sha256();
+	else if (!strcmp(p, "SHA384"))
+		return EVP_sha384();
+	else if (!strcmp(p, "SHA512"))
+		return EVP_sha512();
+	else
+		return NULL;
+	}
+
+static void output_Zhash(FILE *out, int exout,
+				DH *dh, BIGNUM *peerkey, const EVP_MD *md,
+				unsigned char *rhash, size_t rhashlen)
+	{
+	unsigned char *Z;
+	unsigned char chash[EVP_MAX_MD_SIZE];
+	int Zlen, hashlen;
+	if (rhash == NULL)
+		{
+		rhashlen = M_EVP_MD_size(md);
+		if (!DH_generate_key(dh))
+			exit (1);
+		do_bn_print_name(out, "YephemIUT", dh->pub_key);
+		if (exout)
+			do_bn_print_name(out, "XephemIUT", dh->priv_key);
+		}
+	hashlen = BN_num_bytes(dh->p);
+	Z = OPENSSL_malloc(hashlen);
+	if (!Z)
+		exit(1);
+	Zlen = DH_compute_key_padded(Z, peerkey, dh);
+
+	if (exout && Zlen >= 0)
+		OutputValue("Z", Z, Zlen, out, 0);
+
+	if (Zlen > 0) {
+		FIPS_digest(Z, hashlen, chash, NULL, md);
+	} else {
+		/* even in failure, print out IUTHashZZ / HashZZ */
+		if (rhash) memcpy(chash, rhash, rhashlen);
+	}
+	OutputValue(rhash ? "IUTHashZZ" : "HashZZ", chash, rhashlen, out, 0);
+	if (rhash)
+		{
+		fprintf(out, "Result = %s\n",
+				(Zlen < 0) ? "F": (memcmp(chash, rhash, rhashlen) ? "F" : "P"));
+		}
+	else
+		{
+		BN_clear_free(dh->priv_key);
+		BN_clear_free(dh->pub_key);
+		dh->priv_key = NULL;
+		dh->pub_key = NULL;
+		}
+	OPENSSL_cleanse(Z, hashlen);
+	OPENSSL_free(Z);
+	}
+
+#ifdef FIPS_ALGVS
+int fips_dhvs_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+	{
+	char **args = argv + 1;
+	int argn = argc - 1;
+	FILE *in, *out;
+	char buf[2048], lbuf[2048];
+	unsigned char *rhash;
+	long rhashlen;
+	DH *dh = NULL;
+	const EVP_MD *md = NULL;
+	BIGNUM *peerkey = NULL;
+	char *keyword = NULL, *value = NULL;
+	int do_verify = -1, exout = 0;
+
+	fips_algtest_init_nofips();
+	if(!FIPS_mode_set(1)) {
+		fprintf(stderr, "Can't set FIPS mode\n");
+		exit(1);
+	}
+
+	if (argn && !strcmp(*args, "dhver"))
+		{
+		do_verify = 1;
+		args++;
+		argn--;
+		}
+	else if (argn && !strcmp(*args, "dhgen"))
+		{
+		do_verify = 0;
+		args++;
+		argn--;
+		}
+
+	if (argn && !strcmp(*args, "-exout"))
+		{
+		exout = 1;
+		args++;
+		argn--;
+		}
+
+	if (do_verify == -1)
+		{
+		fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]);
+		exit(1);
+		}
+
+	if (argn == 2)
+		{
+		in = fopen(*args, "r");
+		if (!in)
+			{
+			fprintf(stderr, "Error opening input file\n");
+			exit(1);
+			}
+		out = fopen(args[1], "w");
+		if (!out)
+			{
+			fprintf(stderr, "Error opening output file\n");
+			exit(1);
+			}
+		}
+	else if (argn == 0)
+		{
+		in = stdin;
+		out = stdout;
+		}
+	else
+		{
+		fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]);
+		exit(1);
+		}
+
+	dh = FIPS_dh_new();
+
+	while (fgets(buf, sizeof(buf), in) != NULL)
+		{
+		fputs(buf, out);
+		if (strlen(buf) > 6 && !strncmp(buf, "[F", 2))
+			{
+			md = parse_md(buf);
+			if (md == NULL)
+				goto parse_error;
+			if (dh)
+				FIPS_dh_free(dh);
+			dh = FIPS_dh_new();
+			continue;
+			}
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+		if (!strcmp(keyword, "P"))
+			{
+			if (!do_hex2bn(&dh->p, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Q"))
+			{
+			if (!do_hex2bn(&dh->q, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "G"))
+			{
+			if (!do_hex2bn(&dh->g, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "XephemIUT"))
+			{
+			if (!do_hex2bn(&dh->priv_key, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "YephemIUT"))
+			{
+			if (!do_hex2bn(&dh->pub_key, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "YephemCAVS"))
+			{
+			if (!do_hex2bn(&peerkey, value))
+				goto parse_error;
+			if (do_verify == 0)
+				output_Zhash(out, exout, dh, peerkey, md,
+							NULL, 0);
+			}
+		else if (!strcmp(keyword, "CAVSHashZZ"))
+			{
+			if (!md)
+				goto parse_error;
+			rhash = hex2bin_m(value, &rhashlen);
+			if (!rhash || rhashlen != M_EVP_MD_size(md))
+				goto parse_error;
+			output_Zhash(out, exout, dh, peerkey, md,
+							rhash, rhashlen);
+			}
+		}
+	if (in && in != stdin)
+		fclose(in);
+	if (out && out != stdout)
+		fclose(out);
+	return 0;
+	parse_error:
+	fprintf(stderr, "Error Parsing request file\n");
+	exit(1);
+	}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_drbgvs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_drbgvs.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,436 @@
+/* fips/rand/fips_drbgvs.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#define OPENSSL_FIPSAPI
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("No FIPS DRBG support\n");
+    return(0);
+}
+#else
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "fips_utl.h"
+
+static int dparse_md(char *str)
+	{
+	switch(atoi(str + 5))
+		{
+		case 1:
+		return NID_sha1;
+
+		case 224:
+		return NID_sha224;
+
+		case 256:
+		return NID_sha256;
+
+		case 384:
+		return NID_sha384;
+
+		case 512:
+		return NID_sha512;
+
+		}
+
+	return NID_undef;
+	}
+
+static int parse_ec(char *str)
+	{
+	int curve_nid, md_nid;
+	char *md;
+	md = strchr(str, ' ');
+	if (!md)
+		return NID_undef;
+	if (!strncmp(str, "[P-256", 6))
+		curve_nid = NID_X9_62_prime256v1;
+	else if (!strncmp(str, "[P-384", 6))
+		curve_nid = NID_secp384r1;
+	else if (!strncmp(str, "[P-521", 6))
+		curve_nid = NID_secp521r1;
+	else
+		return NID_undef;
+	md_nid = dparse_md(md);
+	if (md_nid == NID_undef)
+		return NID_undef;
+	return (curve_nid << 16) | md_nid;
+	}
+
+static int parse_aes(char *str, int *pdf)
+	{
+
+	if (!strncmp(str + 9, "no", 2))
+		*pdf = 0;
+	else
+		*pdf = DRBG_FLAG_CTR_USE_DF;
+
+	switch(atoi(str + 5))
+		{
+		case 128:
+		return NID_aes_128_ctr;
+
+		case 192:
+		return NID_aes_192_ctr;
+
+		case 256:
+		return NID_aes_256_ctr;
+
+		default:
+		return NID_undef;
+
+		}
+	}
+
+typedef struct 
+	{
+	unsigned char *ent;
+	size_t entlen;
+	unsigned char *nonce;
+	size_t noncelen;
+	} TEST_ENT;
+
+static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout,
+                                int entropy, size_t min_len, size_t max_len)
+	{
+	TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
+	*pout = (unsigned char *)t->ent;
+	return t->entlen;
+	}
+
+static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout,
+                                int entropy, size_t min_len, size_t max_len)
+	{
+	TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
+	*pout = (unsigned char *)t->nonce;
+	return t->noncelen;
+	}
+
+#ifdef FIPS_ALGVS
+int fips_drbgvs_main(int argc,char **argv)
+#else
+int main(int argc,char **argv)
+#endif
+	{
+	FILE *in = NULL, *out = NULL;
+	DRBG_CTX *dctx = NULL;
+	TEST_ENT t;
+	int r, nid = 0;
+	int pr = 0;
+	char buf[2048], lbuf[2048];
+	unsigned char randout[2048];
+	char *keyword = NULL, *value = NULL;
+
+	unsigned char *ent = NULL, *nonce = NULL, *pers = NULL, *adin = NULL;
+	long entlen, noncelen, perslen, adinlen;
+	int df = 0;
+
+	enum dtype { DRBG_NONE, DRBG_CTR, DRBG_HASH, DRBG_HMAC, DRBG_DUAL_EC }
+		drbg_type = DRBG_NONE;
+
+	int randoutlen = 0;
+
+	int gen = 0;
+
+	fips_algtest_init_nofips();
+	if(!FIPS_mode_set(1)) {
+		fprintf(stderr, "Can't set FIPS mode\n");
+		exit(1);
+	}
+
+	if (argc == 3)
+		{
+		in = fopen(argv[1], "r");
+		if (!in)
+			{
+			fprintf(stderr, "Error opening input file\n");
+			exit(1);
+			}
+		out = fopen(argv[2], "w");
+		if (!out)
+			{
+			fprintf(stderr, "Error opening output file\n");
+			exit(1);
+			}
+		}
+	else if (argc == 1)
+		{
+		in = stdin;
+		out = stdout;
+		}
+	else
+		{
+		fprintf(stderr,"%s (infile outfile)\n",argv[0]);
+		exit(1);
+		}
+
+	while (fgets(buf, sizeof(buf), in) != NULL)
+		{
+		fputs(buf, out);
+		if (drbg_type == DRBG_NONE)
+			{
+			if (strstr(buf, "CTR_DRBG"))
+				drbg_type = DRBG_CTR;
+			else if (strstr(buf, "Hash_DRBG"))
+				drbg_type = DRBG_HASH;
+			else if (strstr(buf, "HMAC_DRBG"))
+				drbg_type = DRBG_HMAC;
+			else if (strstr(buf, "Dual_EC_DRBG"))
+				drbg_type = DRBG_DUAL_EC;
+			else
+				continue;
+			}
+		if (strlen(buf) > 4 && !strncmp(buf, "[SHA-", 5))
+			{
+			nid = dparse_md(buf);
+			if (nid == NID_undef)
+				exit(1);
+			if (drbg_type == DRBG_HMAC)
+				{
+				switch (nid)
+					{
+					case NID_sha1:
+					nid = NID_hmacWithSHA1;
+					break;
+
+					case NID_sha224:
+					nid = NID_hmacWithSHA224;
+					break;
+
+					case NID_sha256:
+					nid = NID_hmacWithSHA256;
+					break;
+
+					case NID_sha384:
+					nid = NID_hmacWithSHA384;
+					break;
+
+					case NID_sha512:
+					nid = NID_hmacWithSHA512;
+					break;
+
+					default:
+					exit(1);
+					}
+				}
+			}
+		if (strlen(buf) > 12 && !strncmp(buf, "[AES-", 5))
+			{
+			nid = parse_aes(buf, &df);
+			if (nid == NID_undef)
+				exit(1);
+			}
+		if (strlen(buf) > 12 && !strncmp(buf, "[P-", 3))
+			{
+			nid = parse_ec(buf);
+			if (nid == NID_undef)
+				exit(1);
+			}
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+
+		if (!strcmp(keyword, "[PredictionResistance"))
+			{
+			if (!strcmp(value, "True]"))
+				pr = 1;
+			else if (!strcmp(value, "False]"))
+				pr = 0;
+			else
+				exit(1);
+			}
+
+		if (!strcmp(keyword, "[ReturnedBitsLen"))
+			{
+			errno = 0;
+			randoutlen = strtol(value, NULL, 10);
+			if (errno || randoutlen % 8)
+				{
+				fprintf(stderr, "Invalid ReturnedBitsLen!\n");
+				exit(1);
+				}
+
+			/* ReturnedBitsLen is in bits */
+			randoutlen /= 8;
+			}
+
+		if (!strcmp(keyword, "EntropyInput"))
+			{
+			ent = hex2bin_m(value, &entlen);
+			t.ent = ent;
+			t.entlen = entlen;
+			}
+
+		if (!strcmp(keyword, "Nonce"))
+			{
+			nonce = hex2bin_m(value, &noncelen);
+			t.nonce = nonce;
+			t.noncelen = noncelen;
+			}
+
+		if (!strcmp(keyword, "PersonalizationString"))
+			{
+			pers = hex2bin_m(value, &perslen);
+			if (nid == 0)
+				{
+				fprintf(stderr, "DRBG type not recognised!\n");
+				exit (1);
+				}
+			dctx = FIPS_drbg_new(nid, df | DRBG_FLAG_TEST);
+			if (!dctx)
+				exit (1);
+			FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0,
+							test_nonce, 0);
+			FIPS_drbg_set_app_data(dctx, &t);
+			if (!randoutlen)
+				randoutlen = (int)FIPS_drbg_get_blocklength(dctx);
+			r = FIPS_drbg_instantiate(dctx, pers, perslen);
+			if (!r)
+				{
+				fprintf(stderr, "Error instantiating DRBG\n");
+				exit(1);
+				}
+			OPENSSL_free(pers);
+			OPENSSL_free(ent);
+			OPENSSL_free(nonce);
+			ent = nonce = pers = NULL;
+			gen = 0;
+			}
+
+		if (!strcmp(keyword, "AdditionalInput"))
+			{
+			adin = hex2bin_m(value, &adinlen);
+			if (pr)
+				continue;
+			r = FIPS_drbg_generate(dctx, randout, randoutlen, 0,
+								adin, adinlen);
+			if (!r)
+				{
+				fprintf(stderr, "Error generating DRBG bits\n");
+				exit(1);
+				}
+			if (!r)
+				exit(1);
+			OPENSSL_free(adin);
+			adin = NULL;
+			gen++;
+			}
+
+		if (pr)
+			{
+			if (!strcmp(keyword, "EntropyInputPR"))
+				{
+				ent = hex2bin_m(value, &entlen);
+				t.ent = ent;
+				t.entlen = entlen;
+				r = FIPS_drbg_generate(dctx,
+							randout, randoutlen,
+							1, adin, adinlen);
+				if (!r)
+					{
+					fprintf(stderr,
+						"Error generating DRBG bits\n");
+					exit(1);
+					}
+				OPENSSL_free(adin);
+				OPENSSL_free(ent);
+				adin = ent = NULL;
+				gen++;
+				}
+			}
+		if (!strcmp(keyword, "EntropyInputReseed"))
+			{
+			ent = hex2bin_m(value, &entlen);
+			t.ent = ent;
+			t.entlen = entlen;
+			}
+		if (!strcmp(keyword, "AdditionalInputReseed"))
+			{
+			adin = hex2bin_m(value, &adinlen);
+			FIPS_drbg_reseed(dctx, adin, adinlen);
+			OPENSSL_free(ent);
+			OPENSSL_free(adin);
+			ent = adin = NULL;
+			}
+		if (gen == 2)
+			{
+			OutputValue("ReturnedBits", randout, randoutlen,
+									out, 0);
+			FIPS_drbg_free(dctx);
+			dctx = NULL;
+			gen = 0;
+			}
+
+		}
+	if (in && in != stdin)
+		fclose(in);
+	if (out && out != stdout)
+		fclose(out);
+	return 0;
+	}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_dsa_lib.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_dsa_lib.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,129 @@
+/* fips_dsa_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * 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
+ *    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).
+ *
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <string.h>
+#include <openssl/dsa.h>
+#include <openssl/bn.h>
+#include <openssl/fips.h>
+
+/* Minimal FIPS versions of FIPS_dsa_new() and FIPS_dsa_free: to
+ * reduce external dependencies.
+ */
+
+DSA *FIPS_dsa_new(void)
+	{
+	return DSA_new_method(NULL);
+#if 0
+	/* this is too minimalistic for the testcase */
+	DSA *ret;
+	ret = OPENSSL_malloc(sizeof(DSA));
+	if (!ret)
+		return NULL;
+	memset(ret, 0, sizeof(DSA));
+	ret->meth = DSA_OpenSSL();
+	if (ret->meth->init)
+		ret->meth->init(ret);
+	return ret;
+#endif
+	}
+
+void FIPS_dsa_free(DSA *r)
+	{
+	if (!r)
+		return;
+	DSA_free(r);
+#if 0
+	/* this is too minimalistic for the testcase */
+	if (r->meth->finish)
+		r->meth->finish(r);
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->g != NULL) BN_clear_free(r->g);
+	if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+	if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+	if (r->kinv != NULL) BN_clear_free(r->kinv);
+	if (r->r != NULL) BN_clear_free(r->r);
+	OPENSSL_free(r);
+#endif
+	}
+
+DSA_SIG *FIPS_dsa_sig_new(void)
+	{
+	DSA_SIG *sig;
+	sig = OPENSSL_malloc(sizeof(DSA_SIG));
+	if (!sig)
+		return NULL;
+	sig->r = NULL;
+	sig->s = NULL;
+	return sig;
+	}
+
+void FIPS_dsa_sig_free(DSA_SIG *sig)
+	{
+	if (sig)
+		{
+		if (sig->r)
+			BN_free(sig->r);
+		if (sig->s)
+			BN_free(sig->s);
+		OPENSSL_free(sig);
+		}
+	}
+
Index: openssl-1.0.2j/crypto/fips/fips_dsa_sign.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_dsa_sign.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,141 @@
+/* fips_dsa_sign.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_FIPS
+
+/* FIPS versions of DSA_sign() and DSA_verify().
+ * Handle DSA_SIG structures to avoid need to handle ASN1.
+ */
+
+DSA_SIG * FIPS_dsa_sign_ctx(DSA *dsa, EVP_MD_CTX *ctx)
+	{
+	DSA_SIG *s;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digestfinal(ctx, dig, &dlen);
+	s = dsa->meth->dsa_do_sign(dig,dlen,dsa);
+	OPENSSL_cleanse(dig, dlen);
+	return s;
+	}
+
+DSA_SIG * FIPS_dsa_sign_digest(DSA *dsa, const unsigned char *dig, int dlen)
+	{
+	if (FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_DSA_SIGN_DIGEST, FIPS_R_SELFTEST_FAILED);
+		return NULL;
+		}
+	return dsa->meth->dsa_do_sign(dig, dlen, dsa);
+	}
+
+int FIPS_dsa_verify_ctx(DSA *dsa, EVP_MD_CTX *ctx, DSA_SIG *s)
+	{
+	int ret=-1;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digestfinal(ctx, dig, &dlen);
+	ret=dsa->meth->dsa_do_verify(dig,dlen,s,dsa);
+	OPENSSL_cleanse(dig, dlen);
+	return ret;
+	}
+
+int FIPS_dsa_verify_digest(DSA *dsa,
+				const unsigned char *dig, int dlen, DSA_SIG *s)
+	{
+	if (FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_DSA_VERIFY_DIGEST, FIPS_R_SELFTEST_FAILED);
+		return -1;
+		}
+	return dsa->meth->dsa_do_verify(dig,dlen,s,dsa);
+	}
+
+int FIPS_dsa_verify(DSA *dsa, const unsigned char *msg, size_t msglen,
+			const EVP_MD *mhash, DSA_SIG *s)
+	{
+	int ret=-1;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digest(msg, msglen, dig, &dlen, mhash);
+	ret=FIPS_dsa_verify_digest(dsa, dig, dlen, s);
+	OPENSSL_cleanse(dig, dlen);
+	return ret;
+	}
+
+DSA_SIG * FIPS_dsa_sign(DSA *dsa, const unsigned char *msg, size_t msglen,
+			const EVP_MD *mhash)
+	{
+	DSA_SIG *s;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digest(msg, msglen, dig, &dlen, mhash);
+	s = FIPS_dsa_sign_digest(dsa, dig, dlen);
+	OPENSSL_cleanse(dig, dlen);
+	return s;
+	}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_dssvs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_dssvs.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,805 @@
+
+#define OPENSSL_FIPSAPI
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("No FIPS DSA support\n");
+    return(0);
+}
+#else
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "fips_utl.h"
+
+static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
+				const EVP_MD **pmd)
+	{
+	char lbuf[10240];
+	char *keyword, *value;
+
+	char *p;
+	p = strchr(line, ',');
+	if (!p)
+		{
+		*pL = atoi(line);
+		*pdsa2 = 0;
+		*pN = 160;
+		if (pmd)
+			*pmd = EVP_sha1();
+		return 1;
+		}
+	*pdsa2 = 1;
+	*p = 0;
+	if (!parse_line2(&keyword, &value, lbuf, line, 0))
+		return 0;
+	if (strcmp(keyword, "L"))
+		return 0;
+	*pL = atoi(value);
+	memmove(line, p + 1, strlen(p+1)+1);
+	if (pmd)
+		p = strchr(line, ',');
+	else
+		p = strchr(line, ']');
+	if (!p)
+		return 0;
+	*p = 0;
+	if (!parse_line2(&keyword, &value, lbuf, line, 0))
+		return 0;
+	if (strcmp(keyword, "N"))
+		return 0;
+	*pN = atoi(value);
+	if (!pmd)
+		return 1;
+	memmove(line, p + 1, strlen(p+1)+1);
+	p = strchr(line, ']');
+	if (!p)
+		return 0;
+	*p = 0;
+	p = line;
+	while(isspace(*p))
+		p++;
+	if (!strcmp(p, "SHA-1"))
+		*pmd = EVP_sha1();
+	else if (!strcmp(p, "SHA-224"))
+		*pmd = EVP_sha224();
+	else if (!strcmp(p, "SHA-256"))
+		*pmd = EVP_sha256();
+	else if (!strcmp(p, "SHA-384"))
+		*pmd = EVP_sha384();
+	else if (!strcmp(p, "SHA-512"))
+		*pmd = EVP_sha512();
+	else
+		return 0;
+	return 1;
+	}
+
+static void primes(FILE *in, FILE *out)
+    {
+    char buf[10240];
+    char lbuf[10240];
+    char *keyword, *value;
+
+    while(fgets(buf,sizeof buf,in) != NULL)
+	{
+	fputs(buf,out);
+	if (!parse_line(&keyword, &value, lbuf, buf))
+		continue;
+	if(!strcmp(keyword,"Prime"))
+	    {
+	    BIGNUM *pp;
+
+	    pp=BN_new();
+	    do_hex2bn(&pp,value);
+	    fprintf(out, "result= %c" RESP_EOL,
+		   BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
+	    }	    
+	}
+    }
+
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+	unsigned char *seed_out,
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
+int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+	const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+	int idx, unsigned char *seed_out,
+	int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
+
+int dsa_paramgen_check_g(DSA *dsa);
+
+
+DSA *FIPS_dsa_new(void);
+void FIPS_dsa_free(DSA *r);
+DSA_SIG *FIPS_dsa_sig_new(void);
+void FIPS_dsa_sig_free(DSA_SIG *sig);
+int FIPS_dsa_verify(DSA *dsa, const unsigned char *msg, size_t msglen, const EVP_MD *mhash, DSA_SIG *s);
+DSA_SIG * FIPS_dsa_sign(DSA *dsa, const unsigned char *msg, size_t msglen, const EVP_MD *mhash);
+
+static void pqg(FILE *in, FILE *out)
+    {
+    char buf[1024];
+    char lbuf[1024];
+    char *keyword, *value;
+    int dsa2, L, N;
+    const EVP_MD *md = NULL;
+    BIGNUM *p = NULL, *q = NULL;
+    enum pqtype { PQG_NONE, PQG_PQ, PQG_G, PQG_GCANON}
+		pqg_type = PQG_NONE;
+    int seedlen=-1, idxlen, idx = -1;
+    unsigned char seed[1024], idtmp[1024];
+
+    while(fgets(buf,sizeof buf,in) != NULL)
+	{
+	if (buf[0] == '[')
+		{
+	    	if (strstr(buf, "Probable"))
+			pqg_type = PQG_PQ;
+	    	else if (strstr(buf, "Unverifiable"))
+			pqg_type = PQG_G;
+	    	else if (strstr(buf, "Canonical"))
+			pqg_type = PQG_GCANON;
+		}
+	if (!parse_line(&keyword, &value, lbuf, buf))
+		{
+		fputs(buf,out);
+		continue;
+		}
+	if (strcmp(keyword, "Num"))
+		fputs(buf,out);
+	if(!strcmp(keyword,"[mod"))
+	    {
+	    if (!parse_mod(value, &dsa2, &L, &N, &md))
+		{
+		fprintf(stderr, "Mod Parse Error\n");
+		exit (1);
+		}
+	    }
+	else if(!strcmp(keyword,"N")
+		|| (!strcmp(keyword, "Num") && pqg_type == PQG_PQ))
+	    {
+	    int n=atoi(value);
+
+	    while(n--)
+		{
+		DSA *dsa;
+		int counter;
+		unsigned long h;
+		dsa = FIPS_dsa_new();
+
+		if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
+						NULL, 0, seed,
+						&counter, &h, NULL))
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+		if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
+						NULL, 0, -1, seed,
+						&counter, &h, NULL) <= 0)
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+
+		do_bn_print_name(out, "P",dsa->p);
+		do_bn_print_name(out, "Q",dsa->q);
+		if (!dsa2)
+			do_bn_print_name(out, "G",dsa->g);
+		OutputValue(dsa2 ? "domain_parameter_seed" : "Seed",
+				seed, M_EVP_MD_size(md), out, 0);
+		if (!dsa2)
+			{
+			fprintf(out, "c = %d" RESP_EOL, counter);
+			fprintf(out, "H = %lx" RESP_EOL RESP_EOL,h);
+			}
+		else
+			{
+			fprintf(out, "counter = %d" RESP_EOL RESP_EOL, counter);
+			}
+		FIPS_dsa_free(dsa);
+		}
+	    }
+	else if(!strcmp(keyword,"P"))
+	    p=hex2bn(value);
+	else if(!strcmp(keyword,"Q"))
+	    q=hex2bn(value);
+	else if(!strcmp(keyword,"domain_parameter_seed"))
+	    seedlen = hex2bin(value, seed);
+	else if(!strcmp(keyword,"firstseed"))
+	    seedlen = hex2bin(value, seed);
+	else if(!strcmp(keyword,"pseed"))
+	    seedlen += hex2bin(value, seed + seedlen);
+	else if(!strcmp(keyword,"qseed"))
+	    seedlen += hex2bin(value, seed + seedlen);
+	else if(!strcmp(keyword,"index"))
+	    {
+	    idxlen = hex2bin(value, idtmp);
+            if (idxlen != 1)
+		{
+		fprintf(stderr, "Index value error\n");
+		exit (1);
+		}
+	    idx = idtmp[0];
+	    }
+	if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
+		{
+		DSA *dsa;
+		dsa = FIPS_dsa_new();
+		dsa->p = p;
+		dsa->q = q;
+		p = q = NULL;
+		if (dsa_builtin_paramgen2(dsa, L, N, md,
+						seed, seedlen, idx, NULL,
+						NULL, NULL, NULL) <= 0)
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+		do_bn_print_name(out, "G",dsa->g);
+		FIPS_dsa_free(dsa);
+		idx = -1;
+		}
+	}
+    }
+
+static void pqgver(FILE *in, FILE *out)
+    {
+    char buf[1024];
+    char lbuf[1024];
+    char *keyword, *value;
+    BIGNUM *p = NULL, *q = NULL, *g = NULL;
+    int counter=-1, counter2;
+    unsigned long h=0, h2;
+    DSA *dsa=NULL;
+    int dsa2, L, N, part_test = 0;
+    const EVP_MD *md = NULL;
+    int seedlen=-1, idxlen, idx = -1;
+    unsigned char seed[1024], idtmp[1024];
+
+    while(fgets(buf,sizeof buf,in) != NULL)
+	{
+	if (!parse_line(&keyword, &value, lbuf, buf))
+		{
+		if (p && q)
+			{
+			part_test = 1;
+			goto partial;
+			}
+		fputs(buf,out);
+		continue;
+		}
+	fputs(buf, out);
+	if(!strcmp(keyword,"[mod"))
+	    {
+	    if (!parse_mod(value, &dsa2, &L, &N, &md))
+		{
+		fprintf(stderr, "Mod Parse Error\n");
+		exit (1);
+		}
+	    }
+	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,"firstseed"))
+	    seedlen = hex2bin(value, seed);
+	else if(!strcmp(keyword,"pseed"))
+	    seedlen += hex2bin(value, seed + seedlen);
+	else if(!strcmp(keyword,"qseed"))
+	    seedlen += hex2bin(value, seed + seedlen);
+	else if(!strcmp(keyword,"Seed")
+		|| !strcmp(keyword,"domain_parameter_seed"))
+	    {
+	    seedlen = hex2bin(value, seed);
+	    if (!dsa2 && seedlen != 20)
+		{
+		fprintf(stderr, "Seed parse length error\n");
+		exit (1);
+		}
+	    if (idx > 0)
+		part_test = 1;
+	    }
+	else if(!strcmp(keyword,"index"))
+	    {
+	    idxlen = hex2bin(value, idtmp);
+            if (idxlen != 1)
+		{
+		fprintf(stderr, "Index value error\n");
+		exit (1);
+		}
+	    idx = idtmp[0];
+	    }
+	else if(!strcmp(keyword,"c"))
+	    counter = atoi(buf+4);
+	partial:
+	if (part_test && idx < 0 && h == 0 && g)
+	    {
+	    dsa = FIPS_dsa_new();
+	    dsa->p = BN_dup(p);
+	    dsa->q = BN_dup(q);
+	    dsa->g = BN_dup(g);
+	    if (dsa_paramgen_check_g(dsa))
+		fprintf(out, "Result = P" RESP_EOL);
+	    else
+		fprintf(out, "Result = F" RESP_EOL);
+	    BN_free(p);
+	    BN_free(q);
+	    BN_free(g);
+	    p = NULL;
+	    q = NULL;
+	    g = NULL;
+	    FIPS_dsa_free(dsa);
+	    dsa = NULL;
+	    part_test = 0;
+	    }
+	else if(!strcmp(keyword,"H") || part_test)
+	    {
+	    if (!part_test)
+	    	h = atoi(value);
+	    if (!p || !q || (!g && !part_test))
+		{
+		fprintf(stderr, "Parse Error\n");
+		exit (1);
+		}
+	    dsa = FIPS_dsa_new();
+	    if (idx >= 0)
+		{
+		dsa->p = BN_dup(p);
+		dsa->q = BN_dup(q);
+		}
+	    no_err = 1;
+	    if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
+					seed, seedlen, NULL,
+					&counter2, &h2, NULL))
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+	    if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
+					seed, seedlen, idx, NULL,
+					&counter2, &h2, NULL) < 0)
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+	    no_err = 0;
+	    if (idx >= 0)
+		{
+		if (BN_cmp(dsa->g, g))
+			fprintf(out, "Result = F" RESP_EOL);
+		else
+			fprintf(out, "Result = P" RESP_EOL);
+		}
+            else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) ||
+		(!part_test &&
+		((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
+	    	fprintf(out, "Result = F" RESP_EOL);
+	    else
+	    	fprintf(out, "Result = P" RESP_EOL);
+	    BN_free(p);
+	    BN_free(q);
+	    BN_free(g);
+	    p = NULL;
+	    q = NULL;
+	    g = NULL;
+	    FIPS_dsa_free(dsa);
+	    dsa = NULL;
+	    if (part_test)
+		{
+		if (idx == -1)
+			fputs(buf,out);
+		part_test = 0;
+		}
+	    idx = -1;
+	    }
+	}
+    }
+
+/* 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 L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
+							BN_CTX *ctx)
+    {
+    BIGNUM *rem = NULL;
+    if (BN_num_bits(p) != L)
+	return 0;
+    if (BN_num_bits(q) != N)
+	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;
+    }
+
+static void keyver(FILE *in, FILE *out)
+    {
+    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 dsa2, L, N;
+    int paramcheck = 0;
+
+    ctx = BN_CTX_new();
+    Y2 = BN_new();
+
+    while(fgets(buf,sizeof buf,in) != NULL)
+	{
+	if (!parse_line(&keyword, &value, lbuf, buf))
+		{
+		fputs(buf,out);
+		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;
+	    if (!parse_mod(value, &dsa2, &L, &N, NULL))
+		{
+		fprintf(stderr, "Mod Parse Error\n");
+		exit (1);
+		}
+	    }
+	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);
+		}
+	    do_bn_print_name(out, "P",p);
+	    do_bn_print_name(out, "Q",q);
+	    do_bn_print_name(out, "G",g);
+	    do_bn_print_name(out, "X",X);
+	    do_bn_print_name(out, "Y",Y);
+	    if (!paramcheck)
+		{
+		if (dss_paramcheck(L, N, p, q, g, ctx))
+			paramcheck = 1;
+		else
+			paramcheck = -1;
+		}
+	    if (paramcheck != 1)
+	   	fprintf(out, "Result = F" RESP_EOL);
+	    else
+		{
+		if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
+	    		fprintf(out, "Result = F" RESP_EOL);
+	        else
+	    		fprintf(out, "Result = P" RESP_EOL);
+		}
+	    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);
+	if (ctx)
+	    BN_CTX_free(ctx);
+    }
+
+static void keypair(FILE *in, FILE *out)
+    {
+    char buf[1024];
+    char lbuf[1024];
+    char *keyword, *value;
+    int dsa2, L, N;
+
+    while(fgets(buf,sizeof buf,in) != NULL)
+	{
+	if (!parse_line(&keyword, &value, lbuf, buf))
+		{
+		continue;
+		}
+	if(!strcmp(keyword,"[mod"))
+	    {
+	    if (!parse_mod(value, &dsa2, &L, &N, NULL))
+		{
+		fprintf(stderr, "Mod Parse Error\n");
+		exit (1);
+		}
+	    fputs(buf,out);
+	    }
+	else if(!strcmp(keyword,"N"))
+	    {
+	    DSA *dsa;
+	    int n=atoi(value);
+
+	    dsa = FIPS_dsa_new();
+	    if (!dsa)
+		{
+		fprintf(stderr, "DSA allocation error\n");
+		exit(1);
+		}
+	    if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
+						NULL, NULL, NULL, NULL))
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+	    if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
+						NULL, NULL, NULL, NULL) <= 0)
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+	    do_bn_print_name(out, "P",dsa->p);
+	    do_bn_print_name(out, "Q",dsa->q);
+	    do_bn_print_name(out, "G",dsa->g);
+	    fputs(RESP_EOL, out);
+
+	    while(n--)
+		{
+		if (!DSA_generate_key(dsa))
+			exit(1);
+
+		do_bn_print_name(out, "X",dsa->priv_key);
+		do_bn_print_name(out, "Y",dsa->pub_key);
+	    	fputs(RESP_EOL, out);
+		}
+	    FIPS_dsa_free(dsa);
+	    }
+	}
+    }
+
+static void siggen(FILE *in, FILE *out)
+    {
+    char buf[1024];
+    char lbuf[1024];
+    char *keyword, *value;
+    int dsa2, L, N;
+    const EVP_MD *md = NULL;
+    DSA *dsa=NULL;
+
+    while(fgets(buf,sizeof buf,in) != NULL)
+	{
+	if (!parse_line(&keyword, &value, lbuf, buf))
+		{
+		fputs(buf,out);
+		continue;
+		}
+	fputs(buf,out);
+	if(!strcmp(keyword,"[mod"))
+	    {
+	    if (!parse_mod(value, &dsa2, &L, &N, &md))
+		{
+		fprintf(stderr, "Mod Parse Error\n");
+		exit (1);
+		}
+	    if (dsa)
+		FIPS_dsa_free(dsa);
+	    dsa = FIPS_dsa_new();
+	    if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
+						NULL, NULL, NULL, NULL))
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+	    if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
+						NULL, NULL, NULL, NULL) <= 0)
+			{
+			fprintf(stderr, "Parameter Generation error\n");
+			exit(1);
+			}
+	    do_bn_print_name(out, "P",dsa->p);
+	    do_bn_print_name(out, "Q",dsa->q);
+	    do_bn_print_name(out, "G",dsa->g);
+	    fputs(RESP_EOL, out);
+	    }
+	else if(!strcmp(keyword,"Msg"))
+	    {
+	    unsigned char msg[1024];
+	    int n;
+	    DSA_SIG *sig;
+
+	    n=hex2bin(value,msg);
+
+	    if (!DSA_generate_key(dsa))
+		exit(1);
+	    do_bn_print_name(out, "Y",dsa->pub_key);
+
+	    sig = FIPS_dsa_sign(dsa, msg, n, md);
+
+	    do_bn_print_name(out, "R",sig->r);
+	    do_bn_print_name(out, "S",sig->s);
+	    fputs(RESP_EOL, out);
+	    FIPS_dsa_sig_free(sig);
+	    }
+	}
+    if (dsa)
+	FIPS_dsa_free(dsa);
+    }
+
+static void sigver(FILE *in, FILE *out)
+    {
+    DSA *dsa=NULL;
+    char buf[1024];
+    char lbuf[1024];
+    unsigned char msg[1024];
+    char *keyword, *value;
+    int n=0;
+    int dsa2, L, N;
+    const EVP_MD *md = NULL;
+    DSA_SIG sg, *sig = &sg;
+
+    sig->r = NULL;
+    sig->s = NULL;
+
+    while(fgets(buf,sizeof buf,in) != NULL)
+	{
+	if (!parse_line(&keyword, &value, lbuf, buf))
+		{
+		fputs(buf,out);
+		continue;
+		}
+	fputs(buf,out);
+	if(!strcmp(keyword,"[mod"))
+	    {
+	    if (!parse_mod(value, &dsa2, &L, &N, &md))
+		{
+		fprintf(stderr, "Mod Parse Error\n");
+		exit (1);
+		}
+	    if (dsa)
+		FIPS_dsa_free(dsa);
+	    dsa = FIPS_dsa_new();
+	    }
+	else if(!strcmp(keyword,"P"))
+	    do_hex2bn(&dsa->p, value);
+	else if(!strcmp(keyword,"Q"))
+	    do_hex2bn(&dsa->q, value);
+	else if(!strcmp(keyword,"G"))
+	    do_hex2bn(&dsa->g, value);
+	else if(!strcmp(keyword,"Msg"))
+	    n=hex2bin(value,msg);
+	else if(!strcmp(keyword,"Y"))
+	    do_hex2bn(&dsa->pub_key, value);
+	else if(!strcmp(keyword,"R"))
+	    sig->r=hex2bn(value);
+	else if(!strcmp(keyword,"S"))
+	    {
+	    int r;
+	    sig->s=hex2bn(value);
+
+	    no_err = 1;
+	    r = FIPS_dsa_verify(dsa, msg, n, md, sig);
+	    no_err = 0;
+	    if (sig->s)
+		{
+		BN_free(sig->s);
+		sig->s = NULL;
+		}
+	    if (sig->r)
+		{
+		BN_free(sig->r);
+		sig->r = NULL;
+		}
+	
+	    fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
+	    }
+	}
+	if (dsa)
+	    FIPS_dsa_free(dsa);
+    }
+
+#ifdef FIPS_ALGVS
+int fips_dssvs_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+    {
+    FILE *in, *out;
+    if (argc == 4)
+	{
+	in = fopen(argv[2], "r");
+	if (!in)
+		{
+		fprintf(stderr, "Error opening input file\n");
+		exit(1);
+		}
+	out = fopen(argv[3], "w");
+	if (!out)
+		{
+		fprintf(stderr, "Error opening output file\n");
+		exit(1);
+		}
+	}
+    else if (argc == 2)
+	{
+	in = stdin;
+	out = stdout;
+	}
+    else
+	{
+	fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
+	exit(1);
+	}
+    fips_algtest_init_nofips();
+    if(!FIPS_mode_set(1)) {
+	    fprintf(stderr, "Can't set FIPS mode\n");
+	    exit(1);
+    }
+    if(!strcmp(argv[1],"prime"))
+	primes(in, out);
+    else if(!strcmp(argv[1],"pqg"))
+	pqg(in, out);
+    else if(!strcmp(argv[1],"pqgver"))
+	pqgver(in, out);
+    else if(!strcmp(argv[1],"keypair"))
+	keypair(in, out);
+    else if(!strcmp(argv[1],"keyver"))
+	keyver(in, out);
+    else if(!strcmp(argv[1],"siggen"))
+	siggen(in, out);
+    else if(!strcmp(argv[1],"sigver"))
+	sigver(in, out);
+    else
+	{
+	fprintf(stderr,"Don't know how to %s.\n",argv[1]);
+	exit(1);
+	}
+
+    if (argc == 4)
+	{
+	fclose(in);
+	fclose(out);
+	}
+
+    return 0;
+    }
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_ecdhvs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_ecdhvs.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,500 @@
+/* fips/ecdh/fips_ecdhvs.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#define OPENSSL_FIPSAPI
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("No FIPS ECDH support\n");
+    return(0);
+}
+#else
+
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/ecdh.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "fips_utl.h"
+
+static const EVP_MD *eparse_md(char *line)
+	{
+	char *p;
+	if (line[0] != '[' || line[1] != 'E')
+		return NULL;
+	p = strchr(line, '-');
+	if (!p)
+		return NULL;
+	line = p + 1;
+	p = strchr(line, ']');
+	if (!p)
+		return NULL;
+	*p = 0;
+	p = line;
+	while(isspace(*p))
+		p++;
+	if (!strcmp(p, "SHA1"))
+		return EVP_sha1();
+	else if (!strcmp(p, "SHA224"))
+		return EVP_sha224();
+	else if (!strcmp(p, "SHA256"))
+		return EVP_sha256();
+	else if (!strcmp(p, "SHA384"))
+		return EVP_sha384();
+	else if (!strcmp(p, "SHA512"))
+		return EVP_sha512();
+	else
+		return NULL;
+	}
+
+static int lookup_curve2(char *cname)
+	{
+	char *p;
+	p = strchr(cname, ']');
+	if (!p)
+		{
+		fprintf(stderr, "Parse error: missing ]\n");
+		return NID_undef;
+		}
+	*p = 0;
+
+	if (!strcmp(cname, "B-163"))
+		return NID_sect163r2;
+	if (!strcmp(cname, "B-233"))
+		return NID_sect233r1;
+	if (!strcmp(cname, "B-283"))
+		return NID_sect283r1;
+	if (!strcmp(cname, "B-409"))
+		return NID_sect409r1;
+	if (!strcmp(cname, "B-571"))
+		return NID_sect571r1;
+	if (!strcmp(cname, "K-163"))
+		return NID_sect163k1;
+	if (!strcmp(cname, "K-233"))
+		return NID_sect233k1;
+	if (!strcmp(cname, "K-283"))
+		return NID_sect283k1;
+	if (!strcmp(cname, "K-409"))
+		return NID_sect409k1;
+	if (!strcmp(cname, "K-571"))
+		return NID_sect571k1;
+	if (!strcmp(cname, "P-192"))
+		return NID_X9_62_prime192v1;
+	if (!strcmp(cname, "P-224"))
+		return NID_secp224r1;
+	if (!strcmp(cname, "P-256"))
+		return NID_X9_62_prime256v1;
+	if (!strcmp(cname, "P-384"))
+		return NID_secp384r1;
+	if (!strcmp(cname, "P-521"))
+		return NID_secp521r1;
+
+	fprintf(stderr, "Unknown Curve name %s\n", cname);
+	return NID_undef;
+	}
+
+static int lookup_curve(char *cname)
+	{
+	char *p;
+	p = strchr(cname, ':');
+	if (!p)
+		{
+		fprintf(stderr, "Parse error: missing :\n");
+		return NID_undef;
+		}
+	cname = p + 1;
+	while(isspace(*cname))
+		cname++;
+	return lookup_curve2(cname);
+	}
+
+static EC_POINT *make_peer(EC_GROUP *group, BIGNUM *x, BIGNUM *y)
+	{
+	EC_POINT *peer;
+	int rv;
+	BN_CTX *c;
+	peer = EC_POINT_new(group);
+	if (!peer)
+		return NULL;
+	c = BN_CTX_new();
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group))
+		== NID_X9_62_prime_field)
+		rv = EC_POINT_set_affine_coordinates_GFp(group, peer, x, y, c);
+	else
+#ifdef OPENSSL_NO_EC2M
+		{
+		fprintf(stderr, "ERROR: GF2m not supported\n");
+		exit(1);
+		}
+#else
+		rv = EC_POINT_set_affine_coordinates_GF2m(group, peer, x, y, c);
+#endif
+
+	BN_CTX_free(c);
+	if (rv)
+		return peer;
+	EC_POINT_free(peer);
+	return NULL;
+	}
+
+static int ec_print_key(FILE *out, EC_KEY *key, int add_e, int exout)
+	{
+	const EC_POINT *pt;
+	const EC_GROUP *grp;
+	const EC_METHOD *meth;
+	int rv;
+	BIGNUM *tx, *ty;
+	const BIGNUM *d = NULL;
+	BN_CTX *ctx;
+	ctx = BN_CTX_new();
+	if (!ctx)
+		return 0;
+	tx = BN_CTX_get(ctx);
+	ty = BN_CTX_get(ctx);
+	if (!tx || !ty)
+		return 0;
+	grp = EC_KEY_get0_group(key);
+	pt = EC_KEY_get0_public_key(key);
+	if (exout)
+		d = EC_KEY_get0_private_key(key);
+	meth = EC_GROUP_method_of(grp);
+	if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
+		rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, tx, ty, ctx);
+	else
+#ifdef OPENSSL_NO_EC2M
+		{
+		fprintf(stderr, "ERROR: GF2m not supported\n");
+		exit(1);
+		}
+#else
+		rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, tx, ty, ctx);
+#endif
+
+	if (add_e)
+		{
+		do_bn_print_name(out, "QeIUTx", tx);
+		do_bn_print_name(out, "QeIUTy", ty);
+		if (d)
+			do_bn_print_name(out, "QeIUTd", d);
+		}
+	else
+		{
+		do_bn_print_name(out, "QIUTx", tx);
+		do_bn_print_name(out, "QIUTy", ty);
+		if (d)
+			do_bn_print_name(out, "QIUTd", d);
+		}
+
+	BN_CTX_free(ctx);
+
+	return rv;
+
+	}
+
+static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group,
+			BIGNUM *ix, BIGNUM *iy, BIGNUM *id, BIGNUM *cx,
+			BIGNUM *cy, const EVP_MD *md,
+				unsigned char *rhash, size_t rhashlen)
+	{
+	EC_KEY *ec = NULL;
+	EC_POINT *peerkey = NULL;
+	unsigned char *Z;
+	unsigned char chash[EVP_MAX_MD_SIZE];
+	int Zlen;
+	ec = EC_KEY_new();
+	EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH);
+	EC_KEY_set_group(ec, group);
+	peerkey = make_peer(group, cx, cy);
+	if (rhash == NULL)
+		{
+		if (md)
+			rhashlen = M_EVP_MD_size(md);
+		EC_KEY_generate_key(ec);
+		ec_print_key(out, ec, md ? 1 : 0, exout);
+		}
+	else
+		{
+		EC_KEY_set_public_key_affine_coordinates(ec, ix, iy);
+		EC_KEY_set_private_key(ec, id);
+		}
+	Zlen = (EC_GROUP_get_degree(group) + 7)/8;
+	Z = OPENSSL_malloc(Zlen);
+	if (!Z)
+		exit(1);
+	ECDH_compute_key(Z, Zlen, peerkey, ec, 0);
+	if (md)
+		{
+		if (exout)
+			OutputValue("Z", Z, Zlen, out, 0);
+		FIPS_digest(Z, Zlen, chash, NULL, md);
+		OutputValue(rhash ? "IUTHashZZ" : "HashZZ",
+						chash, rhashlen, out, 0);
+		if (rhash)
+			{
+			fprintf(out, "Result = %s\n",
+				memcmp(chash, rhash, rhashlen) ? "F" : "P");
+			}
+		}
+	else
+		OutputValue("ZIUT", Z, Zlen, out, 0);
+	OPENSSL_cleanse(Z, Zlen);
+	OPENSSL_free(Z);
+	EC_KEY_free(ec);
+	EC_POINT_free(peerkey);
+	}
+		
+#ifdef FIPS_ALGVS
+int fips_ecdhvs_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+	{
+	char **args = argv + 1;
+	int argn = argc - 1;
+	FILE *in, *out;
+	char buf[2048], lbuf[2048];
+	unsigned char *rhash = NULL;
+	long rhashlen;
+	BIGNUM *cx = NULL, *cy = NULL;
+	BIGNUM *id = NULL, *ix = NULL, *iy = NULL;
+	const EVP_MD *md = NULL;
+	EC_GROUP *group = NULL;
+	char *keyword = NULL, *value = NULL;
+	int do_verify = -1, exout = 0;
+	int rv = 1;
+
+	int curve_nids[5] = {0,0,0,0,0};
+	int param_set = -1;
+
+	fips_algtest_init_nofips();
+	if(!FIPS_mode_set(1)) {
+		fprintf(stderr, "Can't set FIPS mode\n");
+		exit(1);
+	}
+
+	if (argn && !strcmp(*args, "ecdhver"))
+		{
+		do_verify = 1;
+		args++;
+		argn--;
+		}
+	else if (argn && !strcmp(*args, "ecdhgen"))
+		{
+		do_verify = 0;
+		args++;
+		argn--;
+		}
+
+	if (argn && !strcmp(*args, "-exout"))
+		{
+		exout = 1;
+		args++;
+		argn--;
+		}
+
+	if (do_verify == -1)
+		{
+		fprintf(stderr,"%s [ecdhver|ecdhgen|] [-exout] (infile outfile)\n",argv[0]);
+		exit(1);
+		}
+
+	if (argn == 2)
+		{
+		in = fopen(*args, "r");
+		if (!in)
+			{
+			fprintf(stderr, "Error opening input file\n");
+			exit(1);
+			}
+		out = fopen(args[1], "w");
+		if (!out)
+			{
+			fprintf(stderr, "Error opening output file\n");
+			exit(1);
+			}
+		}
+	else if (argn == 0)
+		{
+		in = stdin;
+		out = stdout;
+		}
+	else
+		{
+		fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]);
+		exit(1);
+		}
+
+	while (fgets(buf, sizeof(buf), in) != NULL)
+		{
+		fputs(buf, out);
+		if (buf[0] == '[' && buf[1] == 'E')
+			{
+			int c = buf[2];
+			if (c < 'A' || c > 'E')
+				goto parse_error;
+			param_set = c - 'A';
+			/* If just [E?] then initial paramset */
+			if (buf[3] == ']')
+				continue;
+			if (group)
+				EC_GROUP_free(group);
+			group = EC_GROUP_new_by_curve_name(curve_nids[c - 'A']);
+			}
+		if (strlen(buf) > 10 && !strncmp(buf, "[Curve", 6))
+			{
+			int nid;
+			if (param_set == -1)
+				goto parse_error;
+			nid = lookup_curve(buf);
+			if (nid == NID_undef)
+				goto parse_error;
+			curve_nids[param_set] = nid;
+			}
+
+		if (strlen(buf) > 4 && buf[0] == '[' && buf[2] == '-')
+			{
+			int nid = lookup_curve2(buf + 1);
+			if (nid == NID_undef)
+				goto parse_error;
+			if (group)
+				EC_GROUP_free(group);
+			group = EC_GROUP_new_by_curve_name(nid);
+			if (!group)
+				{
+				fprintf(stderr, "ERROR: unsupported curve %s\n", buf + 1);
+				return 1;
+				}
+			}
+
+		if (strlen(buf) > 6 && !strncmp(buf, "[E", 2))
+			{
+			md = eparse_md(buf);
+			if (md == NULL)
+				goto parse_error;
+			continue;
+			}
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+		if (!strcmp(keyword, "QeCAVSx") || !strcmp(keyword, "QCAVSx"))
+			{
+			if (!do_hex2bn(&cx, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "QeCAVSy") || !strcmp(keyword, "QCAVSy"))
+			{
+			if (!do_hex2bn(&cy, value))
+				goto parse_error;
+			if (do_verify == 0)
+				ec_output_Zhash(out, exout, group,
+						NULL, NULL, NULL,
+						cx, cy, md, rhash, rhashlen);
+			}
+		else if (!strcmp(keyword, "deIUT"))
+			{
+			if (!do_hex2bn(&id, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "QeIUTx"))
+			{
+			if (!do_hex2bn(&ix, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "QeIUTy"))
+			{
+			if (!do_hex2bn(&iy, value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "CAVSHashZZ"))
+			{
+			if (!md)
+				goto parse_error;
+			rhash = hex2bin_m(value, &rhashlen);
+			if (!rhash || rhashlen != M_EVP_MD_size(md))
+				goto parse_error;
+			ec_output_Zhash(out, exout, group, ix, iy, id, cx, cy,
+					md, rhash, rhashlen);
+			}
+		}
+	rv = 0;
+	parse_error:
+	if (id)
+		BN_free(id);
+	if (ix)
+		BN_free(ix);
+	if (iy)
+		BN_free(iy);
+	if (cx)
+		BN_free(cx);
+	if (cy)
+		BN_free(cy);
+	if (group)
+		EC_GROUP_free(group);
+	if (in && in != stdin)
+		fclose(in);
+	if (out && out != stdout)
+		fclose(out);
+	if (rv)
+		fprintf(stderr, "Error Parsing request file\n");
+	return rv;
+	}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_ecdsa_lib.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_ecdsa_lib.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,93 @@
+/* fips_dsa_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * 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
+ *    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).
+ *
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <string.h>
+#include <openssl/ecdsa.h>
+#include <openssl/bn.h>
+#include <openssl/fips.h>
+
+ECDSA_SIG *FIPS_ecdsa_sig_new(void)
+	{
+	ECDSA_SIG *sig;
+	sig = OPENSSL_malloc(sizeof(ECDSA_SIG));
+	if (!sig)
+		return NULL;
+	sig->r = BN_new();
+	sig->s = BN_new();
+	if (!sig->r || !sig->s)
+		{
+		FIPS_ecdsa_sig_free(sig);
+		return NULL;
+		}
+	return sig;
+	}
+
+void FIPS_ecdsa_sig_free(ECDSA_SIG *sig)
+	{
+	if (sig)
+		{
+		if (sig->r)
+			BN_free(sig->r);
+		if (sig->s)
+			BN_free(sig->s);
+		OPENSSL_free(sig);
+		}
+	}
+
Index: openssl-1.0.2j/crypto/fips/fips_ecdsavs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_ecdsavs.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,585 @@
+/* fips/ecdsa/fips_ecdsavs.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#define OPENSSL_FIPSAPI
+#include <openssl/opensslconf.h>
+#include <stdio.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char **argv)
+{
+    printf("No FIPS ECDSA support\n");
+    return(0);
+}
+#else
+
+#include <string.h>
+#include <ctype.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#include "fips_utl.h"
+#include <openssl/sha.h>
+
+#include <openssl/objects.h>
+
+ECDSA_SIG * FIPS_ecdsa_sign_ctx(EC_KEY *key, EVP_MD_CTX *ctx)
+	{
+	ECDSA_SIG *s;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digestfinal(ctx, dig, &dlen);
+	s = FIPS_ecdsa_sign_digest(key, dig, dlen);
+	OPENSSL_cleanse(dig, dlen);
+	return s;
+	}
+
+int FIPS_ecdsa_verify_ctx(EC_KEY *key, EVP_MD_CTX *ctx, ECDSA_SIG *s)
+	{
+	int ret=-1;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digestfinal(ctx, dig, &dlen);
+	ret = FIPS_ecdsa_verify_digest(key, dig, dlen, s);
+	OPENSSL_cleanse(dig, dlen);
+	return ret;
+	}
+
+int FIPS_ecdsa_verify(EC_KEY *key, const unsigned char *msg, size_t msglen,
+			const EVP_MD *mhash, ECDSA_SIG *s)
+	{
+	int ret=-1;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digest(msg, msglen, dig, &dlen, mhash);
+	ret=FIPS_ecdsa_verify_digest(key, dig, dlen, s);
+	OPENSSL_cleanse(dig, dlen);
+	return ret;
+	}
+
+ECDSA_SIG * FIPS_ecdsa_sign(EC_KEY *key,
+			const unsigned char *msg, size_t msglen,
+			const EVP_MD *mhash)
+	{
+	ECDSA_SIG *s;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int dlen;
+        FIPS_digest(msg, msglen, dig, &dlen, mhash);
+	s = FIPS_ecdsa_sign_digest(key, dig, dlen);
+	OPENSSL_cleanse(dig, dlen);
+	return s;
+	}
+
+static int elookup_curve(char *in, char *curve_name, const EVP_MD **pmd)
+	{
+	char *cname, *p;
+	/* Copy buffer as we will change it */
+	strcpy(curve_name, in);
+	cname = curve_name + 1;
+	p = strchr(cname, ']');
+	if (!p)
+		{
+		fprintf(stderr, "Parse error: missing ]\n");
+		return NID_undef;
+		}
+	*p = 0;
+	p = strchr(cname, ',');
+	if (p)
+		{
+		if (!pmd)
+			{
+			fprintf(stderr, "Parse error: unexpected digest\n");
+			return NID_undef;
+			}
+		*p = 0;
+		p++;
+
+		if (!strcmp(p, "SHA-1"))
+			*pmd = EVP_sha1();
+		else if (!strcmp(p, "SHA-224"))
+			*pmd = EVP_sha224();
+		else if (!strcmp(p, "SHA-256"))
+			*pmd = EVP_sha256();
+		else if (!strcmp(p, "SHA-384"))
+			*pmd = EVP_sha384();
+		else if (!strcmp(p, "SHA-512"))
+			*pmd = EVP_sha512();
+		else
+			{
+			fprintf(stderr, "Unknown digest %s\n", p);
+			return NID_undef;
+			}
+		}
+	else if(pmd)
+		*pmd = EVP_sha1();
+
+	if (!strcmp(cname, "B-163"))
+		return NID_sect163r2;
+	if (!strcmp(cname, "B-233"))
+		return NID_sect233r1;
+	if (!strcmp(cname, "B-283"))
+		return NID_sect283r1;
+	if (!strcmp(cname, "B-409"))
+		return NID_sect409r1;
+	if (!strcmp(cname, "B-571"))
+		return NID_sect571r1;
+	if (!strcmp(cname, "K-163"))
+		return NID_sect163k1;
+	if (!strcmp(cname, "K-233"))
+		return NID_sect233k1;
+	if (!strcmp(cname, "K-283"))
+		return NID_sect283k1;
+	if (!strcmp(cname, "K-409"))
+		return NID_sect409k1;
+	if (!strcmp(cname, "K-571"))
+		return NID_sect571k1;
+	if (!strcmp(cname, "P-192"))
+		return NID_X9_62_prime192v1;
+	if (!strcmp(cname, "P-224"))
+		return NID_secp224r1;
+	if (!strcmp(cname, "P-256"))
+		return NID_X9_62_prime256v1;
+	if (!strcmp(cname, "P-384"))
+		return NID_secp384r1;
+	if (!strcmp(cname, "P-521"))
+		return NID_secp521r1;
+
+	fprintf(stderr, "Unknown Curve name %s\n", cname);
+	return NID_undef;
+	}
+
+static int ec_get_pubkey(EC_KEY *key, BIGNUM *x, BIGNUM *y)
+	{
+	const EC_POINT *pt;
+	const EC_GROUP *grp;
+	const EC_METHOD *meth;
+	int rv;
+	BN_CTX *ctx;
+	ctx = BN_CTX_new();
+	if (!ctx)
+		return 0;
+	grp = EC_KEY_get0_group(key);
+	pt = EC_KEY_get0_public_key(key);
+	meth = EC_GROUP_method_of(grp);
+	if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
+		rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, x, y, ctx);
+	else
+#ifdef OPENSSL_NO_EC2M
+		{
+		fprintf(stderr, "ERROR: GF2m not supported\n");
+		exit(1);
+		}
+#else
+		rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, x, y, ctx);
+#endif
+
+	BN_CTX_free(ctx);
+
+	return rv;
+
+	}
+
+static int KeyPair(FILE *in, FILE *out)
+	{
+	char buf[2048], lbuf[2048];
+	char *keyword, *value;
+	int curve_nid = NID_undef;
+	int i, count;
+	BIGNUM *Qx = NULL, *Qy = NULL;
+	const BIGNUM *d = NULL;
+	EC_KEY *key = NULL;
+	Qx = BN_new();
+	Qy = BN_new();
+	while(fgets(buf, sizeof buf, in) != NULL)
+		{
+		if (*buf == '[' && buf[2] == '-')
+			{
+			if (buf[2] == '-')
+			curve_nid = elookup_curve(buf, lbuf, NULL);
+			fputs(buf, out);
+			continue;
+			}
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			{
+			fputs(buf, out);
+			continue;
+			}
+		if (!strcmp(keyword, "N"))
+			{
+			count = atoi(value);
+
+			for (i = 0; i < count; i++)
+				{
+
+				key = EC_KEY_new_by_curve_name(curve_nid);
+				if (!EC_KEY_generate_key(key))
+					{
+					fprintf(stderr, "Error generating key\n");
+					return 0;
+					}
+
+				if (!ec_get_pubkey(key, Qx, Qy))
+					{
+					fprintf(stderr, "Error getting public key\n");
+					return 0;
+					}
+
+				d = EC_KEY_get0_private_key(key);
+
+				do_bn_print_name(out, "d", d);
+				do_bn_print_name(out, "Qx", Qx);
+				do_bn_print_name(out, "Qy", Qy);
+				fputs(RESP_EOL, out);
+				EC_KEY_free(key);
+
+				}
+
+			}
+
+		}
+	BN_free(Qx);
+	BN_free(Qy);
+	return 1;
+	}
+
+static int PKV(FILE *in, FILE *out)
+	{
+
+	char buf[2048], lbuf[2048];
+	char *keyword, *value;
+	int curve_nid = NID_undef;
+	BIGNUM *Qx = NULL, *Qy = NULL;
+	EC_KEY *key = NULL;
+	while(fgets(buf, sizeof buf, in) != NULL)
+		{
+		fputs(buf, out);
+		if (*buf == '[' && buf[2] == '-')
+			{
+			curve_nid = elookup_curve(buf, lbuf, NULL);
+			if (curve_nid == NID_undef)
+				return 0;
+				
+			}
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+		if (!strcmp(keyword, "Qx"))
+			{
+			if (!do_hex2bn(&Qx, value))
+				{
+				fprintf(stderr, "Invalid Qx value\n");
+				return 0;
+				}
+			}
+		if (!strcmp(keyword, "Qy"))
+			{
+			int rv;
+			if (!do_hex2bn(&Qy, value))
+				{
+				fprintf(stderr, "Invalid Qy value\n");
+				return 0;
+				}
+			key = EC_KEY_new_by_curve_name(curve_nid);
+			no_err = 1;
+			rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy);
+			no_err = 0;
+			EC_KEY_free(key);
+			fprintf(out, "Result = %s" RESP_EOL, rv ? "P":"F");
+			}
+
+		}
+	BN_free(Qx);
+	BN_free(Qy);
+	return 1;
+	}
+
+static int SigGen(FILE *in, FILE *out)
+	{
+	char buf[2048], lbuf[2048];
+	char *keyword, *value;
+	unsigned char *msg;
+	int curve_nid = NID_undef;
+	long mlen;
+	BIGNUM *Qx = NULL, *Qy = NULL;
+	EC_KEY *key = NULL;
+	ECDSA_SIG *sig = NULL;
+	const EVP_MD *digest = NULL;
+	Qx = BN_new();
+	Qy = BN_new();
+	while(fgets(buf, sizeof buf, in) != NULL)
+		{
+		fputs(buf, out);
+		if (*buf == '[')
+			{
+			curve_nid = elookup_curve(buf, lbuf, &digest);
+			if (curve_nid == NID_undef)
+				return 0;
+			}
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+		if (!strcmp(keyword, "Msg"))
+			{
+			msg = hex2bin_m(value, &mlen);
+			if (!msg)
+				{
+				fprintf(stderr, "Invalid Message\n");
+				return 0;
+				}
+
+			key = EC_KEY_new_by_curve_name(curve_nid);
+			if (!EC_KEY_generate_key(key))
+				{
+				fprintf(stderr, "Error generating key\n");
+				return 0;
+				}
+
+			if (!ec_get_pubkey(key, Qx, Qy))
+				{
+				fprintf(stderr, "Error getting public key\n");
+				return 0;
+				}
+
+	    		sig = FIPS_ecdsa_sign(key, msg, mlen, digest);
+
+			if (!sig)
+				{
+				fprintf(stderr, "Error signing message\n");
+				return 0;
+				}
+
+			do_bn_print_name(out, "Qx", Qx);
+			do_bn_print_name(out, "Qy", Qy);
+			do_bn_print_name(out, "R", sig->r);
+			do_bn_print_name(out, "S", sig->s);
+
+			EC_KEY_free(key);
+			OPENSSL_free(msg);
+			FIPS_ecdsa_sig_free(sig);
+
+			}
+
+		}
+	BN_free(Qx);
+	BN_free(Qy);
+	return 1;
+	}
+
+static int SigVer(FILE *in, FILE *out)
+	{
+	char buf[2048], lbuf[2048];
+	char *keyword, *value;
+	unsigned char *msg = NULL;
+	int curve_nid = NID_undef;
+	long mlen;
+	BIGNUM *Qx = NULL, *Qy = NULL;
+	EC_KEY *key = NULL;
+	ECDSA_SIG sg, *sig = &sg;
+	const EVP_MD *digest = NULL;
+	sig->r = NULL;
+	sig->s = NULL;
+	while(fgets(buf, sizeof buf, in) != NULL)
+		{
+		fputs(buf, out);
+		if (*buf == '[')
+			{
+			curve_nid = elookup_curve(buf, lbuf, &digest);
+			if (curve_nid == NID_undef)
+				return 0;
+			}
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+		if (!strcmp(keyword, "Msg"))
+			{
+			msg = hex2bin_m(value, &mlen);
+			if (!msg)
+				{
+				fprintf(stderr, "Invalid Message\n");
+				return 0;
+				}
+			}
+			
+		if (!strcmp(keyword, "Qx"))
+			{
+			if (!do_hex2bn(&Qx, value))
+				{
+				fprintf(stderr, "Invalid Qx value\n");
+				return 0;
+				}
+			}
+		if (!strcmp(keyword, "Qy"))
+			{
+			if (!do_hex2bn(&Qy, value))
+				{
+				fprintf(stderr, "Invalid Qy value\n");
+				return 0;
+				}
+			}
+		if (!strcmp(keyword, "R"))
+			{
+			if (!do_hex2bn(&sig->r, value))
+				{
+				fprintf(stderr, "Invalid R value\n");
+				return 0;
+				}
+			}
+		if (!strcmp(keyword, "S"))
+			{
+			int rv;
+			if (!do_hex2bn(&sig->s, value))
+				{
+				fprintf(stderr, "Invalid S value\n");
+				return 0;
+				}
+			key = EC_KEY_new_by_curve_name(curve_nid);
+			rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy);
+
+			if (rv != 1)
+				{
+				fprintf(stderr, "Error setting public key\n");
+				return 0;
+				}
+
+			no_err = 1;
+	    		rv = FIPS_ecdsa_verify(key, msg, mlen, digest, sig);
+			EC_KEY_free(key);
+			if (msg)
+				OPENSSL_free(msg);
+			no_err = 0;
+
+			fprintf(out, "Result = %s" RESP_EOL, rv ? "P":"F");
+			}
+
+		}
+	if (sig->r)
+		BN_free(sig->r);
+	if (sig->s)
+		BN_free(sig->s);
+	if (Qx)
+		BN_free(Qx);
+	if (Qy)
+		BN_free(Qy);
+	return 1;
+	}
+#ifdef FIPS_ALGVS
+int fips_ecdsavs_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+	{
+	FILE *in = NULL, *out = NULL;
+	const char *cmd = argv[1];
+	int rv = 0;
+
+	fips_algtest_init_nofips();
+	if(!FIPS_mode_set(1)) {
+		fprintf(stderr, "Can't set FIPS mode\n");
+		exit(1);
+	}
+
+	if (argc == 4)
+		{
+		in = fopen(argv[2], "r");
+		if (!in)
+			{
+			fprintf(stderr, "Error opening input file\n");
+			exit(1);
+			}
+		out = fopen(argv[3], "w");
+		if (!out)
+			{
+			fprintf(stderr, "Error opening output file\n");
+			exit(1);
+			}
+		}
+	else if (argc == 2)
+		{
+		in = stdin;
+		out = stdout;
+		}
+
+	if (!cmd)
+		{
+		fprintf(stderr, "fips_ecdsavs [KeyPair|PKV|SigGen|SigVer]\n");
+		return 1;
+		}
+	if (!strcmp(cmd, "KeyPair"))
+		rv = KeyPair(in, out);
+	else if (!strcmp(cmd, "PKV"))
+		rv = PKV(in, out);
+	else if (!strcmp(cmd, "SigVer"))
+		rv = SigVer(in, out);
+	else if (!strcmp(cmd, "SigGen"))
+		rv = SigGen(in, out);
+	else
+		{
+		fprintf(stderr, "Unknown command %s\n", cmd);
+		return 1;
+		}
+
+	if (argc == 4)
+		{
+		fclose(in);
+		fclose(out);
+		}
+
+	if (rv <= 0)
+		{
+		fprintf(stderr, "Error running %s\n", cmd);
+		return 1;
+		}
+
+	return 0;
+	}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_err.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_err.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,89 @@
+/* fips/utl/fips_err.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+/* FIPS error callbacks */
+
+static void (*fips_put_error_cb)(int lib, int func,int reason,const char *file,int line) = 0;
+static void (*fips_add_error_vdata)(int num, va_list args) = 0;
+
+void FIPS_put_error(int lib, int func,int reason,const char *file,int line)
+	{
+	if (fips_put_error_cb)
+		fips_put_error_cb(lib, func, reason, file, line);
+	}
+
+void FIPS_add_error_data(int num, ...)
+	{
+	if (fips_add_error_vdata)
+		{
+		va_list args;
+		va_start(args, num);
+		fips_add_error_vdata(num, args);
+		va_end(args);
+		}
+	}
+
+void FIPS_set_error_callbacks(
+	void (*put_cb)(int lib, int func,int reason,const char *file,int line),
+	void (*add_cb)(int num, va_list args) )
+	{
+	fips_put_error_cb = put_cb;
+	fips_add_error_vdata = add_cb;
+	}
+
+
Index: openssl-1.0.2j/crypto/fips/fips_gcmtest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_gcmtest.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,575 @@
+/* fips/aes/fips_gcmtest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#define OPENSSL_FIPSAPI
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("No FIPS GCM support\n");
+    return(0);
+}
+#else
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "fips_utl.h"
+
+static void gcmtest(FILE *in, FILE *out, int encrypt)
+	{
+	char buf[2048];
+	char lbuf[2048];
+	char *keyword, *value;
+	int keylen = -1, ivlen = -1, aadlen = -1, taglen = -1, ptlen = -1;
+	int rv;
+	long l;
+	unsigned char *key = NULL, *iv = NULL, *aad = NULL, *tag = NULL;
+	unsigned char *ct = NULL, *pt = NULL;
+	EVP_CIPHER_CTX ctx;
+	const EVP_CIPHER *gcm = NULL;
+	FIPS_cipher_ctx_init(&ctx);
+
+	while(fgets(buf,sizeof buf,in) != NULL)
+		{
+		fputs(buf,out);
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+		if(!strcmp(keyword,"[Keylen"))
+			{
+			keylen = atoi(value);
+			if (keylen == 128)
+				gcm = EVP_aes_128_gcm();
+			else if (keylen == 192)
+				gcm = EVP_aes_192_gcm();
+			else if (keylen == 256)
+				gcm = EVP_aes_256_gcm();
+			else 
+				{
+				fprintf(stderr, "Unsupported keylen %d\n",
+							keylen);
+				}
+			keylen >>= 3;
+			}
+		else if (!strcmp(keyword, "[IVlen"))
+			ivlen = atoi(value) >> 3;
+		else if (!strcmp(keyword, "[AADlen"))
+			aadlen = atoi(value) >> 3;
+		else if (!strcmp(keyword, "[Taglen"))
+			taglen = atoi(value) >> 3;
+		else if (!strcmp(keyword, "[PTlen"))
+			ptlen = atoi(value) >> 3;
+		else if(!strcmp(keyword,"Key"))
+			{
+			key = hex2bin_m(value, &l);
+			if (l != keylen)
+				{
+				fprintf(stderr, "Inconsistent Key length\n");
+				exit(1);
+				}
+			}
+		else if(!strcmp(keyword,"IV"))
+			{
+			iv = hex2bin_m(value, &l);
+			if (l != ivlen)
+				{
+				fprintf(stderr, "Inconsistent IV length\n");
+				exit(1);
+				}
+			}
+		else if(!strcmp(keyword,"PT"))
+			{
+			pt = hex2bin_m(value, &l);
+			if (l != ptlen)
+				{
+				fprintf(stderr, "Inconsistent PT length\n");
+				exit(1);
+				}
+			}
+		else if(!strcmp(keyword,"CT"))
+			{
+			ct = hex2bin_m(value, &l);
+			if (l != ptlen)
+				{
+				fprintf(stderr, "Inconsistent CT length\n");
+				exit(1);
+				}
+			}
+		else if(!strcmp(keyword,"AAD"))
+			{
+			aad = hex2bin_m(value, &l);
+			if (l != aadlen)
+				{
+				fprintf(stderr, "Inconsistent AAD length\n");
+				exit(1);
+				}
+			}
+		else if(!strcmp(keyword,"Tag"))
+			{
+			tag = hex2bin_m(value, &l);
+			if (l != taglen)
+				{
+				fprintf(stderr, "Inconsistent Tag length\n");
+				exit(1);
+				}
+			}
+		if (encrypt && pt && aad && (iv || encrypt==1))
+			{
+			tag = OPENSSL_malloc(taglen);
+			FIPS_cipherinit(&ctx, gcm, NULL, NULL, 1);
+			/* Relax FIPS constraints for testing */
+			M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0);
+			if (encrypt == 1)
+				{
+				static unsigned char iv_fixed[4] = {1,2,3,4};
+				if (!iv)
+					iv = OPENSSL_malloc(ivlen);
+				FIPS_cipherinit(&ctx, NULL, key, NULL, 1);
+				FIPS_cipher_ctx_ctrl(&ctx,
+						EVP_CTRL_GCM_SET_IV_FIXED,
+						4, iv_fixed);
+				if (!FIPS_cipher_ctx_ctrl(&ctx,
+					EVP_CTRL_GCM_IV_GEN, 0, iv))
+					{
+					fprintf(stderr, "IV gen error\n");
+					exit(1);
+					}
+				OutputValue("IV", iv, ivlen, out, 0);
+				}
+			else
+				FIPS_cipherinit(&ctx, NULL, key, iv, 1);
+
+
+			if (aadlen)
+				FIPS_cipher(&ctx, NULL, aad, aadlen);
+			if (ptlen)
+				{
+				ct = OPENSSL_malloc(ptlen);
+				rv = FIPS_cipher(&ctx, ct, pt, ptlen);
+				}
+			FIPS_cipher(&ctx, NULL, NULL, 0);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG,
+								taglen, tag);	
+			OutputValue("CT", ct, ptlen, out, 0);
+			OutputValue("Tag", tag, taglen, out, 0);
+			if (iv)
+				OPENSSL_free(iv);
+			if (aad)
+				OPENSSL_free(aad);
+			if (ct)
+				OPENSSL_free(ct);
+			if (pt)
+				OPENSSL_free(pt);
+			if (key)
+				OPENSSL_free(key);
+			if (tag)
+				OPENSSL_free(tag);
+			iv = aad = ct = pt = key = tag = NULL;
+			}	
+		if (!encrypt && tag)
+			{
+			FIPS_cipherinit(&ctx, gcm, NULL, NULL, 0);
+			/* Relax FIPS constraints for testing */
+			M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0);
+			FIPS_cipherinit(&ctx, NULL, key, iv, 0);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, taglen, tag);
+			if (aadlen)
+				FIPS_cipher(&ctx, NULL, aad, aadlen);
+			if (ptlen)
+				{
+				pt = OPENSSL_malloc(ptlen);
+				rv = FIPS_cipher(&ctx, pt, ct, ptlen);
+				}
+			rv = FIPS_cipher(&ctx, NULL, NULL, 0);
+			if (rv < 0)
+				fprintf(out, "FAIL" RESP_EOL);
+			else
+				OutputValue("PT", pt, ptlen, out, 0);
+			if (iv)
+				OPENSSL_free(iv);
+			if (aad)
+				OPENSSL_free(aad);
+			if (ct)
+				OPENSSL_free(ct);
+			if (pt)
+				OPENSSL_free(pt);
+			if (key)
+				OPENSSL_free(key);
+			if (tag)
+				OPENSSL_free(tag);
+			iv = aad = ct = pt = key = tag = NULL;
+			}
+		}
+	FIPS_cipher_ctx_cleanup(&ctx);	
+	}
+
+static void xtstest(FILE *in, FILE *out)
+	{
+	char buf[204800];
+	char lbuf[204800];
+	char *keyword, *value;
+	int inlen = 0;
+	int encrypt = 0;
+	long l;
+	unsigned char *key = NULL, *iv = NULL;
+	unsigned char *inbuf = NULL, *outbuf = NULL;
+	EVP_CIPHER_CTX ctx;
+	const EVP_CIPHER *xts = NULL;
+	FIPS_cipher_ctx_init(&ctx);
+
+	while(fgets(buf,sizeof buf,in) != NULL)
+		{
+		fputs(buf,out);
+		if (buf[0] == '[' && strlen(buf) >= 9)
+			{
+			if(!strncmp(buf,"[ENCRYPT]", 9))
+				encrypt = 1;
+			else if(!strncmp(buf,"[DECRYPT]", 9))
+				encrypt = 0;
+			}
+		if  (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+		else if(!strcmp(keyword,"Key"))
+			{
+			key = hex2bin_m(value, &l);
+			if (l == 32)
+				xts = EVP_aes_128_xts();
+			else if (l == 64)
+				xts = EVP_aes_256_xts();
+			else
+				{
+				fprintf(stderr, "Inconsistent Key length\n");
+				exit(1);
+				}
+			}
+		else if(!strcmp(keyword,"i"))
+			{
+			iv = hex2bin_m(value, &l);
+			if (l != 16)
+				{
+				fprintf(stderr, "Inconsistent i length\n");
+				exit(1);
+				}
+			}
+		else if(encrypt && !strcmp(keyword,"PT"))
+			{
+			inbuf = hex2bin_m(value, &l);
+			inlen = l;
+			}
+		else if(!encrypt && !strcmp(keyword,"CT"))
+			{
+			inbuf = hex2bin_m(value, &l);
+			inlen = l;
+			}
+		if (inbuf)
+			{
+			FIPS_cipherinit(&ctx, xts, key, iv, encrypt);
+			outbuf = OPENSSL_malloc(inlen);
+			FIPS_cipher(&ctx, outbuf, inbuf, inlen);
+			OutputValue(encrypt ? "CT":"PT", outbuf, inlen, out, 0);
+			OPENSSL_free(inbuf);
+			OPENSSL_free(outbuf);
+			OPENSSL_free(key);
+			OPENSSL_free(iv);
+			iv = key = inbuf = outbuf = NULL;
+			}	
+		}
+	FIPS_cipher_ctx_cleanup(&ctx);	
+	}
+
+static void ccmtest(FILE *in, FILE *out)
+	{
+	char buf[200048];
+	char lbuf[200048];
+	char *keyword, *value;
+	long l;
+	unsigned char *Key = NULL, *Nonce = NULL;
+	unsigned char *Adata = NULL, *Payload = NULL;
+	unsigned char *CT = NULL;
+	int Plen = -1, Nlen = -1, Tlen = -1, Alen = -1;
+	int decr = 0;
+	EVP_CIPHER_CTX ctx;
+	const EVP_CIPHER *ccm = NULL;
+	FIPS_cipher_ctx_init(&ctx);
+
+	while(fgets(buf,sizeof buf,in) != NULL)
+		{
+		char *p;
+		fputs(buf,out);
+		redo:
+		if (!parse_line(&keyword, &value, lbuf, buf))
+			continue;
+
+		/* If surrounded by square brackets zap them */
+		if (keyword[0] == '[')
+			{
+			keyword++;
+			p = strchr(value, ']');
+			if (p)
+				*p = 0;
+			}
+		/* See if we have a comma separated list of parameters
+		 * if so copy rest of line back to buffer and redo later.
+		 */
+		p = strchr(value, ',');
+		if (p)
+			{
+			*p = 0;
+			strcpy(buf, p + 1);
+			strcat(buf, "\n");
+			decr = 1;
+			}
+		if (!strcmp(keyword,"Plen"))
+			Plen = atoi(value);
+		else if (!strcmp(keyword,"Nlen"))
+			Nlen = atoi(value);
+		else if (!strcmp(keyword,"Tlen"))
+			Tlen = atoi(value);
+		else if (!strcmp(keyword,"Alen"))
+			Alen = atoi(value);
+		if (p)
+			goto redo;
+		if (!strcmp(keyword,"Key"))
+			{
+			if (Key)
+				OPENSSL_free(Key);
+			Key = hex2bin_m(value, &l);
+			if (l == 16)
+				ccm = EVP_aes_128_ccm();
+			else if (l == 24)
+				ccm = EVP_aes_192_ccm();
+			else if (l == 32)
+				ccm = EVP_aes_256_ccm();
+			else
+				{
+				fprintf(stderr, "Inconsistent Key length\n");
+				exit(1);
+				}
+			}
+		else if (!strcmp(keyword,"Nonce"))
+			{
+			if (Nonce)
+				OPENSSL_free(Nonce);
+			Nonce = hex2bin_m(value, &l);
+			if (l != Nlen)
+				{
+				fprintf(stderr, "Inconsistent nonce length\n");
+				exit(1);
+				}
+			}
+		else if (!strcmp(keyword,"Payload") && !decr)
+			{
+			Payload = hex2bin_m(value, &l);
+			if (Plen && l != Plen)
+				{
+				fprintf(stderr, "Inconsistent Payload length\n");
+				exit(1);
+				}
+			}
+		else if (!strcmp(keyword,"Adata"))
+			{
+			if (Adata)
+				OPENSSL_free(Adata);
+			Adata = hex2bin_m(value, &l);
+			if (Alen && l != Alen)
+				{
+				fprintf(stderr, "Inconsistent Payload length\n");
+				exit(1);
+				}
+			}
+		else if (!strcmp(keyword,"CT") && decr)
+			{
+			CT = hex2bin_m(value, &l);
+			if (l != (Plen + Tlen))
+				{
+				fprintf(stderr, "Inconsistent CT length\n");
+				exit(1);
+				}
+			}
+		if (Payload)
+			{
+			FIPS_cipherinit(&ctx, ccm, NULL, NULL, 1);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, Tlen, 0);
+			FIPS_cipherinit(&ctx, NULL, Key, Nonce, 1);
+
+			FIPS_cipher(&ctx, NULL, NULL, Plen);
+			FIPS_cipher(&ctx, NULL, Adata, Alen);
+			CT = OPENSSL_malloc(Plen + Tlen);
+			FIPS_cipher(&ctx, CT, Payload, Plen);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, Tlen,
+						CT + Plen);
+			OutputValue("CT", CT, Plen + Tlen, out, 0);
+			OPENSSL_free(CT);
+			OPENSSL_free(Payload);
+			CT = Payload = NULL;
+			}
+		if (CT)
+			{
+			int rv;
+			int len = Plen == 0 ? 1: Plen;
+			FIPS_cipherinit(&ctx, ccm, NULL, NULL, 0);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0);
+			FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG,
+						Tlen, CT + Plen);
+			FIPS_cipherinit(&ctx, NULL, Key, Nonce, 0);
+			FIPS_cipher(&ctx, NULL, NULL, Plen);
+			FIPS_cipher(&ctx, NULL, Adata, Alen);
+			Payload = OPENSSL_malloc(len);
+			rv = FIPS_cipher(&ctx, Payload, CT, Plen);
+			if (rv >= 0)
+				{
+				if (rv == 0)
+					Payload[0] = 0;
+				fputs("Result = Pass" RESP_EOL, out);
+				OutputValue("Payload", Payload, len, out, 0);
+				}
+			else
+				fputs("Result = Fail" RESP_EOL, out);
+			OPENSSL_free(CT);
+			OPENSSL_free(Payload);
+			CT = Payload = NULL;
+			}
+		}
+	if (Key)
+		OPENSSL_free(Key);
+	if (Nonce)
+		OPENSSL_free(Nonce);
+	if (Adata)
+		OPENSSL_free(Adata);
+	FIPS_cipher_ctx_cleanup(&ctx);
+	}
+
+#ifdef FIPS_ALGVS
+int fips_gcmtest_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+	{
+	int encrypt;
+	int xts = 0, ccm = 0;
+	FILE *in, *out;
+	if (argc == 4)
+		{
+		in = fopen(argv[2], "r");
+		if (!in)
+			{
+			fprintf(stderr, "Error opening input file\n");
+			exit(1);
+			}
+		out = fopen(argv[3], "w");
+		if (!out)
+			{
+			fprintf(stderr, "Error opening output file\n");
+			exit(1);
+			}
+		}
+	else if (argc == 2)
+		{
+		in = stdin;
+		out = stdout;
+		}
+	else
+		{
+		fprintf(stderr,"%s [-encrypt|-decrypt]\n",argv[0]);
+		exit(1);
+		}
+	fips_algtest_init_nofips();
+	if(!FIPS_mode_set(1)) {
+		fprintf(stderr, "Can't set FIPS mode\n");
+		exit(1);
+	}
+	if(!strcmp(argv[1],"-encrypt"))
+		encrypt = 1;
+	else if(!strcmp(argv[1],"-encryptIVext"))
+		encrypt = 2;
+	else if(!strcmp(argv[1],"-decrypt"))
+		encrypt = 0;
+	else if(!strcmp(argv[1],"-ccm"))
+		ccm = 1;
+	else if(!strcmp(argv[1],"-xts"))
+		xts = 1;
+	else
+		{
+		fprintf(stderr,"Don't know how to %s.\n",argv[1]);
+		exit(1);
+		}
+
+	if (ccm)
+		ccmtest(in, out);
+	else if (xts)
+		xtstest(in, out);
+	else
+		gcmtest(in, out, encrypt);
+
+	if (argc == 4)
+		{
+		fclose(in);
+		fclose(out);
+		}
+
+	return 0;
+}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_hmactest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_hmactest.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,328 @@
+/* fips_hmactest.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).
+ *
+ */
+
+#define OPENSSL_FIPSAPI
+
+#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/bn.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+    printf("No FIPS HMAC support\n");
+    return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+static int hmac_test(const EVP_MD *md, FILE *out, FILE *in);
+static int print_hmac(const EVP_MD *md, FILE *out,
+		unsigned char *Key, int Klen,
+		unsigned char *Msg, int Msglen, int Tlen);
+
+#ifdef FIPS_ALGVS
+int fips_hmactest_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+	{
+	FILE *in = NULL, *out = NULL;
+
+	int ret = 1;
+	fips_algtest_init_nofips();
+	if(!FIPS_mode_set(1)) {
+		fprintf(stderr, "Can't set FIPS mode\n");
+		exit(1);
+	}
+
+	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 (!hmac_test(EVP_sha1(), out, in))
+		{
+		fprintf(stderr, "FATAL hmac file processing error\n");
+		goto end;
+		}
+	else
+		ret = 0;
+
+	end:
+
+	if (in && (in != stdin))
+		fclose(in);
+	if (out && (out != stdout))
+		fclose(out);
+
+	return ret;
+
+	}
+
+#define HMAC_TEST_MAXLINELEN	1024
+
+int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
+	{
+	char *linebuf, *olinebuf, *p, *q;
+	char *keyword, *value;
+	unsigned char *Key = NULL, *Msg = NULL;
+	int Count, Klen, Tlen;
+	long Keylen, Msglen;
+	int ret = 0;
+	int lnum = 0;
+
+	olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
+	linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
+
+	if (!linebuf || !olinebuf)
+		goto error;
+
+	Count = -1;
+	Klen = -1;
+	Tlen = -1;
+
+	while (fgets(olinebuf, HMAC_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)
+			{
+			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,"[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, "Count"))
+			{
+			if (Count != -1)
+				goto parse_error;
+			Count = atoi(value);
+			if (Count < 0)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Klen"))
+			{
+			if (Klen != -1)
+				goto parse_error;
+			Klen = atoi(value);
+			if (Klen < 0)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Tlen"))
+			{
+			if (Tlen != -1)
+				goto parse_error;
+			Tlen = atoi(value);
+			if (Tlen < 0)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Msg"))
+			{
+			if (Msg)
+				goto parse_error;
+			Msg = hex2bin_m(value, &Msglen);
+			if (!Msg)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Key"))
+			{
+			if (Key)
+				goto parse_error;
+			Key = hex2bin_m(value, &Keylen);
+			if (!Key)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "Mac"))
+			continue;
+		else
+			goto parse_error;
+
+		fputs(olinebuf, out);
+
+		if (Key && Msg && (Tlen > 0) && (Klen > 0))
+			{
+			if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
+				goto error;
+			OPENSSL_free(Key);
+			Key = NULL;
+			OPENSSL_free(Msg);
+			Msg = NULL;
+			Klen = -1;
+			Tlen = -1;
+			Count = -1;
+			}
+
+		}
+
+
+	ret = 1;
+
+
+	error:
+
+	if (olinebuf)
+		OPENSSL_free(olinebuf);
+	if (linebuf)
+		OPENSSL_free(linebuf);
+	if (Key)
+		OPENSSL_free(Key);
+	if (Msg)
+		OPENSSL_free(Msg);
+
+	return ret;
+
+	parse_error:
+
+	fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
+
+	goto error;
+
+	}
+
+static int print_hmac(const EVP_MD *emd, FILE *out,
+		unsigned char *Key, int Klen,
+		unsigned char *Msg, int Msglen, int Tlen)
+	{
+	int i, mdlen;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
+						(unsigned int *)&mdlen))
+		{
+		fputs("Error calculating HMAC\n", stderr);
+		return 0;
+		}
+	if (Tlen > mdlen)
+		{
+		fputs("Parameter error, Tlen > HMAC length\n", stderr);
+		return 0;
+		}
+	fputs("Mac = ", out);
+	for (i = 0; i < Tlen; i++)
+		fprintf(out, "%02x", md[i]);
+	fputs(RESP_EOL, out);
+	return 1;
+	}
+
+#endif
Index: openssl-1.0.2j/crypto/fips/fips_rngvs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_rngvs.c	2017-03-16 17:27:29.544992910 +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 <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    printf("No FIPS RNG support\n");
+    return 0;
+}
+#else
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/x509v3.h>
+#include <string.h>
+#include <ctype.h>
+
+#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_x931_set_key(key, keylen);
+	    FIPS_x931_seed(v,16);
+	    FIPS_x931_set_dt(dt);
+	    if (FIPS_x931_bytes(ret,16) <= 0)
+		{
+		fprintf(stderr, "Error getting PRNG value\n");
+	        return;
+	        }
+
+	    OutputValue("R", ret, 16, stdout, 0);
+	    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_x931_set_key(key, keylen);
+	    FIPS_x931_seed(v,16);
+	    for (i = 0; i < 10000; i++)
+		{
+		    FIPS_x931_set_dt(dt);
+		    if (FIPS_x931_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;
+			}
+		}
+
+	    OutputValue("R", ret, 16, stdout, 0);
+	    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_x931_reset();
+    if (!FIPS_x931_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
Index: openssl-1.0.2j/crypto/fips/fips_rsa_lib.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_rsa_lib.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,109 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * 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
+ *    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).
+ *
+ */
+
+#define OPENSSL_FIPSAPI
+
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+/* Minimal FIPS versions of FIPS_rsa_new() and FIPS_rsa_free: to
+ * reduce external dependencies.
+ */
+
+RSA *FIPS_rsa_new(void)
+	{
+
+	return RSA_new_method(NULL);
+#if 0
+	RSA *ret;
+	ret = OPENSSL_malloc(sizeof(RSA));
+	if (!ret)
+		return NULL;
+	memset(ret, 0, sizeof(RSA));
+	ret->meth = RSA_PKCS1_SSLeay();
+	if (ret->meth->init)
+		ret->meth->init(ret);
+	return ret;
+#endif
+	}
+
+void FIPS_rsa_free(RSA *r)
+	{
+	if (!r)
+		return;
+	RSA_free(r);
+#if 0
+	if (r->meth->finish)
+		r->meth->finish(r);
+	if (r->n != NULL) BN_clear_free(r->n);
+	if (r->e != NULL) BN_clear_free(r->e);
+	if (r->d != NULL) BN_clear_free(r->d);
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
+	if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
+	if (r->iqmp != NULL) BN_clear_free(r->iqmp);
+	if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
+	if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
+	OPENSSL_free(r);
+#endif
+	}
+
Index: openssl-1.0.2j/crypto/fips/fips_rsagtest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_rsagtest.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,683 @@
+/* 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 <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/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+RSA *FIPS_rsa_new(void);
+void FIPS_rsa_free(RSA *r);
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+    printf("No FIPS RSA support\n");
+    return(0);
+}
+
+#else
+
+#include "fips_utl.h"
+
+int rsa_KeyGen(FILE *out, FILE *in);
+int rsa_PrimeKAT(FILE *out, FILE *in);
+int rsa_PrimeGen(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;
+	const char *cmd = argv[1];
+
+	int ret = 1;
+
+	if(!FIPS_mode_set(1))
+		{
+		do_print_errors();
+		goto end;
+		}
+
+	if (!cmd) 
+		{
+		fprintf(stderr, "fips_rsagtest [KeyGen|PrimeKAT|PrimeGen]\n");
+		goto end;
+		}
+
+	if (argc == 2)
+		in = stdin;
+	else
+		in = fopen(argv[2], "r");
+
+	if (argc <= 3)
+		out = stdout;
+	else
+		out = fopen(argv[3], "w");
+
+	if (!in)
+		{
+		fprintf(stderr, "FATAL input initialization error\n");
+		goto end;
+		}
+
+	if (!out)
+		{
+		fprintf(stderr, "FATAL output initialization error\n");
+		goto end;
+		}
+
+	if (!strcmp(cmd, "KeyGen"))
+		ret = rsa_KeyGen(out, in);
+	else if (!strcmp(cmd, "PrimeKAT"))
+		ret = rsa_PrimeKAT(out, in);
+	else if (!strcmp(cmd, "PrimeGen"))
+		ret = rsa_PrimeGen(out, in);
+	else
+		{
+		fprintf(stderr, "Unknown command %s\n", cmd);
+		goto end;
+		}
+
+	if (!ret)
+		{
+		fprintf(stderr, "FATAL RSAGTEST file processing error in %s\n", cmd);
+		goto end;
+		}
+
+	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_KeyGen(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))
+		{
+		/* Test tool emits a 0xff at the end of the file */
+		if (((unsigned char*)olinebuf)[0] == 0xff)
+			break;
+		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;
+
+	}
+
+
+int do_prime_test(int mod, BIGNUM *e, BIGNUM *prandom, BIGNUM *qrandom)
+{
+	RSA *rsa = NULL;
+	int result;
+
+	rsa = FIPS_rsa_new();
+	if (!rsa)
+		return -1;
+
+	if (!qrandom)
+		{
+			qrandom = BN_new();
+			BN_one(qrandom);
+		}
+
+	/* prandom and qrandom should be freed in FIPS_rsa_free */
+	rsa->p = prandom;
+	rsa->q = qrandom;
+	
+	result = 1;
+	if (!RSA_generate_key_ex(rsa, mod, e, NULL))
+		result = 0;
+	FIPS_rsa_free(rsa);
+
+	if (!result)
+		do_print_errors();
+
+	return result;
+}
+
+
+int rsa_PrimeKAT(FILE *out, FILE *in)
+	{
+	char *linebuf, *olinebuf, *p, *q;
+	char *keyword, *value;
+	RSA *rsa = NULL;
+	BIGNUM *prandom = NULL, *qrandom = NULL;
+	BIGNUM *e = NULL;
+	int mod = 0;
+	int result = 0;
+	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))
+		{
+		/* Test tool emits a 0xff at the end of the file */
+		if (((unsigned char*)olinebuf)[0] == 0xff)
+			break;
+		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)
+			{
+			fputs(olinebuf, out);
+			continue;
+			}
+
+		if (*keyword == '[')
+			keyword++;
+
+		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;
+		/* For [things], remove trailing ] and whitespace */
+		if (*linebuf == '[')
+			{
+				while (isspace((unsigned char)*p) || *p == ']')
+					*p-- = 0;
+			}
+
+		/* collected e, prandom and next thing is not qrandom -> trigger test */
+		if (e && prandom && (qrandom || strcmp(keyword, "qrandom")))
+			{
+				result = do_prime_test(mod, e, prandom, qrandom);
+				BN_free(e);
+				prandom = NULL;
+				qrandom = NULL;
+				e = NULL;
+				if (result == -1)
+					goto error;
+				fprintf(out, "Result = %c\n\n", result ? 'P' : 'F');
+			}
+
+		if (!strcmp(keyword, "mod"))
+			{
+			mod = atoi(value);
+			if (!mod)
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "prandom"))
+			{
+			if (prandom || !do_hex2bn(&prandom,value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "qrandom"))
+			{
+			if (qrandom || !do_hex2bn(&qrandom,value))
+				goto parse_error;
+			}
+		else if (!strcmp(keyword, "e"))
+			{
+			if (!do_hex2bn(&e,value))
+				goto parse_error;
+			}
+		else if (*linebuf == '[')
+			{
+			/* just copy */
+			}
+		else
+			goto parse_error;
+
+		fputs(olinebuf, out);
+
+		}
+
+	/* trigger last test -- the test should be abstracted out into a function */
+	if (e && prandom)
+		{
+			result = do_prime_test(mod, e, prandom, qrandom);
+			BN_free(e);
+			prandom = NULL;
+			qrandom = NULL;
+			e = NULL;
+			if (result == -1)
+				goto error;
+			fprintf(out, "Result = %c\n\n", result ? 'P' : 'F');
+		}
+
+	ret = 1;
+
+	error:
+
+	if (olinebuf)
+		OPENSSL_free(olinebuf);
+	if (linebuf)
+		OPENSSL_free(linebuf);
+	
+	if (prandom)
+		BN_free(prandom);
+	if (qrandom)
+		BN_free(qrandom);
+	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;
+
+	}
+
+int rsa_PrimeGen(FILE *out, FILE *in)
+	{
+	char *linebuf;
+	RSA *rsa = NULL;
+	BIGNUM *e = NULL;
+	int mod = 0;
+	int N = 0;
+	int ret = 0;
+	int lnum = 0;
+
+	linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
+	e = BN_new();
+
+	if (!linebuf || !e)
+		goto error;
+
+	BN_set_word(e, 65537);
+
+	while (fgets(linebuf, RSA_TEST_MAXLINELEN, in))
+		{
+		/* Test tool emits a 0xff at the end of the file */
+		if (((unsigned char*)linebuf)[0] == 0xff)
+			break;
+		lnum++;
+		fputs(linebuf, out);
+		if (!strncmp(linebuf, "[mod = ", 7))
+			{
+			mod = atoi(linebuf + 7);
+			if (!mod)
+				goto parse_error;
+			}
+
+		if (!strncmp(linebuf, "N = ", 4))
+			{
+			N = atoi(linebuf + 4);
+			for (int i = 0; i < N; i++)
+				{
+				rsa = FIPS_rsa_new();
+				if (!RSA_generate_key_ex(rsa, mod, e, NULL)) {
+					fflush(out);
+					do_print_errors();
+					goto error;
+				}
+
+				do_bn_print_name(out, "e", rsa->e);
+				do_bn_print_name(out, "p", rsa->p);
+				do_bn_print_name(out, "q", rsa->q);
+				do_bn_print_name(out, "n", rsa->n);
+				do_bn_print_name(out, "d", rsa->d);
+				FIPS_rsa_free(rsa);
+				rsa = NULL;
+				}
+			}
+		}
+
+	ret = 1;
+
+	error:
+
+	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;
+
+		return 0;
+	}
+
+
+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)) {
+		fflush(out);
+		do_print_errors();
+		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)) {
+		fflush(out);
+		do_print_errors();
+		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
Index: openssl-1.0.2j/crypto/fips/fips_rsastest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_rsastest.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,386 @@
+/* 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 <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/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+RSA *FIPS_rsa_new(void);
+void FIPS_rsa_free(RSA *r);
+
+#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)) {
+				fprintf(stderr,"X931 key generation failed!\n");
+				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)) {
+				fprintf (stderr, "printsig failed\n");
+				goto error;
+			}
+			OPENSSL_free(Msg);
+			Msg = NULL;
+			}
+
+		}
+
+	ret = 1;
+
+	error:
+	do_print_errors();
+
+	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;
+
+        if ((pk=EVP_PKEY_new()) == NULL)
+		goto error;
+	EVP_PKEY_set1_RSA(pk, rsa);
+
+	siglen = RSA_size(rsa);
+	sigbuf = OPENSSL_malloc(siglen);
+	if (!sigbuf) {
+		fprintf(stderr,"OPENSSL_malloc %d failed.\n", siglen);
+		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)) {
+		fprintf(stderr,"EVP_SignInit_ex failed.\n");
+		goto error;
+	}
+	if (!EVP_SignUpdate(&ctx, Msg, Msglen)) {
+		fprintf(stderr,"EVP_SignUpdate failed.\n");
+		goto error;
+	}
+	if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, pk)) {
+		fprintf(stderr,"EVP_SignFinal failed.\n");
+		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
Index: openssl-1.0.2j/crypto/fips/fips_rsavtest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_rsavtest.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,382 @@
+/* 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 <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>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+RSA *FIPS_rsa_new(void);
+void FIPS_rsa_free(RSA *r);
+
+#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;
+
+        if ((pk=EVP_PKEY_new()) == NULL)
+                goto error;
+        EVP_PKEY_set1_RSA(pk, 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
Index: openssl-1.0.2j/crypto/fips/fips_shatest.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_shatest.c	2017-03-16 17:27:29.544992910 +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 <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+#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
Index: openssl-1.0.2j/crypto/fips/fips_tlsvs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_tlsvs.c	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,539 @@
+/* ====================================================================
+ * 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.
+ *
+ */
+/*---------------------------------------------
+  TLS Algorithm Validation Suite
+  Test Program
+
+  Donated to OpenSSL by:
+  SUSE LLC
+  ----------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#include <openssl/ssl.h>
+
+#include <openssl/err.h>
+#include "e_os.h"
+
+extern int private_tls1_PRF(long digest_mask,
+	const void *seed1, int seed1_len,
+	const void *seed2, int seed2_len,
+	const void *seed3, int seed3_len,
+	const void *seed4, int seed4_len,
+	const void *seed5, int seed5_len,
+	const unsigned char *sec, int slen,
+	unsigned char *out1,
+	unsigned char *out2, int olen);
+
+#define SSL_HANDSHAKE_MAC_MD5 0x10
+#define SSL_HANDSHAKE_MAC_SHA 0x20
+#define SSL_HANDSHAKE_MAC_SHA256 0x80
+#define SSL_HANDSHAKE_MAC_SHA384 0x100
+#define TLS1_PRF_DGST_MASK   (0xff << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_DGST_SHIFT 10
+#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
+#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+    printf("No FIPS TLS support\n");
+    return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+#define VERBOSE 0
+
+/*-----------------------------------------------*/
+
+
+/*================================================*/
+/*----------------------------
+  # CAVS 12.0
+  # 'TLS' information for abc
+  # Cases tested: [TLS 1.0/1.1] [TLS 1.2, SHA-256], [TLS 1.2, SHA-384], [TLS 1.2, SHA-512]
+  # Generated on: 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 len;
+    char amode[8] = "";
+    char atest[8] = "";
+    int akeysz = 0;
+
+    /* TLS stuff */
+    int shabits = 0, premasterlength = 0, tls = 0, keyblocklength = 0;
+    unsigned char *premastersecret = NULL;
+    unsigned char serverHello_random[2048];
+    unsigned int serverhellorandomlen = 0;
+    unsigned char clientHello_random[2048];
+    unsigned int clienthellorandomlen = 0;
+    unsigned char server_random[2048];
+    unsigned int serverrandomlen = 0;
+    unsigned char client_random[2048];
+    unsigned int clientrandomlen = 0;
+    unsigned char mastersecret[2048];
+    unsigned int digest_mask = 0;
+    unsigned char seed[2048];
+    unsigned char *keyblock = NULL;
+    unsigned char *keyblocktmp = NULL;
+    unsigned char tmpsecret[80];
+    /* end of TLS stuff */
+
+    int err = 0, step = 0;
+    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;
+	}
+
+
+    /* hey ho lets go */
+
+    while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
+	{
+	tidy_line(tbuf, ibuf);
+	printf("step=%d ibuf=%s",step,ibuf);
+	switch (step)
+	    {
+	case 0:  /* read preamble */
+	    if (ibuf[0] == '\n')
+		{ /* end of preamble */
+		/* not really anything mandatory, would need to check here */
+		    {
+		    fputs(ibuf, rfp);
+		    ++ step;
+		    }
+		}
+	    else if (ibuf[0] != '#')
+		{
+		printf("Invalid preamble item: %s\n", ibuf);
+		err = 1;
+		}
+	    else
+		{ /* process preamble */
+		char *pp = ibuf+2;
+		if (akeysz)
+		    { /* insert current time & date */
+		    time_t rtim = time(0);
+		    fprintf(rfp, "# %s", ctime(&rtim));
+		    }
+		else
+		    {
+		    fputs(ibuf, rfp);
+		    if (strncmp(pp, "'TLS' ", 5) == 0)
+			{
+			if (VERBOSE)
+				printf("Test = %s, Mode = %s\n", atest, amode);
+			}
+		    else if (strncasecmp(pp, "Cases Tested: ", 14) == 0)
+			{
+			if (VERBOSE)
+				printf("Cases %s\n", pp+14);
+			}
+		    }
+		}
+	    break;
+
+	case 1:  /* [ENCRYPT] | [DECRYPT] */
+	    if (ibuf[0] == '[')
+		{
+		fputs(ibuf, rfp);
+		if (strncasecmp(ibuf, "[TLS 1.0/1.1]", 13 ) == 0) {
+			tls = 10;
+			shabits = 1;
+			printf("TLS 1.0/1.1\n");
+			premasterlength = keyblocklength = 0;
+                } else
+		if (sscanf(ibuf, "[TLS 1.2, SHA-%d]", &shabits) == 1) {
+			tls = 12;
+			printf("TLS 1.2 shabits %d\n", shabits);
+			premasterlength = keyblocklength = 0;
+                } else if (sscanf(ibuf, "[pre-master secret length = %d]", &premasterlength) == 1) {
+			printf("premaster length %d\n", premasterlength);
+			if (premasterlength % 8) {
+				printf("premaster length not byte sized?? %d\n", premasterlength);
+				err = 1;
+				break;
+			}
+			premasterlength /= 8;
+			free(premastersecret);
+			premastersecret = malloc(premasterlength);
+                } else if (sscanf(ibuf, "[key block length = %d]", &keyblocklength) == 1) {
+			printf("key block length %d\n", keyblocklength);
+			if (keyblocklength % 8) {
+				printf("keyblock length not byte sized?? %d\n", keyblocklength);
+				err = 1;
+				break;
+			}
+			free(keyblock);
+			free(keyblocktmp);
+			keyblocklength /= 8;
+			keyblock = malloc(keyblocklength);
+			keyblocktmp = malloc(keyblocklength);
+		} else {
+		    printf("Invalid keyword: %s\n", ibuf);
+		    err = 1;
+		}
+		if (keyblocklength && premasterlength)
+			++step;
+		break;
+		}
+	    else if (strncasecmp(ibuf,"COUNT = ", 8) != 0)
+		{
+		err = 1;
+		printf("Missing new section or COUNT =  keyword\n");
+		break;
+		}
+	    else
+		step = 2;
+
+	case 2: /* COUNT = and pre_master_secret = xxxx */
+	    fputs(ibuf, rfp);
+	    if(*ibuf == '\n')
+		break;
+	    if(!strncasecmp(ibuf,"COUNT = ",8))
+		break;
+
+	    if (strncasecmp(ibuf, "pre_master_secret = ", 20) != 0) {
+		printf("Missing pre_master_secret\n");
+		err = 1;
+	    } else {
+		len = hex2bin((char*)ibuf+20, premastersecret);
+		if (len < 0) {
+		    printf("Invalid premastersecret\n");
+		    err =1;
+		    break;
+		}
+                if (len != premasterlength) {
+		    printf("Invalid len %d vs premasterlenght %d\n", len, premasterlength);
+		    err =1;
+		    break;
+                }
+		PrintValue("pre_master_secret", premastersecret, len);
+		step++;
+	    }
+	    break;
+
+	case 3: /* serverHello_random= xxxx */
+	    fputs(ibuf, rfp);
+	    if (strncasecmp(ibuf, "serverHello_random = ", 21) != 0) {
+		printf("Missing serverHello_random\n");
+		err = 1;
+	    } else {
+		len = hex2bin((char*)ibuf+21, serverHello_random);
+		if (len < 0 || len > sizeof(serverHello_random)) {
+		    printf("Invalid serverHello_random %d vs %d\n", len, (int)sizeof(serverHello_random));
+		    err =1;
+		    break;
+		}
+		PrintValue("serverHello_random", serverHello_random, len);
+		serverhellorandomlen = len;
+		step++;
+	    }
+	    break;
+
+	case 4: /* clientHello_random = xxxx */
+	    fputs(ibuf, rfp);
+	    if (strncasecmp(ibuf, "clientHello_random = ", 21) != 0) {
+		printf("Missing clientHello_random\n");
+		err = 1;
+	    } else {
+		len = hex2bin((char*)ibuf+21, clientHello_random);
+		if (len < 0 || len > sizeof(clientHello_random)) {
+		    printf("Invalid clientHello_random %d vs %d\n", len, (int)sizeof(clientHello_random));
+		    err =1;
+		    break;
+		}
+		clienthellorandomlen = len;
+		PrintValue("serverHello_random", clientHello_random, len);
+		step++;
+            }
+	    break;
+
+	case 5: /* server_random = xxxx */
+	    fputs(ibuf, rfp);
+	    if (strncasecmp(ibuf, "server_random = ", 16) != 0) {
+		printf("Missing server_random\n");
+		err = 1;
+	    } else {
+		len = hex2bin((char*)ibuf+16, server_random);
+		if (len < 0 || len > sizeof(server_random)) {
+		    printf("Invalid server_random %d vs %d\n", len, (int)sizeof(server_random));
+		    err =1;
+		    break;
+		}
+		serverrandomlen = len;
+		PrintValue("server_random", server_random, len);
+		step++;
+            }
+	    break;
+
+	case 6: /* client_random = xxxx */
+	    fputs(ibuf, rfp);
+	    if (strncasecmp(ibuf, "client_random = ", 16) != 0) {
+		printf("Missing client_random\n");
+		err = 1;
+		break;
+	    }
+	    len = hex2bin((char*)ibuf+16, client_random);
+	    if (len < 0 || len > sizeof(client_random)) {
+		printf("Invalid client_random %d vs %d\n", len, (int)sizeof(client_random));
+		err =1;
+		break;
+	    }
+	    PrintValue("client_random", client_random, len);
+	    clientrandomlen = len;
+
+	    /* shit->hit(fan) */
+
+	    if ((tls != 10) && (tls != 12)) {
+		printf("bad tls version %d\n", tls);
+		err = 1;
+		break;
+	    }
+
+	    if (tls == 10)
+		digest_mask = TLS1_PRF;
+
+	    if (tls == 12) {
+		switch (shabits) {
+		case 1:	digest_mask = TLS1_PRF; break;
+		case 256:digest_mask = TLS1_PRF_SHA256; break;
+		case 384:digest_mask = TLS1_PRF_SHA384; break;
+		/*case 512:	digest_mask = TLS1_PRF_SHA512; break; not in openssl */
+		default: printf("bad shabits %d\n", shabits);
+			err=1;
+			break;
+		}
+	    }
+	    memcpy(seed, "master secret",strlen("master secret"));
+	    memcpy(seed+strlen("master secret"), clientHello_random, clienthellorandomlen);
+	    memcpy(seed+strlen("master secret")+clienthellorandomlen, serverHello_random, serverhellorandomlen);
+
+	    private_tls1_PRF(digest_mask,
+		    seed, strlen("master secret")+clienthellorandomlen+serverhellorandomlen,
+		    NULL,	0,
+		    NULL,	0,
+		    NULL, 	0,
+		    NULL,	0,
+		    premastersecret, premasterlength,
+		    mastersecret,tmpsecret,sizeof(tmpsecret));
+	    OutputValue("master_secret", mastersecret, premasterlength, rfp, 0);
+
+	    private_tls1_PRF(digest_mask,
+		    "key expansion", strlen("key expansion"),
+		    server_random, serverrandomlen,
+		    client_random, clientrandomlen,
+		    NULL, 0, NULL, 0,
+		    mastersecret, premasterlength,
+		    keyblock, keyblocktmp, keyblocklength
+	    );
+	    OutputValue("key_block", keyblock, keyblocklength, rfp, 0);
+
+	    step++;
+	    break;
+
+	case 7:
+	    if (ibuf[0] != '\n')
+		{
+		err = 1;
+		printf("Missing terminator\n");
+		}
+	    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 d_opt = 1;
+
+#ifdef OPENSSL_FIPS
+    if(!FIPS_mode_set(1))
+	{
+	do_print_errors();
+	EXIT(1);
+	}
+#endif
+    SSL_library_init();
+    if (argc > 1)
+	{
+	if (strcasecmp(argv[1], "-d") == 0)
+	    {
+	    d_opt = 1;
+	    }
+	else if (strcasecmp(argv[1], "-f") == 0)
+	    {
+	    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
+
Index: openssl-1.0.2j/crypto/fips/fips_utl.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ openssl-1.0.2j/crypto/fips/fips_utl.h	2017-03-16 17:27:29.544992910 +0100
@@ -0,0 +1,508 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    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 FIPS_UTL_H
+#define FIPS_UTL_H
+
+#define OPENSSL_FIPSAPI
+
+#include <openssl/fips_rand.h>
+#include <openssl/objects.h>
+
+#ifdef OPENSSL_SYS_WIN32
+#define RESP_EOL	"\n"
+#else
+#define RESP_EOL	"\r\n"
+#endif
+
+#ifndef FIPS_AUTH_OFFICER_PASS
+#define FIPS_AUTH_OFFICER_PASS	"Default FIPS Crypto Officer Password"
+#endif
+
+#ifndef FIPS_AUTH_USER_PASS
+#define FIPS_AUTH_USER_PASS	"Default FIPS Crypto User Password"
+#endif
+
+
+int hex2bin(const char *in, unsigned char *out);
+unsigned char *hex2bin_m(const char *in, long *plen);
+int do_hex2bn(BIGNUM **pr, const char *in);
+int do_bn_print(FILE *out, const BIGNUM *bn);
+int do_bn_print_name(FILE *out, const char *name, const BIGNUM *bn);
+int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf);
+int parse_line2(char **pkw, char **pval, char *linebuf, char *olinebuf, int eol);
+BIGNUM *hex2bn(const char *in);
+int tidy_line(char *linebuf, char *olinebuf);
+int copy_line(const char *in, FILE *ofp);
+int bint2bin(const char *in, int len, unsigned char *out);
+int bin2bint(const unsigned char *in,int len,char *out);
+void PrintValue(char *tag, unsigned char *val, int len);
+void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode);
+void fips_algtest_init(void);
+void do_entropy_stick(void);
+int fips_strncasecmp(const char *str1, const char *str2, size_t n);
+int fips_strcasecmp(const char *str1, const char *str2);
+
+static int no_err;
+
+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 : "");
+		}
+	}
+
+static void put_err_cb(int lib, int func,int reason,const char *file,int line)
+	{
+	if (no_err)
+		return;
+	fprintf(stderr, "ERROR:%08lX:lib=%d,func=%d,reason=%d"
+				":file=%s:line=%d\n",
+			ERR_PACK(lib, func, reason),
+			lib, func, reason, file, line);
+	}
+
+static void add_err_cb(int num, va_list args)
+	{
+	int i;
+	char *str;
+	if (no_err)
+		return;
+	fputs("\t", stderr);
+	for (i = 0; i < num; i++)
+		{
+		str = va_arg(args, char *);
+		if (str)
+			fputs(str, stderr);
+		}
+	fputs("\n", stderr);
+	}
+
+/* Dummy Entropy to keep DRBG happy. WARNING: THIS IS TOTALLY BOGUS
+ * HAS ZERO SECURITY AND MUST NOT BE USED IN REAL APPLICATIONS.
+ */
+
+static unsigned char dummy_entropy[1024];
+
+static size_t dummy_cb(DRBG_CTX *ctx, unsigned char **pout,
+                                int entropy, size_t min_len, size_t max_len)
+	{
+	*pout = dummy_entropy;
+	return min_len;
+	}
+
+static int entropy_stick = 0;
+
+static void fips_algtest_init_nofips(void)
+	{
+	DRBG_CTX *ctx;
+	size_t i;
+	FIPS_set_error_callbacks(put_err_cb, add_err_cb);
+	for (i = 0; i < sizeof(dummy_entropy); i++)
+		dummy_entropy[i] = i & 0xff;
+	if (entropy_stick)
+		memcpy(dummy_entropy + 32, dummy_entropy + 16, 16);
+	ctx = FIPS_get_default_drbg();
+	FIPS_drbg_init(ctx, NID_aes_256_ctr, DRBG_FLAG_CTR_USE_DF);
+	FIPS_drbg_set_callbacks(ctx, dummy_cb, 0, 16, dummy_cb, 0);
+	FIPS_drbg_instantiate(ctx, dummy_entropy, 10);
+	FIPS_rand_set_method(FIPS_drbg_method());
+	}
+
+void do_entropy_stick(void)
+	{
+	entropy_stick = 1;
+	}
+
+void fips_algtest_init(void)
+	{
+	fips_algtest_init_nofips();
+	if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+		{
+		fprintf(stderr, "Error entering FIPS mode\n");
+		exit(1);
+		}
+	}
+
+int hex2bin(const char *in, unsigned char *out)
+    {
+    int n1, n2, isodd = 0;
+    unsigned char ch;
+
+    n1 = strlen(in);
+    if (in[n1 - 1] == '\n')
+	n1--;
+
+    if (n1 & 1)
+	isodd = 1;
+
+    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;
+	    }
+	/* If input is odd length first digit is least significant: assumes
+	 * all digits valid hex and null terminated which is true for the
+	 * strings we pass.
+	 */
+	if (n1 == 1 && isodd)
+		{
+		out[n2++] = ch;
+		continue;
+		}
+	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;
+	if (strlen(in) == 0)
+		{
+		*plen = 0;
+		return OPENSSL_malloc(1);
+		}
+	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, const 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, const BIGNUM *bn)
+	{
+	int r;
+	fprintf(out, "%s = ", name);
+	r = do_bn_print(out, bn);
+	if (!r)
+		return 0;
+	fputs(RESP_EOL, out);
+	return 1;
+	}
+
+int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf)
+	{
+	return parse_line2(pkw, pval, linebuf, olinebuf, 1);
+	}
+
+int parse_line2(char **pkw, char **pval, char *linebuf, char *olinebuf, int eol)
+	{
+	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;
+
+	if (eol && *p != '\n')
+		fprintf(stderr, "Warning: missing EOL\n");
+
+	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;
+    }
+
+/* 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;
+	}
+/* Copy supplied line to ofp replacing \n with \r\n */
+int copy_line(const char *in, FILE *ofp)
+	{
+	const char *p;
+	p = strchr(in, '\n');
+	if (p)
+		{
+		fwrite(in, 1, (size_t)(p - in), ofp);
+		fputs(RESP_EOL, ofp);
+		}
+	else
+		fputs(in, ofp);
+	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)
+{
+#ifdef VERBOSE
+	OutputValue(tag, val, len, stdout, 0);
+#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);
+    	fprintf(rfp, "%s = %.*s" RESP_EOL, tag, olen, obuf);
+	}
+    else
+	{
+	int i;
+    	fprintf(rfp, "%s = ", tag);
+	for (i = 0; i < len; i++)
+		fprintf(rfp, "%02x", val[i]);
+	fputs(RESP_EOL, rfp);
+	}
+
+#if VERBOSE
+    printf("%s = %.*s\n", tag, olen, obuf);
+#endif
+    }
+
+/* Not all platforms support strcasecmp and strncasecmp: implement versions
+ * in here to avoid need to include them in the validated module. Taken
+ * from crypto/o_str.c written by Richard Levitte (richard@levitte.org)
+ */
+
+int fips_strncasecmp(const char *str1, const char *str2, size_t n)
+	{
+	while (*str1 && *str2 && n)
+		{
+		int res = toupper(*str1) - toupper(*str2);
+		if (res) return res < 0 ? -1 : 1;
+		str1++;
+		str2++;
+		n--;
+		}
+	if (n == 0)
+		return 0;
+	if (*str1)
+		return 1;
+	if (*str2)
+		return -1;
+	return 0;
+	}
+
+int fips_strcasecmp(const char *str1, const char *str2)
+	{
+	return fips_strncasecmp(str1, str2, (size_t)-1);
+	}
+
+
+#endif
Index: openssl-1.0.2j/crypto/evp/evp.h
===================================================================
--- openssl-1.0.2j.orig/crypto/evp/evp.h	2017-03-17 14:04:48.141719095 +0100
+++ openssl-1.0.2j/crypto/evp/evp.h	2017-03-17 14:04:58.921880654 +0100
@@ -516,6 +516,34 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER
 # define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
 # define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
 
+/* Macros to reduce FIPS dependencies: do NOT use in applications */
+#define M_EVP_MD_size(e)		((e)->md_size)
+#define M_EVP_MD_block_size(e)		((e)->block_size)
+#define M_EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
+#define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
+#define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
+#define M_EVP_MD_type(e)			((e)->type)
+#define M_EVP_MD_CTX_type(e)		M_EVP_MD_type(M_EVP_MD_CTX_md(e))
+#define M_EVP_MD_CTX_md(e)			((e)->digest)
+
+#define M_EVP_CIPHER_nid(e)		((e)->nid)
+#define M_EVP_CIPHER_CTX_iv_length(e)	((e)->cipher->iv_len)
+#define M_EVP_CIPHER_CTX_flags(e)	((e)->cipher->flags)
+#define M_EVP_CIPHER_CTX_block_size(e)	((e)->cipher->block_size)
+#define M_EVP_CIPHER_CTX_cipher(e)	((e)->cipher)
+#define M_EVP_CIPHER_CTX_mode(e)	(M_EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
+
+#define M_EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
+
+#define M_EVP_EncryptInit(ctx,ciph,key,iv) \
+	(EVP_CipherInit(ctx,ciph,key,iv,1))
+#define M_EVP_EncryptInit_ex(ctx,ciph,impl,key,iv) \
+	(EVP_CipherInit_ex(ctx,ciph,impl,key,iv,1))
+#define M_EVP_DecryptInit(ctx,ciph,key,iv) \
+	(EVP_CipherInit(ctx,ciph,key,iv,0))
+#define M_EVP_DecryptInit_ex(ctx,ciph,impl,key,iv) \
+	(EVP_CipherInit_ex(ctx,ciph,impl,key,iv,0))
+
 int EVP_MD_type(const EVP_MD *md);
 # define EVP_MD_nid(e)                   EVP_MD_type(e)
 # define EVP_MD_name(e)                  OBJ_nid2sn(EVP_MD_nid(e))
Index: openssl-1.0.2j/crypto/fips/fips_enc.c
===================================================================
--- openssl-1.0.2j.orig/crypto/fips/fips_enc.c	2017-03-17 14:06:50.387553609 +0100
+++ openssl-1.0.2j/crypto/fips/fips_enc.c	2017-03-17 14:07:01.947727357 +0100
@@ -62,6 +62,281 @@
 #include <openssl/err.h>
 #include <openssl/fips.h>
 
+void FIPS_cipher_ctx_init(EVP_CIPHER_CTX *ctx)
+	{
+	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
+	/* ctx->cipher=NULL; */
+	}
+
+EVP_CIPHER_CTX *FIPS_cipher_ctx_new(void)
+	{
+	EVP_CIPHER_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
+	if (ctx)
+		FIPS_cipher_ctx_init(ctx);
+	return ctx;
+	}
+
+/* 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, size_t 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,
+	1,
+	0,
+	0,
+	0,
+	bad_init,
+	bad_do_cipher,
+	NULL,
+	0,
+	bad_set_asn1,
+	bad_get_asn1,
+	bad_ctrl,
+	NULL
+	};
+
+int FIPS_cipherinit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+	     const unsigned char *key, const unsigned char *iv, int enc)
+	{
+	if(FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_CIPHERINIT,FIPS_R_FIPS_SELFTEST_FAILED);
+		ctx->cipher = &bad_cipher;
+		return 0;
+		}
+	if (enc == -1)
+		enc = ctx->encrypt;
+	else
+		{
+		if (enc)
+			enc = 1;
+		ctx->encrypt = enc;
+		}
+	if (cipher)
+		{
+		/* Only FIPS ciphers allowed */
+		if (FIPS_module_mode() && !(cipher->flags & EVP_CIPH_FLAG_FIPS) &&
+			!(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
+			{
+			EVPerr(EVP_F_FIPS_CIPHERINIT, EVP_R_DISABLED_FOR_FIPS);
+			ctx->cipher = &bad_cipher;
+			return 0;
+			}
+		/* Ensure a context left lying around from last time is cleared
+		 * (the previous check attempted to avoid this if the same
+		 * ENGINE and EVP_CIPHER could be used). */
+		FIPS_cipher_ctx_cleanup(ctx);
+
+		/* Restore encrypt field: it is zeroed by cleanup */
+		ctx->encrypt = enc;
+
+		ctx->cipher=cipher;
+		if (ctx->cipher->ctx_size)
+			{
+			ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
+			if (!ctx->cipher_data)
+				{
+				EVPerr(EVP_F_FIPS_CIPHERINIT, ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			}
+		else
+			{
+			ctx->cipher_data = NULL;
+			}
+		ctx->key_len = cipher->key_len;
+		ctx->flags = 0;
+		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
+			{
+			if(!FIPS_cipher_ctx_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
+				{
+				EVPerr(EVP_F_FIPS_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			}
+		}
+	else if(!ctx->cipher)
+		{
+		EVPerr(EVP_F_FIPS_CIPHERINIT, EVP_R_NO_CIPHER_SET);
+		return 0;
+		}
+	/* we assume block size is a power of 2 in *cryptUpdate */
+	OPENSSL_assert(ctx->cipher->block_size == 1
+	    || ctx->cipher->block_size == 8
+	    || ctx->cipher->block_size == 16);
+
+	if(!(M_EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
+		switch(M_EVP_CIPHER_CTX_mode(ctx)) {
+
+			case EVP_CIPH_STREAM_CIPHER:
+			case EVP_CIPH_ECB_MODE:
+			break;
+
+			case EVP_CIPH_CFB_MODE:
+			case EVP_CIPH_OFB_MODE:
+
+			ctx->num = 0;
+			/* fall-through */
+
+			case EVP_CIPH_CBC_MODE:
+
+			OPENSSL_assert(M_EVP_CIPHER_CTX_iv_length(ctx) <=
+					(int)sizeof(ctx->iv));
+			if(iv) memcpy(ctx->oiv, iv, M_EVP_CIPHER_CTX_iv_length(ctx));
+			memcpy(ctx->iv, ctx->oiv, M_EVP_CIPHER_CTX_iv_length(ctx));
+			break;
+
+			case EVP_CIPH_CTR_MODE:
+			/* Don't reuse IV for CTR mode */
+			if(iv)
+				memcpy(ctx->iv, iv, M_EVP_CIPHER_CTX_iv_length(ctx));
+			break;
+
+			default:
+			return 0;
+			break;
+		}
+	}
+
+	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
+		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
+	}
+	ctx->buf_len=0;
+	ctx->final_used=0;
+	ctx->block_mask=ctx->cipher->block_size-1;
+	return 1;
+	}
+
+void FIPS_cipher_ctx_free(EVP_CIPHER_CTX *ctx)
+	{
+	if (ctx)
+		{
+		FIPS_cipher_ctx_cleanup(ctx);
+		OPENSSL_free(ctx);
+		}
+	}
+
+int FIPS_cipher_ctx_cleanup(EVP_CIPHER_CTX *c)
+	{
+	if (c->cipher != NULL)
+		{
+		if(c->cipher->cleanup && !c->cipher->cleanup(c))
+			return 0;
+		/* Cleanse cipher context data */
+		if (c->cipher_data)
+			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+		}
+	if (c->cipher_data)
+		OPENSSL_free(c->cipher_data);
+	memset(c,0,sizeof(EVP_CIPHER_CTX));
+	return 1;
+	}
+
+int FIPS_cipher_ctx_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+	int ret;
+	if (FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_CIPHER_CTX_CTRL, FIPS_R_SELFTEST_FAILED);
+		return 0;
+		}
+	if(!ctx->cipher) {
+		EVPerr(EVP_F_FIPS_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+		return 0;
+	}
+
+	if(!ctx->cipher->ctrl) {
+		EVPerr(EVP_F_FIPS_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+		return 0;
+	}
+
+	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+	if(ret == -1) {
+		EVPerr(EVP_F_FIPS_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+		return 0;
+	}
+	return ret;
+}
+
+int FIPS_cipher_ctx_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
+	{
+	if ((in == NULL) || (in->cipher == NULL))
+		{
+		EVPerr(EVP_F_FIPS_CIPHER_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
+		return 0;
+		}
+
+	/* Only FIPS ciphers allowed */
+	if (FIPS_module_mode() && !(in->cipher->flags & EVP_CIPH_FLAG_FIPS) &&
+		!(out->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
+		{
+		EVPerr(EVP_F_FIPS_CIPHER_CTX_COPY, EVP_R_DISABLED_FOR_FIPS);
+		out->cipher = &bad_cipher;
+		return 0;
+		}
+
+	FIPS_cipher_ctx_cleanup(out);
+	memcpy(out,in,sizeof *out);
+
+	if (in->cipher_data && in->cipher->ctx_size)
+		{
+		out->cipher_data=OPENSSL_malloc(in->cipher->ctx_size);
+		if (!out->cipher_data)
+			{
+			EVPerr(EVP_F_FIPS_CIPHER_CTX_COPY,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		memcpy(out->cipher_data,in->cipher_data,in->cipher->ctx_size);
+		}
+
+	if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
+		return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
+	return 1;
+	}
+
+/* You can't really set the key length with FIPS, so just check that the
+   caller sets the length the context already has. */
+int FIPS_cipher_ctx_set_key_length(EVP_CIPHER_CTX *ctx, int keylen)
+	{
+	if (ctx->key_len == keylen)
+		return 1;
+
+	EVPerr(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH,EVP_R_INVALID_KEY_LENGTH);
+	return 0;
+	}
+
+
+
+int FIPS_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			const unsigned char *in, unsigned int inl)
+	{
+	if (FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_CIPHER, FIPS_R_SELFTEST_FAILED);
+		return -1;
+		}
+	return ctx->cipher->do_cipher(ctx,out,in,inl);
+	}
+
 const EVP_CIPHER *FIPS_get_cipherbynid(int nid)
 {
     switch (nid) {
Index: openssl-1.0.2j/crypto/fips/fips_md.c
===================================================================
--- openssl-1.0.2j.orig/crypto/fips/fips_md.c	2017-03-16 17:27:29.252988353 +0100
+++ openssl-1.0.2j/crypto/fips/fips_md.c	2017-03-17 14:11:22.255650535 +0100
@@ -120,6 +120,208 @@
 #include <openssl/err.h>
 #include <openssl/fips.h>
 
+void FIPS_md_ctx_init(EVP_MD_CTX *ctx)
+	{
+	memset(ctx,'\0',sizeof *ctx);
+	}
+
+EVP_MD_CTX *FIPS_md_ctx_create(void)
+	{
+	EVP_MD_CTX *ctx=OPENSSL_malloc(sizeof *ctx);
+
+	if (ctx)
+		FIPS_md_ctx_init(ctx);
+
+	return ctx;
+	}
+
+/* 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},
+	};
+
+int FIPS_digestinit(EVP_MD_CTX *ctx, const EVP_MD *type)
+	{
+	M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+	if(FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_DIGESTINIT,FIPS_R_FIPS_SELFTEST_FAILED);
+		ctx->digest = &bad_md;
+		ctx->update = bad_update;
+		return 0;
+		}
+	if(FIPS_module_mode() && !(type->flags & EVP_MD_FLAG_FIPS) &&
+		!(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))
+		{
+		EVPerr(EVP_F_FIPS_DIGESTINIT, EVP_R_DISABLED_FOR_FIPS);
+		ctx->digest = &bad_md;
+		ctx->update = bad_update;
+		return 0;
+		}
+	if (ctx->digest != type)
+		{
+		if (ctx->digest && ctx->digest->ctx_size)
+			OPENSSL_free(ctx->md_data);
+		ctx->digest=type;
+		if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size)
+			{
+			ctx->update = type->update;
+			ctx->md_data=OPENSSL_malloc(type->ctx_size);
+			if (ctx->md_data == NULL)
+				{
+				EVPerr(EVP_F_FIPS_DIGESTINIT,
+							ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			}
+		}
+	if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
+		return 1;
+	return ctx->digest->init(ctx);
+	}
+
+int FIPS_digestupdate(EVP_MD_CTX *ctx, const void *data, size_t count)
+	{
+	if (FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_DIGESTUPDATE, FIPS_R_SELFTEST_FAILED);
+		return 0;
+		}
+	return ctx->update(ctx,data,count);
+	}
+
+/* The caller can assume that this removes any secret data from the context */
+int FIPS_digestfinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+	{
+	int ret;
+
+	if (FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_FIPS_DIGESTFINAL, FIPS_R_SELFTEST_FAILED);
+		return 0;
+		}
+
+	OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
+	ret=ctx->digest->final(ctx,md);
+	if (size != NULL)
+		*size=ctx->digest->md_size;
+	if (ctx->digest->cleanup)
+		{
+		ctx->digest->cleanup(ctx);
+		M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+		}
+	memset(ctx->md_data,0,ctx->digest->ctx_size);
+	return ret;
+	}
+
+int FIPS_digest(const void *data, size_t count,
+		unsigned char *md, unsigned int *size, const EVP_MD *type)
+	{
+	EVP_MD_CTX ctx;
+	int ret;
+
+	FIPS_md_ctx_init(&ctx);
+	M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
+	ret=FIPS_digestinit(&ctx, type)
+	  && FIPS_digestupdate(&ctx, data, count)
+	  && FIPS_digestfinal(&ctx, md, size);
+	FIPS_md_ctx_cleanup(&ctx);
+
+	return ret;
+	}
+
+void FIPS_md_ctx_destroy(EVP_MD_CTX *ctx)
+	{
+	FIPS_md_ctx_cleanup(ctx);
+	OPENSSL_free(ctx);
+	}
+
+/* This call frees resources associated with the context */
+int FIPS_md_ctx_cleanup(EVP_MD_CTX *ctx)
+	{
+	/* Don't assume ctx->md_data was cleaned in FIPS_digest_Final,
+	 * because sometimes only copies of the context are ever finalised.
+	 */
+	if (ctx->digest && ctx->digest->cleanup
+	    && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
+		ctx->digest->cleanup(ctx);
+	if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
+	    && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
+		{
+		OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
+		OPENSSL_free(ctx->md_data);
+		}
+	memset(ctx,'\0',sizeof *ctx);
+
+	return 1;
+	}
+
+int FIPS_md_ctx_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+	{
+	unsigned char *tmp_buf;
+	if ((in == NULL) || (in->digest == NULL))
+		{
+		EVPerr(EVP_F_FIPS_MD_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED);
+		return 0;
+		}
+
+	if (out->digest == in->digest)
+		{
+		tmp_buf = out->md_data;
+	    	M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
+		}
+	else tmp_buf = NULL;
+	FIPS_md_ctx_cleanup(out);
+	memcpy(out,in,sizeof *out);
+
+	if (in->md_data && out->digest->ctx_size)
+		{
+		if (tmp_buf)
+			out->md_data = tmp_buf;
+		else
+			{
+			out->md_data=OPENSSL_malloc(out->digest->ctx_size);
+			if (!out->md_data)
+				{
+				EVPerr(EVP_F_FIPS_MD_CTX_COPY,ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			}
+		memcpy(out->md_data,in->md_data,out->digest->ctx_size);
+		}
+
+	out->update = in->update;
+
+	if (out->digest->copy)
+		return out->digest->copy(out,in);
+	
+	return 1;
+	}
+
 const EVP_MD *FIPS_get_digestbynid(int nid)
 {
     switch (nid) {
Index: openssl-1.0.2j/crypto/ecdsa/ecs_ossl.c
===================================================================
--- openssl-1.0.2j.orig/crypto/ecdsa/ecs_ossl.c	2017-03-16 17:27:29.272988665 +0100
+++ openssl-1.0.2j/crypto/ecdsa/ecs_ossl.c	2017-03-17 14:24:11.315328893 +0100
@@ -479,3 +479,31 @@ static int ecdsa_do_verify(const unsigne
         EC_POINT_free(point);
     return ret;
 }
+
+/* FIPS stanadlone version of ecdsa_check: just return FIPS method */
+ECDSA_DATA *fips_ecdsa_check(EC_KEY *key)
+	{
+	static ECDSA_DATA rv = {
+		0,0,0,
+		&openssl_ecdsa_meth
+		};
+	return &rv;
+	}
+
+/* Standalone digest sign and verify */
+int FIPS_ecdsa_verify_digest(EC_KEY *key,
+			const unsigned char *dig, int dlen, ECDSA_SIG *s)
+	{
+	ECDSA_DATA *ecdsa = ecdsa_check(key);
+	if (ecdsa == NULL)
+		return 0;
+	return ecdsa->meth->ecdsa_do_verify(dig, dlen, s, key);
+	}
+ECDSA_SIG * FIPS_ecdsa_sign_digest(EC_KEY *key,
+					const unsigned char *dig, int dlen)
+	{
+	ECDSA_DATA *ecdsa = ecdsa_check(key);
+	if (ecdsa == NULL)
+		return NULL;
+	return ecdsa->meth->ecdsa_do_sign(dig, dlen, NULL, NULL, key);
+	}
Index: openssl-1.0.2j/crypto/ecdsa/ecdsa.h
===================================================================
--- openssl-1.0.2j.orig/crypto/ecdsa/ecdsa.h	2016-09-26 11:49:07.000000000 +0200
+++ openssl-1.0.2j/crypto/ecdsa/ecdsa.h	2017-03-17 14:35:10.121322408 +0100
@@ -228,6 +228,21 @@ int ECDSA_get_ex_new_index(long argl, vo
 int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
 void *ECDSA_get_ex_data(EC_KEY *d, int idx);
 
+#ifdef OPENSSL_FIPS
+/* Standalone FIPS signature operations */
+ECDSA_SIG * FIPS_ecdsa_sign_digest(EC_KEY *key,
+					const unsigned char *dig, int dlen);
+ECDSA_SIG * FIPS_ecdsa_sign_ctx(EC_KEY *key, EVP_MD_CTX *ctx);
+int FIPS_ecdsa_verify_digest(EC_KEY *key,
+			const unsigned char *dig, int dlen, ECDSA_SIG *s);
+int FIPS_ecdsa_verify_ctx(EC_KEY *key, EVP_MD_CTX *ctx, ECDSA_SIG *s);
+int FIPS_ecdsa_verify(EC_KEY *key, const unsigned char *msg, size_t msglen,
+			const EVP_MD *mhash, ECDSA_SIG *s);
+ECDSA_SIG * FIPS_ecdsa_sign(EC_KEY *key,
+			const unsigned char *msg, size_t msglen,
+			const EVP_MD *mhash);
+#endif
+
 /** Allocates and initialize a ECDSA_METHOD structure
  *  \param ecdsa_method pointer to ECDSA_METHOD to copy.  (May be NULL)
  *  \return pointer to a ECDSA_METHOD structure or NULL if an error occurred