From: Dr. Stephen Henson Date: Tue, 16 Sep 2008 10:12:23 +0000 (+0000) Subject: Merge fips directory from FIPS branch. X-Git-Tag: OpenSSL_0_9_8j~115 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=59f3477b8236fd431d2cee942b46e3034e0a7b10;p=oweals%2Fopenssl.git Merge fips directory from FIPS branch. --- diff --git a/fips/.cvsignore b/fips/.cvsignore new file mode 100644 index 0000000000..34f2408d13 --- /dev/null +++ b/fips/.cvsignore @@ -0,0 +1,8 @@ +lib +Makefile.save +fips_test_suite +fips_premain_dso +fips_test_suite.sha1 +fipscanister.o.sha1 +*.flc +semantic.cache diff --git a/fips/Makefile b/fips/Makefile new file mode 100644 index 0000000000..04b1fb08ae --- /dev/null +++ b/fips/Makefile @@ -0,0 +1,219 @@ +# +# OpenSSL/crypto/Makefile +# + +DIR= fips +TOP= .. +CC= cc +INCLUDE= -I. -I$(TOP) -I../include +# INCLUDES targets sudbirs! +INCLUDES= -I.. -I../.. -I../../include +CFLAG= -g +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +RM= rm -f +AR= ar r +ARD= ar d +TEST= fips_test_suite.c +FIPS_TVDIR= testvectors +FIPS_TVOK= $$HOME/fips/tv.ok + +FIPSCANLOC= $(FIPSLIBDIR)fipscanister.o + +RECURSIVE_MAKE= [ -n "$(FDIRS)" ] && for i in $(FDIRS) ; do \ + (cd $$i && echo "making $$target in $(DIR)/$$i..." && \ + $(MAKE) -e TOP=../.. DIR=$$i INCLUDES='${INCLUDES}' $$target ) || exit 1; \ + done; + +PEX_LIBS= +EX_LIBS= + +CFLAGS= $(INCLUDE) $(CFLAG) -DHMAC_EXT=\"$${HMAC_EXT:-sha1}\" +ASFLAGS= $(INCLUDE) $(ASFLAG) +AFLAGS=$(ASFLAGS) + +LIBS= + +FDIRS=sha rand des aes dsa rsa dh hmac + +GENERAL=Makefile README fips-lib.com install.com + +LIB= $(TOP)/libcrypto.a +SHARED_LIB= $(FIPSCANLIB)$(SHLIB_EXT) +LIBSRC=fips.c +LIBOBJ=fips.o + +FIPS_OBJ_LISTS=sha/lib hmac/lib rand/lib des/lib aes/lib dsa/lib rsa/lib dh/lib + +SRC= $(LIBSRC) + +EXHEADER=fips.h +HEADER=$(EXHEADER) fips_utl.h fips_locl.h +EXE=fipsld + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + @(cd ..; $(MAKE) DIRS=$(DIR) all) + +testapps: + @if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi + +all: + @if [ -z "$(FIPSLIBDIR)" ]; then \ + $(MAKE) -e subdirs lib fips_premain_dso$(EXE_EXT); \ + else \ + $(MAKE) -e lib fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT); \ + fi + +# Idea behind fipscanister.o is to "seize" the sequestered code between +# known symbols for fingerprinting purposes, which would be commonly +# done with ld -r start.o ... end.o. The latter however presents a minor +# challenge on multi-ABI platforms. As just implied, we'd rather use ld, +# but the trouble is that we don't generally know how ABI-selection +# compiler flag is translated to corresponding linker flag. All compiler +# drivers seem to recognize -r flag and pass it down to linker, but some +# of them, including gcc, erroneously add -lc, as well as run-time +# components, such as crt1.o and alike. Fortunately among those vendor +# compilers which were observed to misinterpret -r flag multi-ABI ones +# are equipped with smart linkers, which don't require any ABI-selection +# flag and simply assume that all objects are of the same type as first +# one in command line. So the idea is to identify gcc and deficient +# vendor compiler drivers... + +fipscanister.o: fips_start.o $(LIBOBJ) $(FIPS_OBJ_LISTS) fips_end.o + FIPS_ASM=""; \ + list="$(BN_ASM)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/bn/$$i" ; done; \ + list="$(AES_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/aes/$$i" ; done; \ + list="$(DES_ENC)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/des/$$i" ; done; \ + list="$(SHA1_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/sha/$$i" ; done; \ + if [ -n "$(CPUID_OBJ)" ]; then \ + CPUID=../crypto/$(CPUID_OBJ) ; \ + else \ + CPUID="" ; \ + fi ; \ + objs="fips_start.o $(LIBOBJ) $(FIPS_EX_OBJ) $$CPUID $$FIPS_ASM"; \ + for i in $(FIPS_OBJ_LISTS); do \ + dir=`dirname $$i`; script="s|^|$$dir/|;s| | $$dir/|g"; \ + objs="$$objs `sed "$$script" $$i`"; \ + done; \ + objs="$$objs fips_end.o" ; \ + os="`(uname -s) 2>/dev/null`"; cflags="$(CFLAGS)"; \ + [ "$$os" = "AIX" ] && cflags="$$cflags -Wl,-bnoobjreorder"; \ + if [ -n "${FIPS_SITE_LD}" ]; then \ + set -x; ${FIPS_SITE_LD} -r -o $@ $$objs; \ + elif $(CC) -dumpversion >/dev/null 2>&1; then \ + set -x; $(CC) $$cflags -r -nostdlib -o $@ $$objs ; \ + else case "$$os" in \ + HP-UX|OSF1|SunOS) set -x; /usr/ccs/bin/ld -r -o $@ $$objs ;; \ + *) set -x; $(CC) $$cflags -r -o $@ $$objs ;; \ + esac fi + ./fips_standalone_sha1 fipscanister.o > fipscanister.o.sha1 + +# If another exception is immediately required, assign approprite +# site-specific ld command to FIPS_SITE_LD environment variable. + +fips_start.o: fips_canister.c + $(CC) $(CFLAGS) -DFIPS_START -c -o $@ fips_canister.c +fips_end.o: fips_canister.c + $(CC) $(CFLAGS) -DFIPS_END -c -o $@ fips_canister.c +fips_premain_dso$(EXE_EXT): fips_premain.c + $(CC) $(CFLAGS) -DFINGERPRINT_PREMAIN_DSO_LOAD -o $@ fips_premain.c \ + $(FIPSLIBDIR)fipscanister.o ../libcrypto.a $(EX_LIBS) +# this is executed only when linking with external fipscanister.o +fips_standalone_sha1$(EXE_EXT): sha/fips_standalone_sha1.c + $(CC) $(CFLAGS) -DFIPSCANISTER_O -o $@ sha/fips_standalone_sha1.c $(FIPSLIBDIR)fipscanister.o + +subdirs: + @target=all; $(RECURSIVE_MAKE) + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + @target=files; $(RECURSIVE_MAKE) + +links: + @$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../test $(TEST) + @target=links; $(RECURSIVE_MAKE) + +# lib: and $(LIB): are splitted to avoid end-less loop +lib: $(LIB) + if [ "$(FIPSCANISTERINTERNAL)" = "n" -a -n "$(FIPSCANLOC)"]; then $(AR) ../$(FIPSCANLIB).a $(FIPSCANLOC); fi + @touch lib + +$(LIB): $(FIPSLIBDIR)fipscanister.o + $(AR) $(LIB) $(FIPSLIBDIR)fipscanister.o + $(RANLIB) $(LIB) || echo Never mind. + +$(FIPSCANLIB): $(FIPSCANLOC) + $(AR) ../$(FIPSCANLIB).a $(FIPSCANLOC) + if [ "$(FIPSCANLIB)" = "libfips" ]; then \ + $(AR) $(LIB) $(FIPSCANLOC) ; \ + $(RANLIB) $(LIB) || echo Never Mind. ; \ + fi + $(RANLIB) ../$(FIPSCANLIB).a || echo Never mind. + @touch lib + +shared: lib subdirs fips_premain_dso$(EXE_EXT) + +libs: + @target=lib; $(RECURSIVE_MAKE) + +fips_test: top + @target=fips_test; $(RECURSIVE_MAKE) + +fips_test_diff: + @if diff -b -B -I '^\#' -cr -X fips-nodiff.txt $(FIPS_TVDIR) $(FIPS_TVOK) ; then \ + echo "FIPS diff OK" ; \ + else \ + echo "***FIPS DIFF ERROR***" ; exit 1 ; \ + fi + + +install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + @headerlist="$(EXHEADER)"; for i in $$headerlist ;\ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + @target=install; $(RECURSIVE_MAKE) + @cp -p -f fipscanister.o fipscanister.o.sha1 fips_premain.c \ + fips_premain.c.sha1 \ + $(INSTALL_PREFIX)$(INSTALLTOP)/lib/; \ + chmod 0444 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/fips* + +lint: + @target=lint; $(RECURSIVE_MAKE) + +depend: + @[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDE) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + @[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) ) + @if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi + +clean: + rm -f fipscanister.o.sha1 fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT) \ + *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + @target=clean; $(RECURSIVE_MAKE) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + @target=dclean; $(RECURSIVE_MAKE) + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips.o: ../include/openssl/asn1.h ../include/openssl/bio.h +fips.o: ../include/openssl/crypto.h ../include/openssl/des.h +fips.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h +fips.o: ../include/openssl/err.h ../include/openssl/evp.h +fips.o: ../include/openssl/fips.h ../include/openssl/fips_rand.h +fips.o: ../include/openssl/hmac.h ../include/openssl/lhash.h +fips.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h +fips.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h +fips.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h +fips.o: ../include/openssl/rsa.h ../include/openssl/safestack.h +fips.o: ../include/openssl/stack.h ../include/openssl/symhacks.h +fips.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h fips.c +fips.o: fips_locl.h diff --git a/fips/aes/.cvsignore b/fips/aes/.cvsignore new file mode 100644 index 0000000000..439e6d3eb6 --- /dev/null +++ b/fips/aes/.cvsignore @@ -0,0 +1,4 @@ +lib +Makefile.save +*.flc +semantic.cache diff --git a/fips/aes/Makefile b/fips/aes/Makefile new file mode 100644 index 0000000000..dff1b97efa --- /dev/null +++ b/fips/aes/Makefile @@ -0,0 +1,112 @@ +# +# OpenSSL/fips/aes/Makefile +# + +DIR= aes +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +ASFLAGS= $(INCLUDES) $(ASFLAG) +AFLAGS= $(ASFLAGS) + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=fips_aesavs.c +TESTDATA=fips_aes_data +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_aes_selftest.c +LIBOBJ=fips_aes_selftest.o + +SRC= $(LIBSRC) + +EXHEADER= +HEADER= + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TESTDATA) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +fips_test: + -find ../testvectors/aes/req -name '*.req' > testlist + -rm -rf ../testvectors/aes/rsp + mkdir ../testvectors/aes/rsp + if [ -s testlist ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_aesavs -d testlist; fi + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) \ + $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff testlist +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_aes_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_aes_selftest.o: ../../include/openssl/crypto.h +fips_aes_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_aes_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_aes_selftest.o: ../../include/openssl/lhash.h +fips_aes_selftest.o: ../../include/openssl/obj_mac.h +fips_aes_selftest.o: ../../include/openssl/objects.h +fips_aes_selftest.o: ../../include/openssl/opensslconf.h +fips_aes_selftest.o: ../../include/openssl/opensslv.h +fips_aes_selftest.o: ../../include/openssl/ossl_typ.h +fips_aes_selftest.o: ../../include/openssl/safestack.h +fips_aes_selftest.o: ../../include/openssl/stack.h +fips_aes_selftest.o: ../../include/openssl/symhacks.h fips_aes_selftest.c +fips_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/crypto.h ../../include/openssl/e_os2.h +fips_aesavs.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_aesavs.o: ../../include/openssl/fips.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 diff --git a/fips/aes/fips_aes_selftest.c b/fips/aes/fips_aes_selftest.c new file mode 100644 index 0000000000..441bbc18e7 --- /dev/null +++ b/fips/aes/fips_aes_selftest.c @@ -0,0 +1,101 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS +static struct + { + unsigned char key[16]; + unsigned char plaintext[16]; + unsigned char ciphertext[16]; + } tests[]= + { + { + { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, + { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, + 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }, + { 0x69,0xC4,0xE0,0xD8,0x6A,0x7B,0x04,0x30, + 0xD8,0xCD,0xB7,0x80,0x70,0xB4,0xC5,0x5A }, + }, + }; + +void FIPS_corrupt_aes() + { + tests[0].key[0]++; + } + +int FIPS_selftest_aes() + { + int n; + int ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + for(n=0 ; n < 1 ; ++n) + { + if (fips_cipher_test(&ctx, EVP_aes_128_ecb(), + tests[n].key, NULL, + tests[n].plaintext, + tests[n].ciphertext, + 16) <= 0) + goto err; + } + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED); + return ret; + } +#endif diff --git a/fips/aes/fips_aesavs.c b/fips/aes/fips_aesavs.c new file mode 100644 index 0000000000..ff7478044a --- /dev/null +++ b/fips/aes/fips_aesavs.c @@ -0,0 +1,938 @@ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/*--------------------------------------------- + NIST AES Algorithm Validation Suite + Test Program + + Donated to OpenSSL by: + V-ONE Corporation + 20250 Century Blvd, Suite 300 + Germantown, MD 20874 + U.S.A. + ----------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "e_os.h" + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS AES support\n"); + return(0); +} + +#else + +#include +#include "fips_utl.h" + +#define AES_BLOCK_SIZE 16 + +#define VERBOSE 0 + +/*-----------------------------------------------*/ + +int AESTest(EVP_CIPHER_CTX *ctx, + char *amode, int akeysz, unsigned char *aKey, + unsigned char *iVec, + int dir, /* 0 = decrypt, 1 = encrypt */ + unsigned char *plaintext, unsigned char *ciphertext, int len) + { + const EVP_CIPHER *cipher = NULL; + + if (strcasecmp(amode, "CBC") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cbc(); + break; + + case 192: + cipher = EVP_aes_192_cbc(); + break; + + case 256: + cipher = EVP_aes_256_cbc(); + break; + } + + } + else if (strcasecmp(amode, "ECB") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_ecb(); + break; + + case 192: + cipher = EVP_aes_192_ecb(); + break; + + case 256: + cipher = EVP_aes_256_ecb(); + break; + } + } + else if (strcasecmp(amode, "CFB128") == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb128(); + break; + + case 192: + cipher = EVP_aes_192_cfb128(); + break; + + case 256: + cipher = EVP_aes_256_cfb128(); + break; + } + + } + else if (strncasecmp(amode, "OFB", 3) == 0) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_ofb(); + break; + + case 192: + cipher = EVP_aes_192_ofb(); + break; + + case 256: + cipher = EVP_aes_256_ofb(); + break; + } + } + else if(!strcasecmp(amode,"CFB1")) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb1(); + break; + + case 192: + cipher = EVP_aes_192_cfb1(); + break; + + case 256: + cipher = EVP_aes_256_cfb1(); + break; + } + } + else if(!strcasecmp(amode,"CFB8")) + { + switch (akeysz) + { + case 128: + cipher = EVP_aes_128_cfb8(); + break; + + case 192: + cipher = EVP_aes_192_cfb8(); + break; + + case 256: + cipher = EVP_aes_256_cfb8(); + break; + } + } + else + { + printf("Unknown mode: %s\n", amode); + return 0; + } + if (!cipher) + { + printf("Invalid key size: %d\n", akeysz); + return 0; + } + if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) + return 0; + if(!strcasecmp(amode,"CFB1")) + M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); + if (dir) + EVP_Cipher(ctx, ciphertext, plaintext, len); + else + EVP_Cipher(ctx, plaintext, ciphertext, len); + return 1; + } + +/*-----------------------------------------------*/ +char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; +char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"}; +enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128}; +enum XCrypt {XDECRYPT, XENCRYPT}; + +/*=============================*/ +/* Monte Carlo Tests */ +/*-----------------------------*/ + +/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/ +/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/ + +#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1) +#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8))) + +int do_mct(char *amode, + int akeysz, unsigned char *aKey,unsigned char *iVec, + int dir, unsigned char *text, int len, + FILE *rfp) + { + int ret = 0; + unsigned char key[101][32]; + unsigned char iv[101][AES_BLOCK_SIZE]; + unsigned char ptext[1001][32]; + unsigned char ctext[1001][32]; + unsigned char ciphertext[64+4]; + int i, j, n, n1, n2; + int imode = 0, nkeysz = akeysz/8; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (len > 32) + { + printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n", + amode, akeysz); + return -1; + } + for (imode = 0; imode < 6; ++imode) + if (strcmp(amode, t_mode[imode]) == 0) + break; + if (imode == 6) + { + printf("Unrecognized mode: %s\n", amode); + return -1; + } + + memcpy(key[0], aKey, nkeysz); + if (iVec) + memcpy(iv[0], iVec, AES_BLOCK_SIZE); + if (dir == XENCRYPT) + memcpy(ptext[0], text, len); + else + memcpy(ctext[0], text, len); + for (i = 0; i < 100; ++i) + { + /* printf("Iteration %d\n", i); */ + if (i > 0) + { + fprintf(rfp,"COUNT = %d\n",i); + OutputValue("KEY",key[i],nkeysz,rfp,0); + if (imode != ECB) /* ECB */ + OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0); + /* Output Ciphertext | Plaintext */ + OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp, + imode == CFB1); + } + for (j = 0; j < 1000; ++j) + { + switch (imode) + { + case ECB: + if (j == 0) + { /* set up encryption */ + ret = AESTest(&ctx, amode, akeysz, key[i], NULL, + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + if (dir == XENCRYPT) + memcpy(ptext[j+1], ctext[j], len); + else + memcpy(ctext[j+1], ptext[j], len); + } + else + { + if (dir == XENCRYPT) + { + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + memcpy(ptext[j+1], ctext[j], len); + } + else + { + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + memcpy(ctext[j+1], ptext[j], len); + } + } + break; + + case CBC: + case OFB: + case CFB128: + if (j == 0) + { + ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + if (dir == XENCRYPT) + memcpy(ptext[j+1], iv[i], len); + else + memcpy(ctext[j+1], iv[i], len); + } + else + { + if (dir == XENCRYPT) + { + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + memcpy(ptext[j+1], ctext[j-1], len); + } + else + { + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + memcpy(ctext[j+1], ptext[j-1], len); + } + } + break; + + case CFB8: + if (j == 0) + { + ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], + dir, /* 0 = decrypt, 1 = encrypt */ + ptext[j], ctext[j], len); + } + else + { + if (dir == XENCRYPT) + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + else + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + } + if (dir == XENCRYPT) + { + if (j < 16) + memcpy(ptext[j+1], &iv[i][j], len); + else + memcpy(ptext[j+1], ctext[j-16], len); + } + else + { + if (j < 16) + memcpy(ctext[j+1], &iv[i][j], len); + else + memcpy(ctext[j+1], ptext[j-16], len); + } + break; + + case CFB1: + if(j == 0) + { +#if 0 + /* compensate for wrong endianness of input file */ + if(i == 0) + ptext[0][0]<<=7; +#endif + ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir, + ptext[j], ctext[j], len); + } + else + { + if (dir == XENCRYPT) + EVP_Cipher(&ctx, ctext[j], ptext[j], len); + else + EVP_Cipher(&ctx, ptext[j], ctext[j], len); + + } + if(dir == XENCRYPT) + { + if(j < 128) + sb(ptext[j+1],0,gb(iv[i],j)); + else + sb(ptext[j+1],0,gb(ctext[j-128],0)); + } + else + { + if(j < 128) + sb(ctext[j+1],0,gb(iv[i],j)); + else + sb(ctext[j+1],0,gb(ptext[j-128],0)); + } + break; + } + } + --j; /* reset to last of range */ + /* Output Ciphertext | Plaintext */ + OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp, + imode == CFB1); + fprintf(rfp, "\n"); /* add separator */ + + /* Compute next KEY */ + if (dir == XENCRYPT) + { + if (imode == CFB8) + { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ + for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) + ciphertext[n1] = ctext[j-n2][0]; + } + else if(imode == CFB1) + { + for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) + sb(ciphertext,n1,gb(ctext[j-n2],0)); + } + else + switch (akeysz) + { + case 128: + memcpy(ciphertext, ctext[j], 16); + break; + case 192: + memcpy(ciphertext, ctext[j-1]+8, 8); + memcpy(ciphertext+8, ctext[j], 16); + break; + case 256: + memcpy(ciphertext, ctext[j-1], 16); + memcpy(ciphertext+16, ctext[j], 16); + break; + } + } + else + { + if (imode == CFB8) + { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ + for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) + ciphertext[n1] = ptext[j-n2][0]; + } + else if(imode == CFB1) + { + for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) + sb(ciphertext,n1,gb(ptext[j-n2],0)); + } + else + switch (akeysz) + { + case 128: + memcpy(ciphertext, ptext[j], 16); + break; + case 192: + memcpy(ciphertext, ptext[j-1]+8, 8); + memcpy(ciphertext+8, ptext[j], 16); + break; + case 256: + memcpy(ciphertext, ptext[j-1], 16); + memcpy(ciphertext+16, ptext[j], 16); + break; + } + } + /* Compute next key: Key[i+1] = Key[i] xor ct */ + for (n = 0; n < nkeysz; ++n) + key[i+1][n] = key[i][n] ^ ciphertext[n]; + + /* Compute next IV and text */ + if (dir == XENCRYPT) + { + switch (imode) + { + case ECB: + memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE); + break; + case CBC: + case OFB: + case CFB128: + memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE); + memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE); + break; + case CFB8: + /* IV[i+1] = ct */ + for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) + iv[i+1][n1] = ctext[j-n2][0]; + ptext[0][0] = ctext[j-16][0]; + break; + case CFB1: + for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) + sb(iv[i+1],n1,gb(ctext[j-n2],0)); + ptext[0][0]=ctext[j-128][0]&0x80; + break; + } + } + else + { + switch (imode) + { + case ECB: + memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE); + break; + case CBC: + case OFB: + case CFB128: + memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE); + memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE); + break; + case CFB8: + for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) + iv[i+1][n1] = ptext[j-n2][0]; + ctext[0][0] = ptext[j-16][0]; + break; + case CFB1: + for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) + sb(iv[i+1],n1,gb(ptext[j-n2],0)); + ctext[0][0]=ptext[j-128][0]&0x80; + break; + } + } + } + + return ret; + } + +/*================================================*/ +/*---------------------------- + # Config info for v-one + # AESVS MMT test data for ECB + # State : Encrypt and Decrypt + # Key Length : 256 + # Fri Aug 30 04:07:22 PM + ----------------------------*/ + +int proc_file(char *rqfile, char *rspfile) + { + char afn[256], rfn[256]; + FILE *afp = NULL, *rfp = NULL; + char ibuf[2048]; + char tbuf[2048]; + int ilen, len, ret = 0; + char algo[8] = ""; + char amode[8] = ""; + char atest[8] = ""; + int akeysz = 0; + unsigned char iVec[20], aKey[40]; + int dir = -1, err = 0, step = 0; + unsigned char plaintext[2048]; + unsigned char ciphertext[2048]; + char *rp; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (!rqfile || !(*rqfile)) + { + printf("No req file\n"); + return -1; + } + strcpy(afn, rqfile); + + if ((afp = fopen(afn, "r")) == NULL) + { + printf("Cannot open file: %s, %s\n", + afn, strerror(errno)); + return -1; + } + if (!rspfile) + { + strcpy(rfn,afn); + rp=strstr(rfn,"req/"); +#ifdef OPENSSL_SYS_WIN32 + if (!rp) + rp=strstr(rfn,"req\\"); +#endif + assert(rp); + memcpy(rp,"rsp",3); + rp = strstr(rfn, ".req"); + memcpy(rp, ".rsp", 4); + rspfile = rfn; + } + if ((rfp = fopen(rspfile, "w")) == NULL) + { + printf("Cannot open file: %s, %s\n", + rfn, strerror(errno)); + fclose(afp); + afp = NULL; + return -1; + } + while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) + { + tidy_line(tbuf, ibuf); + ilen = strlen(ibuf); + /* printf("step=%d ibuf=%s",step,ibuf); */ + switch (step) + { + case 0: /* read preamble */ + if (ibuf[0] == '\n') + { /* end of preamble */ + if ((*algo == '\0') || + (*amode == '\0') || + (akeysz == 0)) + { + printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n", + algo,amode,akeysz); + err = 1; + } + else + { + fputs(ibuf, rfp); + ++ step; + } + } + else if (ibuf[0] != '#') + { + printf("Invalid preamble item: %s\n", ibuf); + err = 1; + } + else + { /* process preamble */ + char *xp, *pp = ibuf+2; + int n; + if (akeysz) + { /* insert current time & date */ + time_t rtim = time(0); + fprintf(rfp, "# %s", ctime(&rtim)); + } + else + { + fputs(ibuf, rfp); + if (strncmp(pp, "AESVS ", 6) == 0) + { + strcpy(algo, "AES"); + /* get test type */ + pp += 6; + xp = strchr(pp, ' '); + n = xp-pp; + strncpy(atest, pp, n); + atest[n] = '\0'; + /* get mode */ + xp = strrchr(pp, ' '); /* get mode" */ + n = strlen(xp+1)-1; + strncpy(amode, xp+1, n); + amode[n] = '\0'; + /* amode[3] = '\0'; */ + if (VERBOSE) + printf("Test = %s, Mode = %s\n", atest, amode); + } + else if (strncasecmp(pp, "Key Length : ", 13) == 0) + { + akeysz = atoi(pp+13); + if (VERBOSE) + printf("Key size = %d\n", akeysz); + } + } + } + break; + + case 1: /* [ENCRYPT] | [DECRYPT] */ + if (ibuf[0] == '[') + { + fputs(ibuf, rfp); + ++step; + if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) + dir = 1; + else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) + dir = 0; + else + { + printf("Invalid keyword: %s\n", ibuf); + err = 1; + } + break; + } + else if (dir == -1) + { + err = 1; + printf("Missing ENCRYPT/DECRYPT keyword\n"); + break; + } + else + step = 2; + + case 2: /* KEY = xxxx */ + fputs(ibuf, rfp); + if(*ibuf == '\n') + break; + if(!strncasecmp(ibuf,"COUNT = ",8)) + break; + + if (strncasecmp(ibuf, "KEY = ", 6) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+6, aKey); + if (len < 0) + { + printf("Invalid KEY\n"); + err =1; + break; + } + PrintValue("KEY", aKey, len); + if (strcmp(amode, "ECB") == 0) + { + memset(iVec, 0, sizeof(iVec)); + step = (dir)? 4: 5; /* no ivec for ECB */ + } + else + ++step; + } + break; + + case 3: /* IV = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "IV = ", 5) != 0) + { + printf("Missing IV\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+5, iVec); + if (len < 0) + { + printf("Invalid IV\n"); + err =1; + break; + } + PrintValue("IV", iVec, len); + step = (dir)? 4: 5; + } + break; + + case 4: /* PLAINTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) + { + printf("Missing PLAINTEXT\n"); + err = 1; + } + else + { + int nn = strlen(ibuf+12); + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+12,nn-1,plaintext); + else + len=hex2bin(ibuf+12, plaintext); + if (len < 0) + { + printf("Invalid PLAINTEXT: %s", ibuf+12); + err =1; + break; + } + if (len >= sizeof(plaintext)) + { + printf("Buffer overflow\n"); + } + PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); + if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ + { + if(do_mct(amode, akeysz, aKey, iVec, + dir, (unsigned char*)plaintext, len, + rfp) < 0) + EXIT(1); + } + else + { + ret = AESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("CIPHERTEXT",ciphertext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 5: /* CIPHERTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); + else + len = hex2bin(ibuf+13,ciphertext); + if (len < 0) + { + printf("Invalid CIPHERTEXT\n"); + err =1; + break; + } + + PrintValue("CIPHERTEXT", ciphertext, len); + if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ + { + do_mct(amode, akeysz, aKey, iVec, + dir, ciphertext, len, rfp); + } + else + { + ret = AESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 6: + if (ibuf[0] != '\n') + { + err = 1; + printf("Missing terminator\n"); + } + else if (strcmp(atest, "MCT") != 0) + { /* MCT already added terminating nl */ + fputs(ibuf, rfp); + } + step = 1; + break; + } + } + if (rfp) + fclose(rfp); + if (afp) + fclose(afp); + return err; + } + +/*-------------------------------------------------- + Processes either a single file or + a set of files whose names are passed in a file. + A single file is specified as: + aes_test -f xxx.req + A set of files is specified as: + aes_test -d xxxxx.xxx + The default is: -d req.txt +--------------------------------------------------*/ +int main(int argc, char **argv) + { + char *rqlist = "req.txt", *rspfile = NULL; + FILE *fp = NULL; + char fn[250] = "", rfn[256] = ""; + int f_opt = 0, d_opt = 1; + +#ifdef OPENSSL_FIPS + if(!FIPS_mode_set(1)) + { + do_print_errors(); + EXIT(1); + } +#endif + if (argc > 1) + { + if (strcasecmp(argv[1], "-d") == 0) + { + d_opt = 1; + } + else if (strcasecmp(argv[1], "-f") == 0) + { + f_opt = 1; + d_opt = 0; + } + else + { + printf("Invalid parameter: %s\n", argv[1]); + return 0; + } + if (argc < 3) + { + printf("Missing parameter\n"); + return 0; + } + if (d_opt) + rqlist = argv[2]; + else + { + strcpy(fn, argv[2]); + rspfile = argv[3]; + } + } + if (d_opt) + { /* list of files (directory) */ + if (!(fp = fopen(rqlist, "r"))) + { + printf("Cannot open req list file\n"); + return -1; + } + while (fgets(fn, sizeof(fn), fp)) + { + strtok(fn, "\r\n"); + strcpy(rfn, fn); + if (VERBOSE) + printf("Processing: %s\n", rfn); + if (proc_file(rfn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", rfn); + EXIT(1); + } + } + fclose(fp); + } + else /* single file */ + { + if (VERBOSE) + printf("Processing: %s\n", fn); + if (proc_file(fn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", fn); + } + } + EXIT(0); + return 0; + } + +#endif diff --git a/fips/des/.cvsignore b/fips/des/.cvsignore new file mode 100644 index 0000000000..439e6d3eb6 --- /dev/null +++ b/fips/des/.cvsignore @@ -0,0 +1,4 @@ +lib +Makefile.save +*.flc +semantic.cache diff --git a/fips/des/Makefile b/fips/des/Makefile new file mode 100644 index 0000000000..9b34c0af2d --- /dev/null +++ b/fips/des/Makefile @@ -0,0 +1,111 @@ +# +# OpenSSL/fips/des/Makefile +# + +DIR= des +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +ASFLAGS= $(INCLUDES) $(ASFLAG) +AFLAGS= $(ASFLAGS) + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= fips_desmovs.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_des_selftest.c +LIBOBJ=fips_des_selftest.o + +SRC= $(LIBSRC) + +EXHEADER= +HEADER= + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +fips_test: + -find ../testvectors/tdes/req -name '*.req' > testlist + -rm -rf ../testvectors/tdes/rsp + mkdir ../testvectors/tdes/rsp + if [ -s testlist ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_desmovs -d testlist; fi + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) \ + $(SRC) $(TEST) +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff testlist +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_des_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_des_selftest.o: ../../include/openssl/crypto.h +fips_des_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_des_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_des_selftest.o: ../../include/openssl/lhash.h +fips_des_selftest.o: ../../include/openssl/obj_mac.h +fips_des_selftest.o: ../../include/openssl/objects.h +fips_des_selftest.o: ../../include/openssl/opensslconf.h +fips_des_selftest.o: ../../include/openssl/opensslv.h +fips_des_selftest.o: ../../include/openssl/ossl_typ.h +fips_des_selftest.o: ../../include/openssl/safestack.h +fips_des_selftest.o: ../../include/openssl/stack.h +fips_des_selftest.o: ../../include/openssl/symhacks.h fips_des_selftest.c +fips_desmovs.o: ../../e_os.h ../../include/openssl/asn1.h +fips_desmovs.o: ../../include/openssl/bio.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/err.h +fips_desmovs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_desmovs.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_desmovs.o: ../../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 diff --git a/fips/des/fips_des_selftest.c b/fips/des/fips_des_selftest.c new file mode 100644 index 0000000000..61c39ce80b --- /dev/null +++ b/fips/des/fips_des_selftest.c @@ -0,0 +1,137 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +static struct + { + unsigned char key[16]; + unsigned char plaintext[8]; + unsigned char ciphertext[8]; + } tests2[]= + { + { + { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec, + 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 }, + { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef }, + { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd } + }, + { + { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34, + 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 }, + { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e }, + { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff }, + } + }; + +static struct + { + unsigned char key[24]; + unsigned char plaintext[8]; + unsigned char ciphertext[8]; + } tests3[]= + { + { + { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10, + 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 }, + { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c }, + { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b }, + }, + { + { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE, + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 }, + { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }, + { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 }, + }, + }; + +void FIPS_corrupt_des() + { + tests2[0].plaintext[0]++; + } + +int FIPS_selftest_des() + { + int n, ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + /* Encrypt/decrypt with 2-key 3DES and compare to known answers */ + for(n=0 ; n < 2 ; ++n) + { + if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(), + tests2[n].key, NULL, + tests2[n].plaintext, tests2[n].ciphertext, 8)) + goto err; + } + + /* Encrypt/decrypt with 3DES and compare to known answers */ + for(n=0 ; n < 2 ; ++n) + { + if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(), + tests3[n].key, NULL, + tests3[n].plaintext, tests3[n].ciphertext, 8)) + goto err; + } + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED); + + return ret; + } +#endif diff --git a/fips/des/fips_desmovs.c b/fips/des/fips_desmovs.c new file mode 100644 index 0000000000..c0de11bd7b --- /dev/null +++ b/fips/des/fips_desmovs.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include "e_os.h" + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS DES support\n"); + return(0); +} + +#else + +#include +#include "fips_utl.h" + +#define DES_BLOCK_SIZE 8 + +#define VERBOSE 0 + +int DESTest(EVP_CIPHER_CTX *ctx, + char *amode, int akeysz, unsigned char *aKey, + unsigned char *iVec, + int dir, /* 0 = decrypt, 1 = encrypt */ + unsigned char *out, unsigned char *in, int len) + { + const EVP_CIPHER *cipher = NULL; + + if (akeysz != 192) + { + printf("Invalid key size: %d\n", akeysz); + EXIT(1); + } + + if (strcasecmp(amode, "CBC") == 0) + cipher = EVP_des_ede3_cbc(); + else if (strcasecmp(amode, "ECB") == 0) + cipher = EVP_des_ede3_ecb(); + else if (strcasecmp(amode, "CFB64") == 0) + cipher = EVP_des_ede3_cfb64(); + else if (strncasecmp(amode, "OFB", 3) == 0) + cipher = EVP_des_ede3_ofb(); +#if 0 + else if(!strcasecmp(amode,"CFB1")) + { + ctx->cbits = 1; + ctx->cmode = EVP_CIPH_CFB_MODE; + } +#endif + else if(!strcasecmp(amode,"CFB8")) + cipher = EVP_des_ede3_cfb8(); + else + { + printf("Unknown mode: %s\n", amode); + EXIT(1); + } + + if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) + return 0; + 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); + + /* compensate for endianness */ + if(imode == CFB1) + text[0]<<=7; + + memcpy(text0,text,8); + + for(j=0 ; j < 10000 ; ++j) + { + unsigned char old_text[8]; + + memcpy(old_text,text,8); + if(j == 0) + { + memcpy(old_iv,ivec,8); + DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len); + } + else + { + memcpy(old_iv,ctx.iv,8); + EVP_Cipher(&ctx,text,text,len); + } + if(j == 9999) + { + OutputValue(t_tag[dir],text,len,rfp,imode == CFB1); + /* memcpy(ivec,text,8); */ + } + /* DebugValue("iv",ctx.iv,8); */ + /* accumulate material for the next key */ + shiftin(nk,text,Sizes[imode]); + /* DebugValue("nk",nk,24);*/ + if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64 + || imode == CBC)) || imode == OFB) + memcpy(text,old_iv,8); + + if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64)) + { + /* the test specifies using the output of the raw DES operation + which we don't have, so reconstruct it... */ + for(n=0 ; n < 8 ; ++n) + text[n]^=old_text[n]; + } + } + for(n=0 ; n < 8 ; ++n) + akey[n]^=nk[16+n]; + for(n=0 ; n < 8 ; ++n) + akey[8+n]^=nk[8+n]; + for(n=0 ; n < 8 ; ++n) + akey[16+n]^=nk[n]; + if(numkeys < 3) + memcpy(&akey[2*8],akey,8); + if(numkeys < 2) + memcpy(&akey[8],akey,8); + DES_set_odd_parity((DES_cblock *)akey); + DES_set_odd_parity((DES_cblock *)(akey+8)); + DES_set_odd_parity((DES_cblock *)(akey+16)); + memcpy(ivec,ctx.iv,8); + + /* pointless exercise - the final text doesn't depend on the + initial text in OFB mode, so who cares what it is? (Who + designed these tests?) */ + if(imode == OFB) + for(n=0 ; n < 8 ; ++n) + text[n]=text0[n]^old_iv[n]; + } + } + +int proc_file(char *rqfile, char *rspfile) + { + char afn[256], rfn[256]; + FILE *afp = NULL, *rfp = NULL; + char ibuf[2048], tbuf[2048]; + int ilen, len, ret = 0; + char amode[8] = ""; + char atest[100] = ""; + int akeysz=0; + unsigned char iVec[20], aKey[40]; + int dir = -1, err = 0, step = 0; + unsigned char plaintext[2048]; + unsigned char ciphertext[2048]; + char *rp; + EVP_CIPHER_CTX ctx; + int numkeys=1; + EVP_CIPHER_CTX_init(&ctx); + + if (!rqfile || !(*rqfile)) + { + printf("No req file\n"); + return -1; + } + strcpy(afn, rqfile); + + if ((afp = fopen(afn, "r")) == NULL) + { + printf("Cannot open file: %s, %s\n", + afn, strerror(errno)); + return -1; + } + if (!rspfile) + { + strcpy(rfn,afn); + rp=strstr(rfn,"req/"); +#ifdef OPENSSL_SYS_WIN32 + if (!rp) + rp=strstr(rfn,"req\\"); +#endif + assert(rp); + memcpy(rp,"rsp",3); + rp = strstr(rfn, ".req"); + memcpy(rp, ".rsp", 4); + rspfile = rfn; + } + if ((rfp = fopen(rspfile, "w")) == NULL) + { + printf("Cannot open file: %s, %s\n", + rfn, strerror(errno)); + fclose(afp); + afp = NULL; + return -1; + } + while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) + { + tidy_line(tbuf, ibuf); + ilen = strlen(ibuf); + /* printf("step=%d ibuf=%s",step,ibuf);*/ + if(step == 3 && !strcmp(amode,"ECB")) + { + memset(iVec, 0, sizeof(iVec)); + step = (dir)? 4: 5; /* no ivec for ECB */ + } + switch (step) + { + case 0: /* read preamble */ + if (ibuf[0] == '\n') + { /* end of preamble */ + if (*amode == '\0') + { + printf("Missing Mode\n"); + err = 1; + } + else + { + fputs(ibuf, rfp); + ++ step; + } + } + else if (ibuf[0] != '#') + { + printf("Invalid preamble item: %s\n", ibuf); + err = 1; + } + else + { /* process preamble */ + char *xp, *pp = ibuf+2; + int n; + if(*amode) + { /* insert current time & date */ + time_t rtim = time(0); + fprintf(rfp, "# %s", ctime(&rtim)); + } + else + { + fputs(ibuf, rfp); + if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4) + || !strncmp(pp,"TDES ",5) + || !strncmp(pp,"PERMUTATION ",12) + || !strncmp(pp,"SUBSTITUTION ",13) + || !strncmp(pp,"VARIABLE ",9)) + { + /* get test type */ + if(!strncmp(pp,"DES ",4)) + pp+=4; + else if(!strncmp(pp,"TDES ",5)) + pp+=5; + xp = strchr(pp, ' '); + n = xp-pp; + strncpy(atest, pp, n); + atest[n] = '\0'; + /* get mode */ + xp = strrchr(pp, ' '); /* get mode" */ + n = strlen(xp+1)-1; + strncpy(amode, xp+1, n); + amode[n] = '\0'; + /* amode[3] = '\0'; */ + if (VERBOSE) + printf("Test=%s, Mode=%s\n",atest,amode); + } + } + } + break; + + case 1: /* [ENCRYPT] | [DECRYPT] */ + if(ibuf[0] == '\n') + break; + if (ibuf[0] == '[') + { + fputs(ibuf, rfp); + ++step; + if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) + dir = 1; + else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) + dir = 0; + else + { + printf("Invalid keyword: %s\n", ibuf); + err = 1; + } + break; + } + else if (dir == -1) + { + err = 1; + printf("Missing ENCRYPT/DECRYPT keyword\n"); + break; + } + else + step = 2; + + case 2: /* KEY = xxxx */ + if(*ibuf == '\n') + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"COUNT = ",8)) + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"COUNT=",6)) + { + fputs(ibuf, rfp); + break; + } + if(!strncasecmp(ibuf,"NumKeys = ",10)) + { + numkeys=atoi(ibuf+10); + break; + } + + fputs(ibuf, rfp); + if(!strncasecmp(ibuf,"KEY = ",6)) + { + akeysz=64; + len = hex2bin((char*)ibuf+6, aKey); + if (len < 0) + { + printf("Invalid KEY\n"); + err=1; + break; + } + PrintValue("KEY", aKey, len); + ++step; + } + else if(!strncasecmp(ibuf,"KEYs = ",7)) + { + akeysz=64*3; + len=hex2bin(ibuf+7,aKey); + if(len != 8) + { + printf("Invalid KEY\n"); + err=1; + break; + } + memcpy(aKey+8,aKey,8); + memcpy(aKey+16,aKey,8); + ibuf[4]='\0'; + PrintValue("KEYs",aKey,len); + ++step; + } + else if(!strncasecmp(ibuf,"KEY",3)) + { + int n=ibuf[3]-'1'; + + akeysz=64*3; + len=hex2bin(ibuf+7,aKey+n*8); + if(len != 8) + { + printf("Invalid KEY\n"); + err=1; + break; + } + ibuf[4]='\0'; + PrintValue(ibuf,aKey,len); + if(n == 2) + ++step; + } + else + { + printf("Missing KEY\n"); + err = 1; + } + break; + + case 3: /* IV = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "IV = ", 5) != 0) + { + printf("Missing IV\n"); + err = 1; + } + else + { + len = hex2bin((char*)ibuf+5, iVec); + if (len < 0) + { + printf("Invalid IV\n"); + err =1; + break; + } + PrintValue("IV", iVec, len); + step = (dir)? 4: 5; + } + break; + + case 4: /* PLAINTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) + { + printf("Missing PLAINTEXT\n"); + err = 1; + } + else + { + int nn = strlen(ibuf+12); + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+12,nn-1,plaintext); + else + len=hex2bin(ibuf+12, plaintext); + if (len < 0) + { + printf("Invalid PLAINTEXT: %s", ibuf+12); + err =1; + break; + } + if (len >= sizeof(plaintext)) + { + printf("Buffer overflow\n"); + } + PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); + if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ + { + do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp); + } + else + { + assert(dir == 1); + ret = DESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + ciphertext, plaintext, len); + OutputValue("CIPHERTEXT",ciphertext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 5: /* CIPHERTEXT = xxxx */ + fputs(ibuf, rfp); + if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) + { + printf("Missing KEY\n"); + err = 1; + } + else + { + if(!strcmp(amode,"CFB1")) + len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); + else + len = hex2bin(ibuf+13,ciphertext); + if (len < 0) + { + printf("Invalid CIPHERTEXT\n"); + err =1; + break; + } + + PrintValue("CIPHERTEXT", ciphertext, len); + if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ + { + do_mct(amode, akeysz, numkeys, aKey, iVec, + dir, ciphertext, len, rfp); + } + else + { + assert(dir == 0); + ret = DESTest(&ctx, amode, akeysz, aKey, iVec, + dir, /* 0 = decrypt, 1 = encrypt */ + plaintext, ciphertext, len); + OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, + !strcmp(amode,"CFB1")); + } + step = 6; + } + break; + + case 6: + if (ibuf[0] != '\n') + { + err = 1; + printf("Missing terminator\n"); + } + else if (strcmp(atest, "MCT") != 0) + { /* MCT already added terminating nl */ + fputs(ibuf, rfp); + } + step = 1; + break; + } + } + if (rfp) + fclose(rfp); + if (afp) + fclose(afp); + return err; + } + +/*-------------------------------------------------- + Processes either a single file or + a set of files whose names are passed in a file. + A single file is specified as: + aes_test -f xxx.req + A set of files is specified as: + aes_test -d xxxxx.xxx + The default is: -d req.txt +--------------------------------------------------*/ +int main(int argc, char **argv) + { + char *rqlist = "req.txt", *rspfile = NULL; + FILE *fp = NULL; + char fn[250] = "", rfn[256] = ""; + int f_opt = 0, d_opt = 1; + +#ifdef OPENSSL_FIPS + if(!FIPS_mode_set(1)) + { + do_print_errors(); + EXIT(1); + } +#endif + if (argc > 1) + { + if (strcasecmp(argv[1], "-d") == 0) + { + d_opt = 1; + } + else if (strcasecmp(argv[1], "-f") == 0) + { + f_opt = 1; + d_opt = 0; + } + else + { + printf("Invalid parameter: %s\n", argv[1]); + return 0; + } + if (argc < 3) + { + printf("Missing parameter\n"); + return 0; + } + if (d_opt) + rqlist = argv[2]; + else + { + strcpy(fn, argv[2]); + rspfile = argv[3]; + } + } + if (d_opt) + { /* list of files (directory) */ + if (!(fp = fopen(rqlist, "r"))) + { + printf("Cannot open req list file\n"); + return -1; + } + while (fgets(fn, sizeof(fn), fp)) + { + strtok(fn, "\r\n"); + strcpy(rfn, fn); + printf("Processing: %s\n", rfn); + if (proc_file(rfn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", rfn); + EXIT(1); + } + } + fclose(fp); + } + else /* single file */ + { + if (VERBOSE) + printf("Processing: %s\n", fn); + if (proc_file(fn, rspfile)) + { + printf(">>> Processing failed for: %s <<<\n", fn); + } + } + EXIT(0); + return 0; + } + +#endif diff --git a/fips/dh/.cvsignore b/fips/dh/.cvsignore new file mode 100644 index 0000000000..9b0c7485d9 --- /dev/null +++ b/fips/dh/.cvsignore @@ -0,0 +1,4 @@ +lib +*.flc +semantic.cache +Makefile.save diff --git a/fips/dh/Makefile b/fips/dh/Makefile new file mode 100644 index 0000000000..a4e2e7738a --- /dev/null +++ b/fips/dh/Makefile @@ -0,0 +1,114 @@ +# +# OpenSSL/fips/dh/Makefile +# + +DIR= dh +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_dh_check.c fips_dh_gen.c fips_dh_key.c fips_dh_lib.c +LIBOBJ=fips_dh_check.o fips_dh_gen.o fips_dh_key.o fips_dh_lib.o + +SRC= $(LIBSRC) + +EXHEADER= +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +fips_test: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_dh_check.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +fips_dh_check.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h +fips_dh_check.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_dh_check.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_dh_check.o: ../../include/openssl/opensslconf.h +fips_dh_check.o: ../../include/openssl/opensslv.h +fips_dh_check.o: ../../include/openssl/ossl_typ.h +fips_dh_check.o: ../../include/openssl/safestack.h +fips_dh_check.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_dh_check.o: fips_dh_check.c +fips_dh_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +fips_dh_gen.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h +fips_dh_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_dh_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_dh_gen.o: ../../include/openssl/opensslconf.h +fips_dh_gen.o: ../../include/openssl/opensslv.h +fips_dh_gen.o: ../../include/openssl/ossl_typ.h +fips_dh_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_dh_gen.o: ../../include/openssl/symhacks.h fips_dh_gen.c +fips_dh_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +fips_dh_key.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h +fips_dh_key.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_dh_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_dh_key.o: ../../include/openssl/opensslconf.h +fips_dh_key.o: ../../include/openssl/opensslv.h +fips_dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_dh_key.o: ../../include/openssl/symhacks.h fips_dh_key.c +fips_dh_lib.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_dh_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.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 diff --git a/fips/dh/dh_gen.c b/fips/dh/dh_gen.c new file mode 100644 index 0000000000..999e1deb40 --- /dev/null +++ b/fips/dh/dh_gen.c @@ -0,0 +1,179 @@ +/* crypto/dh/dh_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* NB: These functions have been upgraded - the previous prototypes are in + * dh_depr.c as wrappers to these ones. + * - Geoff + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifndef OPENSSL_FIPS + +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); + +int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) + { + if(ret->meth->generate_params) + return ret->meth->generate_params(ret, prime_len, generator, cb); + return dh_builtin_genparams(ret, prime_len, generator, cb); + } + +/* We generate DH parameters as follows + * find a prime q which is prime_len/2 bits long. + * p=(2*q)+1 or (p-1)/2 = q + * For this case, g is a generator if + * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. + * Since the factors of p-1 are q and 2, we just need to check + * g^2 mod p != 1 and g^q mod p != 1. + * + * Having said all that, + * there is another special case method for the generators 2, 3 and 5. + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 <<<<< does not work for safe primes. + * for 5, p mod 10 == 3 or 7 + * + * Thanks to Phil Karn for the pointers about the + * special generators and for answering some of my questions. + * + * I've implemented the second simple method :-). + * Since DH should be using a safe prime (both p and q are prime), + * this generator function can take a very very long time to run. + */ +/* Actually there is no reason to insist that 'generator' be a generator. + * It's just as OK (and in some sense better) to use a generator of the + * order-q subgroup. + */ +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb) + { + BIGNUM *t1,*t2; + int g,ok= -1; + BN_CTX *ctx=NULL; + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t1 == NULL || t2 == NULL) goto err; + + /* Make sure 'ret' has the necessary elements */ + if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err; + if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err; + + if (generator <= 1) + { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + goto err; + } + if (generator == DH_GENERATOR_2) + { + if (!BN_set_word(t1,24)) goto err; + if (!BN_set_word(t2,11)) goto err; + g=2; + } +#if 0 /* does not work for safe primes */ + else if (generator == DH_GENERATOR_3) + { + if (!BN_set_word(t1,12)) goto err; + if (!BN_set_word(t2,5)) goto err; + g=3; + } +#endif + else if (generator == DH_GENERATOR_5) + { + if (!BN_set_word(t1,10)) goto err; + if (!BN_set_word(t2,3)) goto err; + /* BN_set_word(t3,7); just have to miss + * out on these ones :-( */ + g=5; + } + else + { + /* in the general case, don't worry if 'generator' is a + * generator or not: since we are using safe primes, + * it will generate either an order-q or an order-2q group, + * which both is OK */ + if (!BN_set_word(t1,2)) goto err; + if (!BN_set_word(t2,1)) goto err; + g=generator; + } + + if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err; + if(!BN_GENCB_call(cb, 3, 0)) goto err; + if (!BN_set_word(ret->g,g)) goto err; + ok=1; +err: + if (ok == -1) + { + DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB); + ok=0; + } + + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; + } + +#endif diff --git a/fips/dh/fips_dh_check.c b/fips/dh/fips_dh_check.c new file mode 100644 index 0000000000..7333f7c80f --- /dev/null +++ b/fips/dh/fips_dh_check.c @@ -0,0 +1,147 @@ +/* crypto/dh/dh_check.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +/* Check that p is a safe prime and + * if g is 2, 3 or 5, check that is is a suitable generator + * where + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 + * for 5, p mod 10 == 3 or 7 + * should hold. + */ + +#ifdef OPENSSL_FIPS + +int DH_check(const DH *dh, int *ret) + { + int ok=0; + BN_CTX *ctx=NULL; + BN_ULONG l; + BIGNUM *q=NULL; + + *ret=0; + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + q=BN_new(); + if (q == NULL) goto err; + + if (BN_is_word(dh->g,DH_GENERATOR_2)) + { + l=BN_mod_word(dh->p,24); + if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR; + } +#if 0 + else if (BN_is_word(dh->g,DH_GENERATOR_3)) + { + l=BN_mod_word(dh->p,12); + if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR; + } +#endif + else if (BN_is_word(dh->g,DH_GENERATOR_5)) + { + l=BN_mod_word(dh->p,10); + if ((l != 3) && (l != 7)) + *ret|=DH_NOT_SUITABLE_GENERATOR; + } + else + *ret|=DH_UNABLE_TO_CHECK_GENERATOR; + + if (!BN_is_prime_ex(dh->p,BN_prime_checks,ctx,NULL)) + *ret|=DH_CHECK_P_NOT_PRIME; + else + { + if (!BN_rshift1(q,dh->p)) goto err; + if (!BN_is_prime_ex(q,BN_prime_checks,ctx,NULL)) + *ret|=DH_CHECK_P_NOT_SAFE_PRIME; + } + ok=1; +err: + if (ctx != NULL) BN_CTX_free(ctx); + if (q != NULL) BN_free(q); + return(ok); + } + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) + { + int ok=0; + BIGNUM *q=NULL; + + *ret=0; + q=BN_new(); + if (q == NULL) goto err; + BN_set_word(q,1); + if (BN_cmp(pub_key,q) <= 0) + *ret|=DH_CHECK_PUBKEY_TOO_SMALL; + BN_copy(q,dh->p); + BN_sub_word(q,1); + if (BN_cmp(pub_key,q) >= 0) + *ret|=DH_CHECK_PUBKEY_TOO_LARGE; + + ok = 1; +err: + if (q != NULL) BN_free(q); + return(ok); + } + +#endif diff --git a/fips/dh/fips_dh_gen.c b/fips/dh/fips_dh_gen.c new file mode 100644 index 0000000000..d115f9d5d2 --- /dev/null +++ b/fips/dh/fips_dh_gen.c @@ -0,0 +1,192 @@ +/* crypto/dh/dh_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* NB: These functions have been upgraded - the previous prototypes are in + * dh_depr.c as wrappers to these ones. + * - Geoff + */ + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); + +int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) + { + if(ret->meth->generate_params) + return ret->meth->generate_params(ret, prime_len, generator, cb); + return dh_builtin_genparams(ret, prime_len, generator, cb); + } + +/* We generate DH parameters as follows + * find a prime q which is prime_len/2 bits long. + * p=(2*q)+1 or (p-1)/2 = q + * For this case, g is a generator if + * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. + * Since the factors of p-1 are q and 2, we just need to check + * g^2 mod p != 1 and g^q mod p != 1. + * + * Having said all that, + * there is another special case method for the generators 2, 3 and 5. + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 <<<<< does not work for safe primes. + * for 5, p mod 10 == 3 or 7 + * + * Thanks to Phil Karn for the pointers about the + * special generators and for answering some of my questions. + * + * I've implemented the second simple method :-). + * Since DH should be using a safe prime (both p and q are prime), + * this generator function can take a very very long time to run. + */ +/* Actually there is no reason to insist that 'generator' be a generator. + * It's just as OK (and in some sense better) to use a generator of the + * order-q subgroup. + */ +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb) + { + BIGNUM *t1,*t2; + int g,ok= -1; + BN_CTX *ctx=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t1 == NULL || t2 == NULL) goto err; + + /* Make sure 'ret' has the necessary elements */ + if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err; + if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err; + + if (generator <= 1) + { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + goto err; + } + if (generator == DH_GENERATOR_2) + { + if (!BN_set_word(t1,24)) goto err; + if (!BN_set_word(t2,11)) goto err; + g=2; + } +#if 0 /* does not work for safe primes */ + else if (generator == DH_GENERATOR_3) + { + if (!BN_set_word(t1,12)) goto err; + if (!BN_set_word(t2,5)) goto err; + g=3; + } +#endif + else if (generator == DH_GENERATOR_5) + { + if (!BN_set_word(t1,10)) goto err; + if (!BN_set_word(t2,3)) goto err; + /* BN_set_word(t3,7); just have to miss + * out on these ones :-( */ + g=5; + } + else + { + /* in the general case, don't worry if 'generator' is a + * generator or not: since we are using safe primes, + * it will generate either an order-q or an order-2q group, + * which both is OK */ + if (!BN_set_word(t1,2)) goto err; + if (!BN_set_word(t2,1)) goto err; + g=generator; + } + + if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err; + if(!BN_GENCB_call(cb, 3, 0)) goto err; + if (!BN_set_word(ret->g,g)) goto err; + ok=1; +err: + if (ok == -1) + { + DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB); + ok=0; + } + + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; + } + +#endif diff --git a/fips/dh/fips_dh_key.c b/fips/dh/fips_dh_key.c new file mode 100644 index 0000000000..d20fa91d5e --- /dev/null +++ b/fips/dh/fips_dh_key.c @@ -0,0 +1,276 @@ +/* crypto/dh/dh_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#ifndef OPENSSL_NO_RAND +#include +#endif +#ifndef OPENSSL_NO_DH +#include +#include + +#ifdef OPENSSL_FIPS + +static int generate_key(DH *dh); +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int dh_init(DH *dh); +static int dh_finish(DH *dh); + +int DH_generate_key(DH *dh) + { + return dh->meth->generate_key(dh); + } + +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) + { + return dh->meth->compute_key(key, pub_key, dh); + } + +static const DH_METHOD dh_ossl = { +"OpenSSL DH Method", +generate_key, +compute_key, +dh_bn_mod_exp, +dh_init, +dh_finish, +0, +NULL +}; + +const DH_METHOD *DH_OpenSSL(void) +{ + return &dh_ossl; +} + +static int generate_key(DH *dh) + { + int ok=0; + int generate_new_key=0; + unsigned l; + BN_CTX *ctx; + BN_MONT_CTX *mont=NULL; + BIGNUM *pub_key=NULL,*priv_key=NULL; + + if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) goto err; + + if (dh->priv_key == NULL) + { + priv_key=BN_new(); + if (priv_key == NULL) goto err; + generate_new_key=1; + } + else + priv_key=dh->priv_key; + + if (dh->pub_key == NULL) + { + pub_key=BN_new(); + if (pub_key == NULL) goto err; + } + else + pub_key=dh->pub_key; + + if (dh->flags & DH_FLAG_CACHE_MONT_P) + { + mont = BN_MONT_CTX_set_locked( + (BN_MONT_CTX **)&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if (!mont) + goto err; + } + + if (generate_new_key) + { + l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */ + if (!BN_rand(priv_key, l, 0, 0)) goto err; + } + + { + BIGNUM local_prk; + BIGNUM *prk; + + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) + { + BN_init(&local_prk); + prk = &local_prk; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + } + else + prk = priv_key; + + if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) + goto err; + } + + dh->pub_key=pub_key; + dh->priv_key=priv_key; + ok=1; +err: + if (ok != 1) + DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB); + + if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); + if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); + BN_CTX_free(ctx); + return(ok); + } + +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) + { + BN_CTX *ctx; + BN_MONT_CTX *mont=NULL; + BIGNUM *tmp; + int ret= -1; + + ctx = BN_CTX_new(); + if (ctx == NULL) goto err; + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) + { + DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } + + if (dh->priv_key == NULL) + { + DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (dh->flags & DH_FLAG_CACHE_MONT_P) + { + mont = BN_MONT_CTX_set_locked( + (BN_MONT_CTX **)&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) + { + /* XXX */ + BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); + } + if (!mont) + goto err; + } + + if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont)) + { + DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB); + goto err; + } + + ret=BN_bn2bin(tmp,key); +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return(ret); + } + +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) + { + /* If a is only one word long and constant time is false, use the faster + * exponenentiation function. + */ + if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) + { + BN_ULONG A = a->d[0]; + return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx); + } + else + return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx); + } + + +static int dh_init(DH *dh) + { + FIPS_selftest_check(); + dh->flags |= DH_FLAG_CACHE_MONT_P; + return(1); + } + +static int dh_finish(DH *dh) + { + if(dh->method_mont_p) + BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p); + return(1); + } + +#endif +#endif diff --git a/fips/dh/fips_dh_lib.c b/fips/dh/fips_dh_lib.c new file mode 100644 index 0000000000..692f6b792f --- /dev/null +++ b/fips/dh/fips_dh_lib.c @@ -0,0 +1,94 @@ +/* fips_dh_lib.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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). + * + */ + +#include +#include + +/* 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); + } diff --git a/fips/dsa/.cvsignore b/fips/dsa/.cvsignore new file mode 100644 index 0000000000..439e6d3eb6 --- /dev/null +++ b/fips/dsa/.cvsignore @@ -0,0 +1,4 @@ +lib +Makefile.save +*.flc +semantic.cache diff --git a/fips/dsa/Makefile b/fips/dsa/Makefile new file mode 100644 index 0000000000..8d36786c46 --- /dev/null +++ b/fips/dsa/Makefile @@ -0,0 +1,176 @@ +# +# OpenSSL/fips/dsa/Makefile +# + +DIR= dsa +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=fips_dsatest.c fips_dssvs.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_dsa_ossl.c fips_dsa_gen.c fips_dsa_selftest.c fips_dsa_key.c \ + fips_dsa_lib.c fips_dsa_sign.c +LIBOBJ=fips_dsa_ossl.o fips_dsa_gen.o fips_dsa_selftest.o fips_dsa_key.o \ + fips_dsa_lib.o fips_dsa_sign.o + +SRC= $(LIBSRC) + +EXHEADER= +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +Q=../testvectors/dsa/req +A=../testvectors/dsa/rsp + +fips_test: + -rm -rf $A + mkdir $A + if [ -f $(Q)/PQGGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs pqg < $(Q)/PQGGen.req > $(A)/PQGGen.rsp; fi + if [ -f $(Q)/KeyPair.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs keypair < $(Q)/KeyPair.req > $(A)/KeyPair.rsp; fi + if [ -f $(Q)/SigGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs siggen < $(Q)/SigGen.req > $(A)/SigGen.rsp; fi + if [ -f $(Q)/SigVer.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs sigver < $Q/SigVer.req > $A/SigVer.rsp; fi + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_dsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_dsa_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_dsa_gen.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +fips_dsa_gen.o: ../../include/openssl/opensslconf.h +fips_dsa_gen.o: ../../include/openssl/opensslv.h +fips_dsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_dsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_dsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_dsa_gen.o: fips_dsa_gen.c +fips_dsa_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dsa_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_dsa_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_dsa_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_dsa_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +fips_dsa_key.o: ../../include/openssl/opensslconf.h +fips_dsa_key.o: ../../include/openssl/opensslv.h +fips_dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_dsa_key.o: ../../include/openssl/symhacks.h fips_dsa_key.c +fips_dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_dsa_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.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_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dsa_ossl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_dsa_ossl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_dsa_ossl.o: ../../include/openssl/engine.h ../../include/openssl/fips.h +fips_dsa_ossl.o: ../../include/openssl/opensslconf.h +fips_dsa_ossl.o: ../../include/openssl/opensslv.h +fips_dsa_ossl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_dsa_ossl.o: ../../include/openssl/safestack.h +fips_dsa_ossl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_dsa_ossl.o: fips_dsa_ossl.c +fips_dsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dsa_selftest.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h +fips_dsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_dsa_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_dsa_selftest.o: ../../include/openssl/lhash.h +fips_dsa_selftest.o: ../../include/openssl/obj_mac.h +fips_dsa_selftest.o: ../../include/openssl/objects.h +fips_dsa_selftest.o: ../../include/openssl/opensslconf.h +fips_dsa_selftest.o: ../../include/openssl/opensslv.h +fips_dsa_selftest.o: ../../include/openssl/ossl_typ.h +fips_dsa_selftest.o: ../../include/openssl/safestack.h +fips_dsa_selftest.o: ../../include/openssl/stack.h +fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c +fips_dsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h +fips_dsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_dsa_sign.o: ../../include/openssl/evp.h ../../include/openssl/fips.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/bio.h +fips_dsatest.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +fips_dsatest.o: ../../include/openssl/des_old.h ../../include/openssl/dsa.h +fips_dsatest.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +fips_dsatest.o: ../../include/openssl/err.h ../../include/openssl/fips.h +fips_dsatest.o: ../../include/openssl/fips_rand.h ../../include/openssl/lhash.h +fips_dsatest.o: ../../include/openssl/opensslconf.h +fips_dsatest.o: ../../include/openssl/opensslv.h +fips_dsatest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_dsatest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_dsatest.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h +fips_dsatest.o: ../../include/openssl/ui_compat.h ../fips_utl.h fips_dsatest.c +fips_dssvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dssvs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_dssvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_dssvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_dssvs.o: ../../include/openssl/fips.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 diff --git a/fips/dsa/fips_dsa_gen.c b/fips/dsa/fips_dsa_gen.c new file mode 100644 index 0000000000..0cecf34ab2 --- /dev/null +++ b/fips/dsa/fips_dsa_gen.c @@ -0,0 +1,339 @@ +/* crypto/dsa/dsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#undef GENUINE_DSA + +#ifdef GENUINE_DSA +/* Parameter generation follows the original release of FIPS PUB 186, + * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */ +#define HASH EVP_sha() +#else +/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, + * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in + * FIPS PUB 180-1) */ +#define HASH EVP_sha1() +#endif + +#include /* To see if OPENSSL_NO_SHA is defined */ + +#ifndef OPENSSL_NO_SHA + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +static int dsa_builtin_paramgen(DSA *ret, int bits, + unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); + +int DSA_generate_parameters_ex(DSA *ret, int bits, + unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) + { + if(ret->meth->dsa_paramgen) + return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, + counter_ret, h_ret, cb); + return dsa_builtin_paramgen(ret, bits, seed_in, seed_len, + counter_ret, h_ret, cb); + } + +static int dsa_builtin_paramgen(DSA *ret, int bits, + unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) + { + int ok=0; + unsigned char seed[SHA_DIGEST_LENGTH]; + unsigned char md[SHA_DIGEST_LENGTH]; + unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH]; + BIGNUM *r0,*W,*X,*c,*test; + BIGNUM *g=NULL,*q=NULL,*p=NULL; + BN_MONT_CTX *mont=NULL; + int k,n=0,i,b,m=0; + int counter=0; + int r=0; + BN_CTX *ctx=NULL; + unsigned int h=2; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, + FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + + if (bits < 512) bits=512; + bits=(bits+63)/64*64; + + /* NB: seed_len == 0 is special case: copy generated seed to + * seed_in if it is not NULL. + */ + if (seed_len && (seed_len < 20)) + seed_in = NULL; /* seed buffer too small -- ignore */ + if (seed_len > 20) + seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED, + * but our internal buffers are restricted to 160 bits*/ + if ((seed_in != NULL) && (seed_len == 20)) + { + memcpy(seed,seed_in,seed_len); + /* set seed_in to NULL to avoid it being copied back */ + seed_in = NULL; + } + + if ((ctx=BN_CTX_new()) == NULL) goto err; + + if ((mont=BN_MONT_CTX_new()) == NULL) goto err; + + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + g = BN_CTX_get(ctx); + W = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); + p = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + + if (!BN_lshift(test,BN_value_one(),bits-1)) + goto err; + + for (;;) + { + for (;;) /* find q */ + { + int seed_is_random; + + /* step 1 */ + if(!BN_GENCB_call(cb, 0, m++)) + goto err; + + if (!seed_len) + { + RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH); + seed_is_random = 1; + } + else + { + seed_is_random = 0; + seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ + } + memcpy(buf,seed,SHA_DIGEST_LENGTH); + memcpy(buf2,seed,SHA_DIGEST_LENGTH); + /* precompute "SEED + 1" for step 7: */ + for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) + { + buf[i]++; + if (buf[i] != 0) break; + } + + /* step 2 */ + EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); + EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL); + for (i=0; i 0) + break; + if (r != 0) + goto err; + + /* do a callback call */ + /* step 5 */ + } + + if(!BN_GENCB_call(cb, 2, 0)) goto err; + if(!BN_GENCB_call(cb, 3, 0)) goto err; + + /* step 6 */ + counter=0; + /* "offset = 2" */ + + n=(bits-1)/160; + b=(bits-1)-n*160; + + for (;;) + { + if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) + goto err; + + /* step 7 */ + BN_zero(W); + /* now 'buf' contains "SEED + offset - 1" */ + for (k=0; k<=n; k++) + { + /* obtain "SEED + offset + k" by incrementing: */ + for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) + { + buf[i]++; + if (buf[i] != 0) break; + } + + EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); + + /* step 8 */ + if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) + goto err; + if (!BN_lshift(r0,r0,160*k)) goto err; + if (!BN_add(W,W,r0)) goto err; + } + + /* more of step 8 */ + if (!BN_mask_bits(W,bits-1)) goto err; + if (!BN_copy(X,W)) goto err; + if (!BN_add(X,X,test)) goto err; + + /* step 9 */ + if (!BN_lshift1(r0,q)) goto err; + if (!BN_mod(c,X,r0,ctx)) goto err; + if (!BN_sub(r0,c,BN_value_one())) goto err; + if (!BN_sub(p,X,r0)) goto err; + + /* step 10 */ + if (BN_cmp(p,test) >= 0) + { + /* step 11 */ + r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, + ctx, 1, cb); + if (r > 0) + goto end; /* found it */ + if (r != 0) + goto err; + } + + /* step 13 */ + counter++; + /* "offset = offset + n + 1" */ + + /* step 14 */ + if (counter >= 4096) break; + } + } +end: + if(!BN_GENCB_call(cb, 2, 1)) + goto err; + + /* We now need to generate g */ + /* Set r0=(p-1)/q */ + if (!BN_sub(test,p,BN_value_one())) goto err; + if (!BN_div(r0,NULL,test,q,ctx)) goto err; + + if (!BN_set_word(test,h)) goto err; + if (!BN_MONT_CTX_set(mont,p,ctx)) goto err; + + for (;;) + { + /* g=test^r0%p */ + if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err; + if (!BN_is_one(g)) break; + if (!BN_add(test,test,BN_value_one())) goto err; + h++; + } + + if(!BN_GENCB_call(cb, 3, 1)) + goto err; + + ok=1; +err: + if (ok) + { + if(ret->p) BN_free(ret->p); + if(ret->q) BN_free(ret->q); + if(ret->g) BN_free(ret->g); + ret->p=BN_dup(p); + ret->q=BN_dup(q); + ret->g=BN_dup(g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) + { + ok=0; + goto err; + } + if (seed_in != NULL) memcpy(seed_in,seed,20); + if (counter_ret != NULL) *counter_ret=counter; + if (h_ret != NULL) *h_ret=h; + } + if(ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (mont != NULL) BN_MONT_CTX_free(mont); + return ok; + } +#endif +#endif diff --git a/fips/dsa/fips_dsa_key.c b/fips/dsa/fips_dsa_key.c new file mode 100644 index 0000000000..b5f8cfa1d0 --- /dev/null +++ b/fips/dsa/fips_dsa_key.c @@ -0,0 +1,169 @@ +/* crypto/dsa/dsa_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#ifndef OPENSSL_NO_SHA +#include +#include +#include +#include +#include +#include +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +static int fips_dsa_pairwise_fail = 0; + +void FIPS_corrupt_dsa_keygen(void) + { + fips_dsa_pairwise_fail = 1; + } + +static int dsa_builtin_keygen(DSA *dsa); + +int fips_check_dsa(DSA *dsa) + { + EVP_PKEY pk; + unsigned char tbs[] = "DSA Pairwise Check Data"; + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + + if (!fips_pkey_signature_test(&pk, tbs, -1, + NULL, 0, EVP_dss1(), 0, NULL)) + { + FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED); + fips_set_selftest_fail(); + return 0; + } + return 1; + } + +int DSA_generate_key(DSA *dsa) + { + if(dsa->meth->dsa_keygen) + return dsa->meth->dsa_keygen(dsa); + return dsa_builtin_keygen(dsa); + } + +static int dsa_builtin_keygen(DSA *dsa) + { + int ok=0; + BN_CTX *ctx=NULL; + BIGNUM *pub_key=NULL,*priv_key=NULL; + + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + + if ((ctx=BN_CTX_new()) == NULL) goto err; + + if (dsa->priv_key == NULL) + { + if ((priv_key=BN_new()) == NULL) goto err; + } + else + priv_key=dsa->priv_key; + + do + if (!BN_rand_range(priv_key,dsa->q)) goto err; + while (BN_is_zero(priv_key)); + + if (dsa->pub_key == NULL) + { + if ((pub_key=BN_new()) == NULL) goto err; + } + else + pub_key=dsa->pub_key; + + { + BIGNUM local_prk; + BIGNUM *prk; + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) + { + BN_init(&local_prk); + prk = &local_prk; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + } + else + prk = priv_key; + + if (!BN_mod_exp(pub_key,dsa->g,prk,dsa->p,ctx)) goto err; + } + + dsa->priv_key=priv_key; + dsa->pub_key=pub_key; + if (fips_dsa_pairwise_fail) + BN_add_word(dsa->pub_key, 1); + if(!fips_check_dsa(dsa)) + goto err; + ok=1; + +err: + if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key); + if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key); + if (ctx != NULL) BN_CTX_free(ctx); + return(ok); + } +#endif + +#endif diff --git a/fips/dsa/fips_dsa_lib.c b/fips/dsa/fips_dsa_lib.c new file mode 100644 index 0000000000..12f0badb99 --- /dev/null +++ b/fips/dsa/fips_dsa_lib.c @@ -0,0 +1,94 @@ +/* fips_dsa_lib.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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). + * + */ + +#include +#include + +/* Minimal FIPS versions of FIPS_dsa_new() and FIPS_dsa_free: to + * reduce external dependencies. + */ + +DSA *FIPS_dsa_new(void) + { + 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; + } + +void FIPS_dsa_free(DSA *r) + { + if (!r) + return; + 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); + } + diff --git a/fips/dsa/fips_dsa_ossl.c b/fips/dsa/fips_dsa_ossl.c new file mode 100644 index 0000000000..6e3747a205 --- /dev/null +++ b/fips/dsa/fips_dsa_ossl.c @@ -0,0 +1,434 @@ +/* crypto/dsa/dsa_ossl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#include + +#ifdef OPENSSL_FIPS + +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa); +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); +static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig, + DSA *dsa); +static int dsa_init(DSA *dsa); +static int dsa_finish(DSA *dsa); +static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); +static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + +static const DSA_METHOD openssl_dsa_meth = { +"OpenSSL FIPS DSA method", +dsa_do_sign, +dsa_sign_setup, +dsa_do_verify, +dsa_mod_exp, +dsa_bn_mod_exp, +dsa_init, +dsa_finish, +DSA_FLAG_FIPS_METHOD, +NULL +}; +#if 0 +int FIPS_dsa_check(struct dsa_st *dsa) + { + if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign + || dsa->meth->dsa_sign_setup != dsa_sign_setup + || dsa->meth->dsa_mod_exp != dsa_mod_exp + || dsa->meth->bn_mod_exp != dsa_bn_mod_exp + || dsa->meth->init != dsa_init + || dsa->meth->finish != dsa_finish) + { + FIPSerr(FIPS_F_FIPS_DSA_CHECK,FIPS_R_NON_FIPS_METHOD); + return 0; + } + return 1; + } +#endif + +const DSA_METHOD *DSA_OpenSSL(void) +{ + return &openssl_dsa_meth; +} + +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa) + { + BIGNUM *kinv=NULL,*r=NULL,*s=NULL; + BIGNUM m; + BIGNUM xr; + BN_CTX *ctx=NULL; + int i,reason=ERR_R_BN_LIB; + DSA_SIG *ret=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED); + return NULL; + } + + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL); + return NULL; + } + + BN_init(&m); + BN_init(&xr); + + if (!dsa->p || !dsa->q || !dsa->g) + { + reason=DSA_R_MISSING_PARAMETERS; + goto err; + } + + s=BN_new(); + if (s == NULL) goto err; + + i=BN_num_bytes(dsa->q); /* should be 20 */ + if ((dlen > i) || (dlen > 50)) + { + reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; + goto err; + } + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + + if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err; + + if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; + + /* Compute s = inv(k) (m + xr) mod q */ + if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ + if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ + if (BN_cmp(s,dsa->q) > 0) + BN_sub(s,s,dsa->q); + if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; + + ret= DSA_SIG_new(); + if (ret == NULL) goto err; + ret->r = r; + ret->s = s; + +err: + if (!ret) + { + DSAerr(DSA_F_DSA_DO_SIGN,reason); + BN_free(r); + BN_free(s); + } + if (ctx != NULL) BN_CTX_free(ctx); + BN_clear_free(&m); + BN_clear_free(&xr); + if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ + BN_clear_free(kinv); + return(ret); + } + +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) + { + BN_CTX *ctx; + BIGNUM k,kq,*K,*kinv=NULL,*r=NULL; + int ret=0; + + if (!dsa->p || !dsa->q || !dsa->g) + { + DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS); + return 0; + } + + BN_init(&k); + BN_init(&kq); + + if (ctx_in == NULL) + { + if ((ctx=BN_CTX_new()) == NULL) goto err; + } + else + ctx=ctx_in; + + if ((r=BN_new()) == NULL) goto err; + + /* Get random k */ + do + if (!BN_rand_range(&k, dsa->q)) goto err; + while (BN_is_zero(&k)); + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) + { + BN_set_flags(&k, BN_FLG_CONSTTIME); + } + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) + { + if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, + CRYPTO_LOCK_DSA, + dsa->p, ctx)) + goto err; + } + + /* Compute r = (g^k mod p) mod q */ + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) + { + if (!BN_copy(&kq, &k)) goto err; + + /* We do not want timing information to leak the length of k, + * so we compute g^k using an equivalent exponent of fixed length. + * + * (This is a kludge that we need because the BN_mod_exp_mont() + * does not let us specify the desired timing behaviour.) */ + + if (!BN_add(&kq, &kq, dsa->q)) goto err; + if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) + { + if (!BN_add(&kq, &kq, dsa->q)) goto err; + } + + K = &kq; + } + else + { + K = &k; + } + if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,K,dsa->p,ctx, + (BN_MONT_CTX *)dsa->method_mont_p)) goto err; + if (!BN_mod(r,r,dsa->q,ctx)) goto err; + + /* Compute part of 's = inv(k) (m + xr) mod q' */ + if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err; + + if (*kinvp != NULL) BN_clear_free(*kinvp); + *kinvp=kinv; + kinv=NULL; + if (*rp != NULL) BN_clear_free(*rp); + *rp=r; + ret=1; +err: + if (!ret) + { + DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); + if (kinv != NULL) BN_clear_free(kinv); + if (r != NULL) BN_clear_free(r); + } + if (ctx_in == NULL) BN_CTX_free(ctx); + if (kinv != NULL) BN_clear_free(kinv); + BN_clear_free(&k); + BN_clear_free(&kq); + return(ret); + } + +static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig, + DSA *dsa) + { + BN_CTX *ctx; + BIGNUM u1,u2,t1; + BN_MONT_CTX *mont=NULL; + int ret = -1; + + if (!dsa->p || !dsa->q || !dsa->g) + { + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS); + return -1; + } + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (BN_num_bits(dsa->q) != 160) + { + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE); + return -1; + } + + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) + { + DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + BN_init(&u1); + BN_init(&u2); + BN_init(&t1); + + if ((ctx=BN_CTX_new()) == NULL) goto err; + + if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0) + { + ret = 0; + goto err; + } + if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0) + { + ret = 0; + goto err; + } + + /* Calculate W = inv(S) mod Q + * save W in u2 */ + if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; + + /* save M in u1 */ + if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; + + /* u1 = M * w mod q */ + if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err; + + /* u2 = r * w mod q */ + if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; + + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) + { + mont = BN_MONT_CTX_set_locked( + (BN_MONT_CTX **)&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx); + if (!mont) + goto err; + } + +#if 0 + { + BIGNUM t2; + + BN_init(&t2); + /* v = ( g^u1 * y^u2 mod p ) mod q */ + /* let t1 = g ^ u1 mod p */ + if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err; + /* let t2 = y ^ u2 mod p */ + if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err; + /* let u1 = t1 * t2 mod p */ + if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn; + BN_free(&t2); + } + /* let u1 = u1 mod q */ + if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err; +#else + { + if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2, + dsa->p,ctx,mont)) goto err; + /* BN_copy(&u1,&t1); */ + /* let u1 = u1 mod q */ + if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; + } +#endif + /* V is now in u1. If the signature is correct, it will be + * equal to R. */ + ret=(BN_ucmp(&u1, sig->r) == 0); + + err: + if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); + if (ctx != NULL) BN_CTX_free(ctx); + BN_free(&u1); + BN_free(&u2); + BN_free(&t1); + return(ret); + } + +static int dsa_init(DSA *dsa) +{ + FIPS_selftest_check(); + dsa->flags|=DSA_FLAG_CACHE_MONT_P; + return(1); +} + +static int dsa_finish(DSA *dsa) +{ + if(dsa->method_mont_p) + BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p); + return(1); +} + +static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont) +{ + return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont); +} + +static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +} + +#else /* ndef OPENSSL_FIPS */ + +static void *dummy=&dummy; + +#endif /* ndef OPENSSL_FIPS */ diff --git a/fips/dsa/fips_dsa_selftest.c b/fips/dsa/fips_dsa_selftest.c new file mode 100644 index 0000000000..6ff114e6b2 --- /dev/null +++ b/fips/dsa/fips_dsa_selftest.c @@ -0,0 +1,179 @@ +/* crypto/dsa/dsatest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +/* seed, out_p, out_q, out_g are taken the NIST test vectors */ + +static unsigned char seed[20] = { + 0x77, 0x8f, 0x40, 0x74, 0x6f, 0x66, 0xbe, 0x33, 0xce, 0xbe, 0x99, 0x34, + 0x4c, 0xfc, 0xf3, 0x28, 0xaa, 0x70, 0x2d, 0x3a + }; + +static unsigned char out_p[] = { + 0xf7, 0x7c, 0x1b, 0x83, 0xd8, 0xe8, 0x5c, 0x7f, 0x85, 0x30, 0x17, 0x57, + 0x21, 0x95, 0xfe, 0x26, 0x04, 0xeb, 0x47, 0x4c, 0x3a, 0x4a, 0x81, 0x4b, + 0x71, 0x2e, 0xed, 0x6e, 0x4f, 0x3d, 0x11, 0x0f, 0x7c, 0xfe, 0x36, 0x43, + 0x51, 0xd9, 0x81, 0x39, 0x17, 0xdf, 0x62, 0xf6, 0x9c, 0x01, 0xa8, 0x69, + 0x71, 0xdd, 0x29, 0x7f, 0x47, 0xe6, 0x65, 0xa6, 0x22, 0xe8, 0x6a, 0x12, + 0x2b, 0xc2, 0x81, 0xff, 0x32, 0x70, 0x2f, 0x9e, 0xca, 0x53, 0x26, 0x47, + 0x0f, 0x59, 0xd7, 0x9e, 0x2c, 0xa5, 0x07, 0xc4, 0x49, 0x52, 0xa3, 0xe4, + 0x6b, 0x04, 0x00, 0x25, 0x49, 0xe2, 0xe6, 0x7f, 0x28, 0x78, 0x97, 0xb8, + 0x3a, 0x32, 0x14, 0x38, 0xa2, 0x51, 0x33, 0x22, 0x44, 0x7e, 0xd7, 0xef, + 0x45, 0xdb, 0x06, 0x4a, 0xd2, 0x82, 0x4a, 0x82, 0x2c, 0xb1, 0xd7, 0xd8, + 0xb6, 0x73, 0x00, 0x4d, 0x94, 0x77, 0x94, 0xef + }; + +static unsigned char out_q[] = { + 0xd4, 0x0a, 0xac, 0x9f, 0xbd, 0x8c, 0x80, 0xc2, 0x38, 0x7e, 0x2e, 0x0c, + 0x52, 0x5c, 0xea, 0x34, 0xa1, 0x83, 0x32, 0xf3 + }; + +static unsigned char out_g[] = { + 0x34, 0x73, 0x8b, 0x57, 0x84, 0x8e, 0x55, 0xbf, 0x57, 0xcc, 0x41, 0xbb, + 0x5e, 0x2b, 0xd5, 0x42, 0xdd, 0x24, 0x22, 0x2a, 0x09, 0xea, 0x26, 0x1e, + 0x17, 0x65, 0xcb, 0x1a, 0xb3, 0x12, 0x44, 0xa3, 0x9e, 0x99, 0xe9, 0x63, + 0xeb, 0x30, 0xb1, 0x78, 0x7b, 0x09, 0x40, 0x30, 0xfa, 0x83, 0xc2, 0x35, + 0xe1, 0xc4, 0x2d, 0x74, 0x1a, 0xb1, 0x83, 0x54, 0xd8, 0x29, 0xf4, 0xcf, + 0x7f, 0x6f, 0x67, 0x1c, 0x36, 0x49, 0xee, 0x6c, 0xa2, 0x3c, 0x2d, 0x6a, + 0xe9, 0xd3, 0x9a, 0xf6, 0x57, 0x78, 0x6f, 0xfd, 0x33, 0xcd, 0x3c, 0xed, + 0xfd, 0xd4, 0x41, 0xe6, 0x5c, 0x8b, 0xe0, 0x68, 0x31, 0x47, 0x47, 0xaf, + 0x12, 0xa7, 0xf9, 0x32, 0x0d, 0x94, 0x15, 0x48, 0xd0, 0x54, 0x85, 0xb2, + 0x04, 0xb5, 0x4d, 0xd4, 0x9d, 0x05, 0x22, 0x25, 0xd9, 0xfd, 0x6c, 0x36, + 0xef, 0xbe, 0x69, 0x6c, 0x55, 0xf4, 0xee, 0xec + }; + +static const unsigned char str1[]="12345678901234567890"; + +void FIPS_corrupt_dsa() + { + ++seed[0]; + } + +int FIPS_selftest_dsa() + { + DSA *dsa=NULL; + int counter,i,j, ret = 0; + unsigned int slen; + unsigned char buf[256]; + unsigned long h; + EVP_MD_CTX mctx; + EVP_PKEY pk; + + EVP_MD_CTX_init(&mctx); + + dsa = FIPS_dsa_new(); + + if(dsa == NULL) + goto err; + if(!DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,NULL)) + goto err; + if (counter != 378) + goto err; + if (h != 2) + goto err; + i=BN_bn2bin(dsa->q,buf); + j=sizeof(out_q); + if (i != j || memcmp(buf,out_q,i) != 0) + goto err; + + i=BN_bn2bin(dsa->p,buf); + j=sizeof(out_p); + if (i != j || memcmp(buf,out_p,i) != 0) + goto err; + + i=BN_bn2bin(dsa->g,buf); + j=sizeof(out_g); + if (i != j || memcmp(buf,out_g,i) != 0) + goto err; + DSA_generate_key(dsa); + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + + if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) + goto err; + if (!EVP_SignUpdate(&mctx, str1, 20)) + goto err; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto err; + + if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) + goto err; + if (!EVP_VerifyUpdate(&mctx, str1, 20)) + goto err; + if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1) + goto err; + + ret = 1; + + err: + EVP_MD_CTX_cleanup(&mctx); + if (dsa) + FIPS_dsa_free(dsa); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED); + return ret; + } +#endif diff --git a/fips/dsa/fips_dsa_sign.c b/fips/dsa/fips_dsa_sign.c new file mode 100644 index 0000000000..1707ff39b2 --- /dev/null +++ b/fips/dsa/fips_dsa_sign.c @@ -0,0 +1,255 @@ +/* fips_dsa_sign.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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). + * + */ + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +/* FIPS versions of DSA_sign() and DSA_verify(). + * These include a tiny ASN1 encoder/decoder to handle the specific + * case of a DSA signature. + */ + +int FIPS_dsa_size(DSA *r) + { + int ilen; + ilen = BN_num_bytes(r->q); + if (ilen > 20) + return -1; + /* If MSB set need padding byte */ + ilen ++; + /* Also need 2 bytes INTEGER header for r and s plus + * 2 bytes SEQUENCE header making 6 in total. + */ + return ilen * 2 + 6; + } + +/* Tiny ASN1 encoder for DSA_SIG structure. We can assume r, s smaller than + * 0x80 octets as by the DSA standards they will be less than 2^160 + */ + +int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig) + { + int rlen, slen, rpad, spad, seqlen; + rlen = BN_num_bytes(sig->r); + if (rlen > 20) + return -1; + if (BN_num_bits(sig->r) & 0x7) + rpad = 0; + else + rpad = 1; + slen = BN_num_bytes(sig->s); + if (slen > 20) + return -1; + if (BN_num_bits(sig->s) & 0x7) + spad = 0; + else + spad = 1; + /* Length of SEQUENCE, (1 tag + 1 len octet) * 2 + content octets */ + seqlen = rlen + rpad + slen + spad + 4; + /* Actual encoded length: include SEQUENCE header */ + if (!out) + return seqlen + 2; + + /* Output SEQUENCE header */ + *out++ = V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED; + *out++ = (unsigned char)seqlen; + + /* Output r */ + *out++ = V_ASN1_INTEGER; + *out++ = (unsigned char)(rlen + rpad); + if (rpad) + *out++ = 0; + BN_bn2bin(sig->r, out); + out += rlen; + + /* Output s */ + *out++ = V_ASN1_INTEGER; + *out++ = (unsigned char)(slen + spad); + if (spad) + *out++ = 0; + BN_bn2bin(sig->s, out); + return seqlen + 2; + } + +/* Companion DSA_SIG decoder */ + +int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen) + { + int seqlen, rlen, slen; + const unsigned char *rbin; + /* Sanity check */ + + /* Need SEQUENCE tag */ + if (*in++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) + return 0; + /* Get length octet */ + seqlen = *in++; + /* Check sensible length value */ + if (seqlen < 4 || seqlen > 0x7F) + return 0; + /* Check INTEGER tag */ + if (*in++ != V_ASN1_INTEGER) + return 0; + rlen = *in++; + seqlen -= 2 + rlen; + /* Check sensible seqlen value */ + if (seqlen < 2) + return 0; + rbin = in; + in += rlen; + /* Check INTEGER tag */ + if (*in++ != V_ASN1_INTEGER) + return 0; + slen = *in++; + /* Remaining bytes of SEQUENCE should exactly match + * encoding of s + */ + if (seqlen != (slen + 2)) + return 0; + if (!sig->r && !(sig->r = BN_new())) + return 0; + if (!sig->s && !(sig->s = BN_new())) + return 0; + if (!BN_bin2bn(rbin, rlen, sig->r)) + return 0; + if (!BN_bin2bn(in, slen, sig->s)) + return 0; + return 1; + } + +static int fips_dsa_sign(int type, const unsigned char *x, int y, + unsigned char *sig, unsigned int *siglen, EVP_MD_SVCTX *sv) + { + DSA *dsa = sv->key; + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int dlen; + DSA_SIG *s; + EVP_DigestFinal_ex(sv->mctx, dig, &dlen); + s=dsa->meth->dsa_do_sign(dig,dlen,dsa); + OPENSSL_cleanse(dig, dlen); + if (s == NULL) + { + *siglen=0; + return 0; + } + *siglen= FIPS_dsa_sig_encode(sig, s); + DSA_SIG_free(s); + if (*siglen < 0) + return 0; + return 1; + } + +static int fips_dsa_verify(int type, const unsigned char *x, int y, + const unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv) + { + DSA *dsa = sv->key; + DSA_SIG *s; + int ret=-1; + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int dlen; + + s = DSA_SIG_new(); + if (s == NULL) + return ret; + if (!FIPS_dsa_sig_decode(s,sigbuf,siglen)) + goto err; + EVP_DigestFinal_ex(sv->mctx, dig, &dlen); + ret=dsa->meth->dsa_do_verify(dig,dlen,s,dsa); + OPENSSL_cleanse(dig, dlen); +err: + DSA_SIG_free(s); + return ret; + } + +static int init(EVP_MD_CTX *ctx) + { return SHA1_Init(ctx->md_data); } + +static int update(EVP_MD_CTX *ctx,const void *data,size_t count) + { return SHA1_Update(ctx->md_data,data,count); } + +static int final(EVP_MD_CTX *ctx,unsigned char *md) + { return SHA1_Final(md,ctx->md_data); } + +static const EVP_MD dss1_md= + { + NID_dsa, + NID_dsaWithSHA1, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init, + update, + final, + NULL, + NULL, + (evp_sign_method *)fips_dsa_sign, + (evp_verify_method *)fips_dsa_verify, + {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, EVP_PKEY_DSA4,0}, + SHA_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA_CTX), + }; + +const EVP_MD *EVP_dss1(void) + { + return(&dss1_md); + } +#endif diff --git a/fips/dsa/fips_dsatest.c b/fips/dsa/fips_dsatest.c new file mode 100644 index 0000000000..2729a98f17 --- /dev/null +++ b/fips/dsa/fips_dsatest.c @@ -0,0 +1,269 @@ +/* crypto/dsa/dsatest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include + +#include "e_os.h" + +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif + + +#if defined(OPENSSL_NO_DSA) || !defined(OPENSSL_FIPS) +int main(int argc, char *argv[]) +{ + printf("No FIPS DSA support\n"); + return(0); +} +#else +#include +#include +#include + +#ifdef OPENSSL_SYS_WIN16 +#define MS_CALLBACK _far _loadds +#else +#define MS_CALLBACK +#endif + +#include "fips_utl.h" + +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb); + +/* seed, out_p, out_q, out_g are taken from the earlier validation test + * vectors. + */ + +static unsigned char seed[20] = { + 0x1c, 0xfb, 0xa9, 0x6c, 0xf7, 0x95, 0xb3, 0x2e, 0x01, 0x01, 0x3c, 0x8d, + 0x7f, 0x6e, 0xf4, 0x59, 0xcc, 0x2f, 0x19, 0x59 + }; + +static unsigned char out_p[] = { + 0xc2, 0x3c, 0x48, 0x31, 0x7e, 0x3b, 0x4e, 0x5d, 0x3c, 0x93, 0x78, 0x60, + 0x5c, 0xf2, 0x60, 0xbb, 0x5a, 0xfa, 0x7f, 0x17, 0xf9, 0x26, 0x69, 0x46, + 0xe7, 0x07, 0xbb, 0x3b, 0x2e, 0xc4, 0xb5, 0x66, 0xf7, 0x4d, 0xae, 0x9b, + 0x8f, 0xf0, 0x42, 0xea, 0xb3, 0xa0, 0x7e, 0x81, 0x85, 0x89, 0xe6, 0xb0, + 0x29, 0x03, 0x6b, 0xcc, 0xfb, 0x8e, 0x46, 0x15, 0x4d, 0xc1, 0x69, 0xd8, + 0x2f, 0xef, 0x5c, 0x8b, 0x29, 0x32, 0x41, 0xbd, 0x13, 0x72, 0x3d, 0xac, + 0x81, 0xcc, 0x86, 0x6c, 0x06, 0x5d, 0x51, 0xa1, 0xa5, 0x07, 0x0c, 0x3e, + 0xbe, 0xdd, 0xf4, 0x6e, 0xa8, 0xed, 0xb4, 0x2f, 0xbd, 0x3e, 0x64, 0xea, + 0xee, 0x92, 0xec, 0x51, 0xe1, 0x0d, 0xab, 0x25, 0x45, 0xae, 0x55, 0x21, + 0x4d, 0xd6, 0x96, 0x6f, 0xe6, 0xaa, 0xd3, 0xca, 0x87, 0x92, 0xb1, 0x1c, + 0x3c, 0xaf, 0x29, 0x09, 0x8b, 0xc6, 0xed, 0xe1 + }; + +static unsigned char out_q[] = { + 0xae, 0x0a, 0x8c, 0xfb, 0x80, 0xe1, 0xc6, 0xd1, 0x09, 0x0f, 0x26, 0xde, + 0x91, 0x53, 0xc2, 0x8b, 0x2b, 0x0f, 0xde, 0x7f + }; + +static unsigned char out_g[] = { + 0x0d, 0x7d, 0x92, 0x74, 0x10, 0xf6, 0xa4, 0x43, 0x86, 0x9a, 0xd1, 0xd9, + 0x56, 0x00, 0xbc, 0x18, 0x97, 0x99, 0x4e, 0x9a, 0x93, 0xfb, 0x00, 0x3d, + 0x6c, 0xa0, 0x1b, 0x95, 0x6b, 0xbd, 0xf7, 0x7a, 0xbc, 0x36, 0x3f, 0x3d, + 0xb9, 0xbf, 0xf9, 0x91, 0x37, 0x68, 0xd1, 0xb9, 0x1e, 0xfe, 0x7f, 0x10, + 0xc0, 0x6a, 0xcd, 0x5f, 0xc1, 0x65, 0x1a, 0xb8, 0xe7, 0xab, 0xb5, 0xc6, + 0x8d, 0xb7, 0x86, 0xad, 0x3a, 0xbf, 0x6b, 0x7b, 0x0a, 0x66, 0xbe, 0xd5, + 0x58, 0x23, 0x16, 0x48, 0x83, 0x29, 0xb6, 0xa7, 0x64, 0xc7, 0x08, 0xbe, + 0x55, 0x4c, 0x6f, 0xcb, 0x34, 0xc1, 0x73, 0xb0, 0x39, 0x68, 0x52, 0xdf, + 0x27, 0x7f, 0x32, 0xbc, 0x2b, 0x0d, 0x63, 0xed, 0x75, 0x3e, 0xb5, 0x54, + 0xac, 0xc8, 0x20, 0x2a, 0x73, 0xe8, 0x29, 0x51, 0x03, 0x77, 0xe8, 0xc9, + 0x61, 0x32, 0x25, 0xaf, 0x21, 0x5b, 0x6e, 0xda + }; + + +static const unsigned char str1[]="12345678901234567890"; + +static const char rnd_seed[] = "string to make the random number generator think it has entropy"; + +int main(int argc, char **argv) + { + DSA *dsa=NULL; + EVP_PKEY pk; + int counter,ret=0,i,j; + unsigned int slen; + unsigned char buf[256]; + unsigned long h; + BN_GENCB cb; + EVP_MD_CTX mctx; + BN_GENCB_set(&cb, dsa_cb, stderr); + EVP_MD_CTX_init(&mctx); + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + EXIT(1); + } + + fprintf(stderr,"test generation of DSA parameters\n"); + + dsa = FIPS_dsa_new(); + DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,&cb); + + fprintf(stderr,"seed\n"); + for (i=0; i<20; i+=4) + { + fprintf(stderr,"%02X%02X%02X%02X ", + seed[i],seed[i+1],seed[i+2],seed[i+3]); + } + fprintf(stderr,"\ncounter=%d h=%ld\n",counter,h); + + if (dsa == NULL) goto end; + if (counter != 16) + { + fprintf(stderr,"counter should be 105\n"); + goto end; + } + if (h != 2) + { + fprintf(stderr,"h should be 2\n"); + goto end; + } + + i=BN_bn2bin(dsa->q,buf); + j=sizeof(out_q); + if ((i != j) || (memcmp(buf,out_q,i) != 0)) + { + fprintf(stderr,"q value is wrong\n"); + goto end; + } + + i=BN_bn2bin(dsa->p,buf); + j=sizeof(out_p); + if ((i != j) || (memcmp(buf,out_p,i) != 0)) + { + fprintf(stderr,"p value is wrong\n"); + goto end; + } + + i=BN_bn2bin(dsa->g,buf); + j=sizeof(out_g); + if ((i != j) || (memcmp(buf,out_g,i) != 0)) + { + fprintf(stderr,"g value is wrong\n"); + goto end; + } + DSA_generate_key(dsa); + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + + if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, str1, 20)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, str1, 20)) + goto end; + if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1) + goto end; + + ret = 1; + +end: + if (!ret) + do_print_errors(); + if (dsa != NULL) FIPS_dsa_free(dsa); + EVP_MD_CTX_cleanup(&mctx); +#if 0 + CRYPTO_mem_leaks(bio_err); +#endif + EXIT(!ret); + return(!ret); + } + +static int cb_exit(int ec) + { + EXIT(ec); + return(0); /* To keep some compilers quiet */ + } + +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb) + { + char c='*'; + static int ok=0,num=0; + + if (p == 0) { c='.'; num++; }; + if (p == 1) c='+'; + if (p == 2) { c='*'; ok++; } + if (p == 3) c='\n'; + fwrite(&c,1, 1, cb->arg); + fflush(cb->arg); + + if (!ok && (p == 0) && (num > 1)) + { + fprintf(cb->arg,"error in dsatest\n"); + cb_exit(1); + } + return 1; + } +#endif diff --git a/fips/dsa/fips_dssvs.c b/fips/dsa/fips_dssvs.c new file mode 100644 index 0000000000..41515e571a --- /dev/null +++ b/fips/dsa/fips_dssvs.c @@ -0,0 +1,542 @@ +#include + +#ifndef OPENSSL_FIPS +#include + +int main() +{ + printf("No FIPS DSA support\n"); + return(0); +} +#else + +#include +#include +#include +#include +#include +#include +#include + +#include "fips_utl.h" + +static void pbn(const char *name, BIGNUM *bn) + { + int len, i; + unsigned char *tmp; + len = BN_num_bytes(bn); + tmp = OPENSSL_malloc(len); + if (!tmp) + { + fprintf(stderr, "Memory allocation error\n"); + return; + } + BN_bn2bin(bn, tmp); + printf("%s = ", name); + for (i = 0; i < len; i++) + printf("%02X", tmp[i]); + fputs("\n", stdout); + OPENSSL_free(tmp); + return; + } + +void primes() + { + char buf[10240]; + char lbuf[10240]; + char *keyword, *value; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Prime")) + { + BIGNUM *pp; + + pp=BN_new(); + do_hex2bn(&pp,value); + printf("result= %c\n", + BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F'); + } + } + } + +void pqg() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"N")) + { + int n=atoi(value); + + printf("[mod = %d]\n\n",nmod); + + while(n--) + { + unsigned char seed[20]; + DSA *dsa; + int counter; + unsigned long h; + dsa = FIPS_dsa_new(); + + if (!DSA_generate_parameters_ex(dsa, nmod,seed,0,&counter,&h,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + pv("Seed",seed,20); + printf("c = %d\n",counter); + printf("H = %lx\n",h); + putc('\n',stdout); + } + } + else + fputs(buf,stdout); + } + } + +void pqgver() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + BIGNUM *p = NULL, *q = NULL, *g = NULL; + int counter, counter2; + unsigned long h, h2; + DSA *dsa=NULL; + int nmod=0; + unsigned char seed[1024]; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"P")) + p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + q=hex2bn(value); + else if(!strcmp(keyword,"G")) + g=hex2bn(value); + else if(!strcmp(keyword,"Seed")) + { + int slen = hex2bin(value, seed); + if (slen != 20) + { + fprintf(stderr, "Seed parse length error\n"); + exit (1); + } + } + else if(!strcmp(keyword,"c")) + counter =atoi(buf+4); + else if(!strcmp(keyword,"H")) + { + h = atoi(value); + if (!p || !q || !g) + { + fprintf(stderr, "Parse Error\n"); + exit (1); + } + pbn("P",p); + pbn("Q",q); + pbn("G",g); + pv("Seed",seed,20); + printf("c = %d\n",counter); + printf("H = %lx\n",h); + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL)) + { + do_print_errors(); + exit(1); + } + if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g) + || (counter != counter2) || (h != h2)) + printf("Result = F\n"); + else + printf("Result = T\n"); + BN_free(p); + BN_free(q); + BN_free(g); + p = NULL; + q = NULL; + g = NULL; + FIPS_dsa_free(dsa); + dsa = NULL; + } + } + } + +/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2 + * algorithm tests. It is an additional test to perform sanity checks on the + * output of the KeyPair test. + */ + +static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g, + BN_CTX *ctx) + { + BIGNUM *rem = NULL; + if (BN_num_bits(p) != nmod) + return 0; + if (BN_num_bits(q) != 160) + return 0; + if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1) + return 0; + if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1) + return 0; + rem = BN_new(); + if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem) + || (BN_cmp(g, BN_value_one()) <= 0) + || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) + { + BN_free(rem); + return 0; + } + /* Todo: check g */ + BN_free(rem); + return 1; + } + +void keyver() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL; + BIGNUM *Y2; + BN_CTX *ctx = NULL; + int nmod=0, paramcheck = 0; + + ctx = BN_CTX_new(); + Y2 = BN_new(); + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + if (p) + BN_free(p); + p = NULL; + if (q) + BN_free(q); + q = NULL; + if (g) + BN_free(g); + g = NULL; + paramcheck = 0; + nmod=atoi(value); + } + else if(!strcmp(keyword,"P")) + p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + q=hex2bn(value); + else if(!strcmp(keyword,"G")) + g=hex2bn(value); + else if(!strcmp(keyword,"X")) + X=hex2bn(value); + else if(!strcmp(keyword,"Y")) + { + Y=hex2bn(value); + if (!p || !q || !g || !X || !Y) + { + fprintf(stderr, "Parse Error\n"); + exit (1); + } + pbn("P",p); + pbn("Q",q); + pbn("G",g); + pbn("X",X); + pbn("Y",Y); + if (!paramcheck) + { + if (dss_paramcheck(nmod, p, q, g, ctx)) + paramcheck = 1; + else + paramcheck = -1; + } + if (paramcheck != 1) + printf("Result = F\n"); + else + { + if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y)) + printf("Result = F\n"); + else + printf("Result = T\n"); + } + BN_free(X); + BN_free(Y); + X = NULL; + Y = NULL; + } + } + if (p) + BN_free(p); + if (q) + BN_free(q); + if (g) + BN_free(g); + if (Y2) + BN_free(Y2); + } + +void keypair() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + nmod=atoi(value); + else if(!strcmp(keyword,"N")) + { + DSA *dsa; + int n=atoi(value); + + printf("[mod = %d]\n\n",nmod); + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + + while(n--) + { + if (!DSA_generate_key(dsa)) + { + do_print_errors(); + exit(1); + } + + pbn("X",dsa->priv_key); + pbn("Y",dsa->pub_key); + putc('\n',stdout); + } + } + } + } + +void siggen() + { + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + int nmod=0; + DSA *dsa=NULL; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + nmod=atoi(value); + printf("[mod = %d]\n\n",nmod); + if (dsa) + FIPS_dsa_free(dsa); + dsa = FIPS_dsa_new(); + if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) + { + do_print_errors(); + exit(1); + } + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + } + else if(!strcmp(keyword,"Msg")) + { + unsigned char msg[1024]; + unsigned char sbuf[60]; + unsigned int slen; + int n; + EVP_PKEY pk; + EVP_MD_CTX mctx; + DSA_SIG *sig; + EVP_MD_CTX_init(&mctx); + + n=hex2bin(value,msg); + pv("Msg",msg,n); + + if (!DSA_generate_key(dsa)) + { + do_print_errors(); + exit(1); + } + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + pbn("Y",dsa->pub_key); + + EVP_SignInit_ex(&mctx, EVP_dss1(), NULL); + EVP_SignUpdate(&mctx, msg, n); + EVP_SignFinal(&mctx, sbuf, &slen, &pk); + + sig = DSA_SIG_new(); + FIPS_dsa_sig_decode(sig, sbuf, slen); + + pbn("R",sig->r); + pbn("S",sig->s); + putc('\n',stdout); + DSA_SIG_free(sig); + EVP_MD_CTX_cleanup(&mctx); + } + } + if (dsa) + FIPS_dsa_free(dsa); + } + +void sigver() + { + DSA *dsa=NULL; + char buf[1024]; + char lbuf[1024]; + unsigned char msg[1024]; + char *keyword, *value; + int nmod=0, n=0; + DSA_SIG sg, *sig = &sg; + + sig->r = NULL; + sig->s = NULL; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + if (!parse_line(&keyword, &value, lbuf, buf)) + { + fputs(buf,stdout); + continue; + } + if(!strcmp(keyword,"[mod")) + { + nmod=atoi(value); + if(dsa) + FIPS_dsa_free(dsa); + dsa=FIPS_dsa_new(); + } + else if(!strcmp(keyword,"P")) + dsa->p=hex2bn(value); + else if(!strcmp(keyword,"Q")) + dsa->q=hex2bn(value); + else if(!strcmp(keyword,"G")) + { + dsa->g=hex2bn(value); + + printf("[mod = %d]\n\n",nmod); + pbn("P",dsa->p); + pbn("Q",dsa->q); + pbn("G",dsa->g); + putc('\n',stdout); + } + else if(!strcmp(keyword,"Msg")) + { + n=hex2bin(value,msg); + pv("Msg",msg,n); + } + else if(!strcmp(keyword,"Y")) + dsa->pub_key=hex2bn(value); + else if(!strcmp(keyword,"R")) + sig->r=hex2bn(value); + else if(!strcmp(keyword,"S")) + { + EVP_MD_CTX mctx; + EVP_PKEY pk; + unsigned char sigbuf[60]; + unsigned int slen; + int r; + EVP_MD_CTX_init(&mctx); + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + sig->s=hex2bn(value); + + pbn("Y",dsa->pub_key); + pbn("R",sig->r); + pbn("S",sig->s); + + slen = FIPS_dsa_sig_encode(sigbuf, sig); + EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL); + EVP_VerifyUpdate(&mctx, msg, n); + r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk); + EVP_MD_CTX_cleanup(&mctx); + + printf("Result = %c\n", r == 1 ? 'P' : 'F'); + putc('\n',stdout); + } + } + } + +int main(int argc,char **argv) + { + if(argc != 2) + { + fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]); + exit(1); + } + if(!FIPS_mode_set(1)) + { + do_print_errors(); + exit(1); + } + if(!strcmp(argv[1],"prime")) + primes(); + else if(!strcmp(argv[1],"pqg")) + pqg(); + else if(!strcmp(argv[1],"pqgver")) + pqgver(); + else if(!strcmp(argv[1],"keypair")) + keypair(); + else if(!strcmp(argv[1],"keyver")) + keyver(); + else if(!strcmp(argv[1],"siggen")) + siggen(); + else if(!strcmp(argv[1],"sigver")) + sigver(); + else + { + fprintf(stderr,"Don't know how to %s.\n",argv[1]); + exit(1); + } + + return 0; + } + +#endif diff --git a/fips/fips-lib.com b/fips/fips-lib.com new file mode 100644 index 0000000000..539117b2ed --- /dev/null +++ b/fips/fips-lib.com @@ -0,0 +1,1196 @@ +$! +$! FIPS-LIB.COM +$! Written By: Robert Byer +$! Vice-President +$! A-Com Computing, Inc. +$! byer@mail.all-net.net +$! +$! Changes by Richard Levitte +$! +$! This command files compiles and creates the FIPS parts of the +$! "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" library for OpenSSL. The "xxx" +$! denotes the machine architecture of AXP or VAX. +$! +$! It was re-written so it would try to determine what "C" compiler to use +$! or you can specify which "C" compiler to use. +$! +$! Specify the following as P1 to build just that part or ALL to just +$! build everything. +$! +$! LIBRARY To just compile the [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library. +$! APPS To just compile the [.xxx.EXE.CRYPTO]*.EXE +$! ALL To do both LIBRARY and APPS +$! +$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger +$! information. +$! +$! Specify which compiler at P3 to try to compile under. +$! +$! VAXC For VAX C. +$! DECC For DEC C. +$! GNUC For GNU C. +$! +$! If you don't speficy a compiler, it will try to determine which +$! "C" compiler to use. +$! +$! P4, if defined, sets a TCP/IP library to use, through one of the following +$! keywords: +$! +$! UCX for UCX +$! TCPIP for TCPIP (post UCX) +$! SOCKETSHR for SOCKETSHR+NETLIB +$! +$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up) +$! +$! P6, if defined, sets a choice of crypto methods to compile. +$! WARNING: this should only be done to recompile some part of an already +$! fully compiled library. +$! +$! +$! Define A TCP/IP Library That We Will Need To Link To. +$! (That Is, If We Need To Link To One.) +$! +$ TCPIP_LIB = "" +$! +$! Check Which Architecture We Are Using. +$! +$ IF (F$GETSYI("CPU").GE.128) +$ THEN +$! +$! The Architecture Is AXP +$! +$ ARCH := AXP +$! +$! Else... +$! +$ ELSE +$! +$! The Architecture Is VAX. +$! +$ ARCH := VAX +$! +$! End The Architecture Check. +$! +$ ENDIF +$! +$! Define The Different Encryption Types. +$! +$ ENCRYPT_TYPES = "Basic,SHA,RAND,DES,AES,DSA,RSA,DH,HMAC" +$! +$! Check To Make Sure We Have Valid Command Line Parameters. +$! +$ GOSUB CHECK_OPTIONS +$! +$! Initialise logical names and such +$! +$ GOSUB INITIALISE +$! +$! Tell The User What Kind of Machine We Run On. +$! +$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine." +$! +$! Define The OBJ Directory. +$! +$ OBJ_DIR := SYS$DISK:[-.'ARCH'.OBJ.CRYPTO] +$! +$! Check To See If The Architecture Specific OBJ Directory Exists. +$! +$ IF (F$PARSE(OBJ_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIR 'OBJ_DIR' +$! +$! End The Architecture Specific OBJ Directory Check. +$! +$ ENDIF +$! +$! Define The EXE Directory. +$! +$ EXE_DIR := SYS$DISK:[-.'ARCH'.EXE.CRYPTO] +$! +$! Check To See If The Architecture Specific Directory Exists. +$! +$ IF (F$PARSE(EXE_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIRECTORY 'EXE_DIR' +$! +$! End The Architecture Specific Directory Check. +$! +$ ENDIF +$! +$! Define The Library Name. +$! +$ LIB_NAME := 'EXE_DIR'LIBCRYPTO.OLB +$! +$! Define The CRYPTO-LIB We Are To Use. +$! +$ CRYPTO_LIB := 'EXE_DIR'LIBCRYPTO.OLB +$! +$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" Library... +$! +$ IF (F$SEARCH(LIB_NAME).EQS."") +$ THEN +$! +$! Guess Not, Create The Library. +$! +$ LIBRARY/CREATE/OBJECT 'LIB_NAME' +$! +$! End The Library Check. +$! +$ ENDIF +$! +$! Build our options file for the application +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Define The Different Encryption "library" Strings. +$! +$ LIB_ = "fips,fips_err_wrapper" +$ LIB_SHA = "fips_sha1dgst,fips_sha1_selftest,fips_sha256,fips_sha512" +$ LIB_RAND = "fips_rand,fips_rand_selftest" +$ LIB_DES = "fips_des_enc,fips_des_selftest,fips_set_key" +$ LIB_AES = "fips_aes_core,fips_aes_selftest" +$ LIB_DSA = "fips_dsa_ossl,fips_dsa_gen,fips_dsa_selftest" +$ LIB_RSA = "fips_rsa_eay,fips_rsa_gen,fips_rsa_selftest,fips_rsa_x931g" +$ LIB_DH = "fips_dh_check,fips_dh_gen,fips_dh_key" +$ LIB_HMAC = "fips_hmac,fips_hmac_selftest" +$! +$! Setup exceptional compilations +$! +$ ! Add definitions for no threads on OpenVMS 7.1 and higher +$ COMPILEWITH_CC3 = ",bss_rtcp," +$ ! Disable the DOLLARID warning +$ COMPILEWITH_CC4 = ",a_utctm,bss_log,o_time," +$ ! Disable disjoint optimization +$ COMPILEWITH_CC5 = ",md2_dgst,md4_dgst,md5_dgst,mdc2dgst," + - + "sha_dgst,sha1dgst,rmd_dgst,bf_enc," +$ ! Disable the MIXLINKAGE warning +$ COMPILEWITH_CC6 = ",fips_set_key," +$! +$! Figure Out What Other Modules We Are To Build. +$! +$ BUILD_SET: +$! +$! Define A Module Counter. +$! +$ MODULE_COUNTER = 0 +$! +$! Top Of The Loop. +$! +$ MODULE_NEXT: +$! +$! Extract The Module Name From The Encryption List. +$! +$ MODULE_NAME = F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES) +$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = "" +$ MODULE_NAME1 = MODULE_NAME +$! +$! Check To See If We Are At The End Of The Module List. +$! +$ IF (MODULE_NAME.EQS.",") +$ THEN +$! +$! We Are At The End Of The Module List, Go To MODULE_DONE. +$! +$ GOTO MODULE_DONE +$! +$! End The Module List Check. +$! +$ ENDIF +$! +$! Increment The Moudle Counter. +$! +$ MODULE_COUNTER = MODULE_COUNTER + 1 +$! +$! Create The Library and Apps Module Names. +$! +$ LIB_MODULE = "LIB_" + MODULE_NAME +$ APPS_MODULE = "APPS_" + MODULE_NAME +$ IF (MODULE_NAME.EQS."ASN1_2") +$ THEN +$ MODULE_NAME = "ASN1" +$ ENDIF +$ IF (MODULE_NAME.EQS."EVP_2") +$ THEN +$ MODULE_NAME = "EVP" +$ ENDIF +$! +$! Set state (can be LIB and APPS) +$! +$ STATE = "LIB" +$ IF BUILDALL .EQS. "APPS" THEN STATE = "APPS" +$! +$! Check if the library module name actually is defined +$! +$ IF F$TYPE('LIB_MODULE') .EQS. "" +$ THEN +$ WRITE SYS$ERROR "" +$ WRITE SYS$ERROR "The module ",MODULE_NAME," does not exist. Continuing..." +$ WRITE SYS$ERROR "" +$ GOTO MODULE_NEXT +$ ENDIF +$! +$! Top Of The Module Loop. +$! +$ MODULE_AGAIN: +$! +$! Tell The User What Module We Are Building. +$! +$ IF (MODULE_NAME1.NES."") +$ THEN +$ IF STATE .EQS. "LIB" +$ THEN +$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Library Files. (",BUILDALL,",",STATE,")" +$ ELSE IF F$TYPE('APPS_MODULE') .NES. "" +$ THEN +$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Applications. (",BUILDALL,",",STATE,")" +$ ENDIF +$ ENDIF +$ ENDIF +$! +$! Define A File Counter And Set It To "0". +$! +$ FILE_COUNTER = 0 +$ APPLICATION = "" +$ APPLICATION_COUNTER = 0 +$! +$! Top Of The File Loop. +$! +$ NEXT_FILE: +$! +$! Look in the LIB_MODULE is we're in state LIB +$! +$ IF STATE .EQS. "LIB" +$ THEN +$! +$! O.K, Extract The File Name From The File List. +$! +$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE') +$! +$! else +$! +$ ELSE +$ FILE_NAME = "," +$! +$ IF F$TYPE('APPS_MODULE') .NES. "" +$ THEN +$! +$! Extract The File Name From The File List. +$! This part is a bit more complicated. +$! +$ IF APPLICATION .EQS. "" +$ THEN +$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE') +$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1 +$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION) +$ APPLICATION = F$ELEMENT(0,"/",APPLICATION) +$ FILE_COUNTER = 0 +$ ENDIF +$ +$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*" +$! SHOW SYMBOL APPLICATION* +$! +$ IF APPLICATION .NES. ";" +$ THEN +$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS) +$ IF FILE_NAME .EQS. "," +$ THEN +$ APPLICATION = "" +$ GOTO NEXT_FILE +$ ENDIF +$ ENDIF +$ ENDIF +$ ENDIF +$! +$! Check To See If We Are At The End Of The File List. +$! +$ IF (FILE_NAME.EQS.",") +$ THEN +$! +$! We Are At The End Of The File List, Change State Or Goto FILE_DONE. +$! +$ IF STATE .EQS. "LIB" .AND. BUILDALL .NES. "LIBRARY" +$ THEN +$ STATE = "APPS" +$ GOTO MODULE_AGAIN +$ ELSE +$ GOTO FILE_DONE +$ ENDIF +$! +$! End The File List Check. +$! +$ ENDIF +$! +$! Increment The Counter. +$! +$ FILE_COUNTER = FILE_COUNTER + 1 +$! +$! Create The Source File Name. +$! +$ TMP_FILE_NAME = F$ELEMENT(1,"]",FILE_NAME) +$ IF TMP_FILE_NAME .EQS. "]" THEN TMP_FILE_NAME = FILE_NAME +$ IF F$ELEMENT(0,".",TMP_FILE_NAME) .EQS. TMP_FILE_NAME THEN - + FILE_NAME = FILE_NAME + ".c" +$ IF (MODULE_NAME.NES."") +$ THEN +$ SOURCE_FILE = "SYS$DISK:[." + MODULE_NAME+ "]" + FILE_NAME +$ ELSE +$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME +$ ENDIF +$ SOURCE_FILE = SOURCE_FILE - "][" +$! +$! Create The Object File Name. +$! +$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ" +$ ON WARNING THEN GOTO NEXT_FILE +$! +$! Check To See If The File We Want To Compile Is Actually There. +$! +$ IF (F$SEARCH(SOURCE_FILE).EQS."") +$ THEN +$! +$! Tell The User That The File Doesn't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ GOTO EXIT +$! +$! End The File Exist Check. +$! +$ ENDIF +$! +$! Tell The User We Are Compiling The File. +$! +$ IF (MODULE_NAME.EQS."") +$ THEN +$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME," File. (",BUILDALL,",",STATE,")" +$ ENDIF +$ IF (MODULE_NAME.NES."") +$ THEN +$ WRITE SYS$OUTPUT " ",FILE_NAME,"" +$ ENDIF +$! +$! Compile The File. +$! +$ ON ERROR THEN GOTO NEXT_FILE +$ FILE_NAME0 = F$ELEMENT(0,".",FILE_NAME) +$ IF FILE_NAME - ".mar" .NES. FILE_NAME +$ THEN +$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF COMPILEWITH_CC3 - FILE_NAME0 .NES. COMPILEWITH_CC3 +$ THEN +$ CC3/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF COMPILEWITH_CC4 - FILE_NAME0 .NES. COMPILEWITH_CC4 +$ THEN +$ CC4/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5 +$ THEN +$ CC5/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF COMPILEWITH_CC6 - FILE_NAME0 .NES. COMPILEWITH_CC6 +$ THEN +$ CC6/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ENDIF +$ ENDIF +$ ENDIF +$ ENDIF +$ ENDIF +$ IF STATE .EQS. "LIB" +$ THEN +$! +$! Add It To The Library. +$! +$ LIBRARY/REPLACE 'LIB_NAME' 'OBJECT_FILE' +$! +$! Time To Clean Up The Object File. +$! +$ DELETE 'OBJECT_FILE';* +$ ENDIF +$! +$! Go Back And Do It Again. +$! +$ GOTO NEXT_FILE +$! +$! All Done With This Library Part. +$! +$ FILE_DONE: +$! +$! Time To Build Some Applications +$! +$ IF F$TYPE('APPS_MODULE') .NES. "" .AND. BUILDALL .NES. "LIBRARY" +$ THEN +$ APPLICATION_COUNTER = 0 +$ NEXT_APPLICATION: +$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE') +$ IF APPLICATION .EQS. ";" THEN GOTO APPLICATION_DONE +$ +$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1 +$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION) +$ APPLICATION = F$ELEMENT(0,"/",APPLICATION) +$ +$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*" +$! SHOW SYMBOL APPLICATION* +$! +$! Tell the user what happens +$! +$ WRITE SYS$OUTPUT " ",APPLICATION,".exe" +$! +$! Link The Program. +$! +$ ON ERROR THEN GOTO NEXT_APPLICATION +$! +$! Check To See If We Are To Link With A Specific TCP/IP Library. +$! +$ IF (TCPIP_LIB.NES."") +$ THEN +$! +$! Link With A TCP/IP Library. +$! +$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR''APPLICATION'.EXE - + 'OBJ_DIR''APPLICATION_OBJECTS', - + 'CRYPTO_LIB'/LIBRARY, - + 'TCPIP_LIB','OPT_FILE'/OPTION +$! +$! Else... +$! +$ ELSE +$! +$! Don't Link With A TCP/IP Library. +$! +$ LINK/'DEBUGGER'/'TRACEBACK'/EXE='EXE_DIR''APPLICATION'.EXE - + 'OBJ_DIR''APPLICATION_OBJECTS',- + 'CRYPTO_LIB'/LIBRARY, - + 'OPT_FILE'/OPTION +$! +$! End The TCP/IP Library Check. +$! +$ ENDIF +$ GOTO NEXT_APPLICATION +$ APPLICATION_DONE: +$ ENDIF +$! +$! Go Back And Get The Next Module. +$! +$ GOTO MODULE_NEXT +$! +$! All Done With This Module. +$! +$ MODULE_DONE: +$! +$! Tell The User That We Are All Done. +$! +$ WRITE SYS$OUTPUT "All Done..." +$ EXIT: +$ GOSUB CLEANUP +$ EXIT +$! +$! Check For The Link Option FIle. +$! +$ CHECK_OPT_FILE: +$! +$! Check To See If We Need To Make A VAX C Option File. +$! +$ IF (COMPILER.EQS."VAXC") +$ THEN +$! +$! Check To See If We Already Have A VAX C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A VAX C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Agianst +! The Sharable VAX C Runtime Library. +! +SYS$SHARE:VAXCRTL.EXE/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The VAXC Check. +$! +$ ENDIF +$! +$! Check To See If We Need A GNU C Option File. +$! +$ IF (COMPILER.EQS."GNUC") +$ THEN +$! +$! Check To See If We Already Have A GNU C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A GNU C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Agianst +! The Sharable C Runtime Library. +! +GNU_CC:[000000]GCCLIB/LIBRARY +SYS$SHARE:VAXCRTL/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Check To See If We Need A DEC C Option File. +$! +$ IF (COMPILER.EQS."DECC") +$ THEN +$! +$! Check To See If We Already Have A DEC C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! Figure Out If We Need An AXP Or A VAX Linker Option File. +$! +$ IF ARCH .EQS. "VAX" +$ THEN +$! +$! We Need A DEC C Linker Option File For VAX. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Agianst +! The Sharable DEC C Runtime Library. +! +SYS$SHARE:DECC$SHR.EXE/SHARE +$EOD +$! +$! Else... +$! +$ ELSE +$! +$! Create The AXP Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File For AXP To Link Agianst +! The Sharable C Runtime Library. +! +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE +SYS$SHARE:CMA$OPEN_RTL/SHARE +$EOD +$! +$! End The VAX/AXP DEC C Option File Check. +$! +$ ENDIF +$! +$! End The Option File Search. +$! +$ ENDIF +$! +$! End The DEC C Check. +$! +$ ENDIF +$! +$! Tell The User What Linker Option File We Are Using. +$! +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"." +$! +$! Time To RETURN. +$! +$ RETURN +$! +$! Check The User's Options. +$! +$ CHECK_OPTIONS: +$! +$! Check To See If P1 Is Blank. +$! +$ IF (P1.EQS."ALL") +$ THEN +$! +$! P1 Is Blank, So Build Everything. +$! +$ BUILDALL = "TRUE" +$! +$! Else... +$! +$ ELSE +$! +$! Else, Check To See If P1 Has A Valid Arguement. +$! +$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."APPS") +$ THEN +$! +$! A Valid Arguement. +$! +$ BUILDALL = P1 +$! +$! Else... +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " ALL : Just Build Everything." +$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library." +$ WRITE SYS$OUTPUT " APPS : To Compile Just The [.xxx.EXE.CRYPTO]*.EXE Programs." +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " AXP : Alpha Architecture." +$ WRITE SYS$OUTPUT " VAX : VAX Architecture." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Arguement Check. +$! +$ ENDIF +$! +$! End The P1 Check. +$! +$ ENDIF +$! +$! Check To See If P2 Is Blank. +$! +$ IF (P2.EQS."NODEBUG") +$ THEN +$! +$! P2 Is NODEBUG, So Compile Without The Debugger Information. +$! +$ DEBUGGER = "NODEBUG" +$ TRACEBACK = "NOTRACEBACK" +$ GCC_OPTIMIZE = "OPTIMIZE" +$ CC_OPTIMIZE = "OPTIMIZE" +$ MACRO_OPTIMIZE = "OPTIMIZE" +$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization." +$ ELSE +$! +$! Check To See If We Are To Compile With Debugger Information. +$! +$ IF (P2.EQS."DEBUG") +$ THEN +$! +$! Compile With Debugger Information. +$! +$ DEBUGGER = "DEBUG" +$ TRACEBACK = "TRACEBACK" +$ GCC_OPTIMIZE = "NOOPTIMIZE" +$ CC_OPTIMIZE = "NOOPTIMIZE" +$ MACRO_OPTIMIZE = "NOOPTIMIZE" +$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization." +$ ELSE +$! +$! They Entered An Invalid Option.. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information." +$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Arguement Check. +$! +$ ENDIF +$! +$! End The P2 Check. +$! +$ ENDIF +$! +$! Special Threads For OpenVMS v7.1 Or Later +$! +$! Written By: Richard Levitte +$! richard@levitte.org +$! +$! +$! Check To See If We Have A Option For P5. +$! +$ IF (P5.EQS."") +$ THEN +$! +$! Get The Version Of VMS We Are Using. +$! +$ ISSEVEN := +$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION"))) +$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP)) +$! +$! Check To See If The VMS Version Is v7.1 Or Later. +$! +$ IF (TMP.GE.71) +$ THEN +$! +$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads. +$! +$ ISSEVEN := ,PTHREAD_USE_D4 +$! +$! End The VMS Version Check. +$! +$ ENDIF +$! +$! End The P5 Check. +$! +$ ENDIF +$! +$! Check To See If P3 Is Blank. +$! +$ IF (P3.EQS."") +$ THEN +$! +$! O.K., The User Didn't Specify A Compiler, Let's Try To +$! Find Out Which One To Use. +$! +$! Check To See If We Have GNU C. +$! +$ IF (F$TRNLNM("GNU_CC").NES."") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ P3 = "GNUC" +$! +$! Else... +$! +$ ELSE +$! +$! Check To See If We Have VAXC Or DECC. +$! +$ IF (ARCH.EQS."AXP").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ P3 = "DECC" +$! +$! Else... +$! +$ ELSE +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ P3 = "VAXC" +$! +$! End The VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The DECC & VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The Compiler Check. +$! +$ ENDIF +$! +$! Check To See If We Have A Option For P4. +$! +$ IF (P4.EQS."") +$ THEN +$! +$! Find out what socket library we have available +$! +$ IF F$PARSE("SOCKETSHR:") .NES. "" +$ THEN +$! +$! We have SOCKETSHR, and it is my opinion that it's the best to use. +$! +$ P4 = "SOCKETSHR" +$! +$! Tell the user +$! +$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP" +$! +$! Else, let's look for something else +$! +$ ELSE +$! +$! Like UCX (the reason to do this before Multinet is that the UCX +$! emulation is easier to use...) +$! +$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" - + .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" - + .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. "" +$ THEN +$! +$! Last resort: a UCX or UCX-compatible library +$! +$ P4 = "UCX" +$! +$! Tell the user +$! +$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP" +$! +$! That was all... +$! +$ ENDIF +$ ENDIF +$ ENDIF +$! +$! Set Up Initial CC Definitions, Possibly With User Ones +$! +$ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS" +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS +$ CCEXTRAFLAGS = "" +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS +$ CCDISABLEWARNINGS = "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR" +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN - + CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," + USER_CCDISABLEWARNINGS +$! +$! Check To See If The User Entered A Valid Paramter. +$! +$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC") +$ THEN +$! +$! Check To See If The User Wanted DECC. +$! +$ IF (P3.EQS."DECC") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ COMPILER = "DECC" +$! +$! Tell The User We Are Using DECC. +$! +$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler." +$! +$! Use DECC... +$! +$ CC = "CC" +$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" - + THEN CC = "CC/DECC" +$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + - + "/NOLIST/PREFIX=ALL" + - + "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + - + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "SYS$DISK:[]VAX_DECC_OPTIONS.OPT" +$! +$! End DECC Check. +$! +$ ENDIF +$! +$! Check To See If We Are To Use VAXC. +$! +$ IF (P3.EQS."VAXC") +$ THEN +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ COMPILER = "VAXC" +$! +$! Tell The User We Are Using VAX C. +$! +$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler." +$! +$! Compile Using VAXC. +$! +$ CC = "CC" +$ IF ARCH.EQS."AXP" +$ THEN +$ WRITE SYS$OUTPUT "There is no VAX C on Alpha!" +$ EXIT +$ ENDIF +$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC" +$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - + "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + - + CCEXTRAFLAGS +$ CCDEFS = """VAXC""," + CCDEFS +$! +$! Define As SYS$COMMON:[SYSLIB] +$! +$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB] +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "SYS$DISK:[]VAX_VAXC_OPTIONS.OPT" +$! +$! End VAXC Check +$! +$ ENDIF +$! +$! Check To See If We Are To Use GNU C. +$! +$ IF (P3.EQS."GNUC") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ COMPILER = "GNUC" +$! +$! Tell The User We Are Using GNUC. +$! +$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler." +$! +$! Use GNU C... +$! +$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - + "/INCLUDE=(SYS$DISK:[],SYS$DISK:[-],SYS$DISK:[-.CRYPTO])" + - + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "SYS$DISK:[]VAX_GNUC_OPTIONS.OPT" +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Set up default defines +$! +$ CCDEFS = """FLAT_INC=1""," + CCDEFS +$! +$! Finish up the definition of CC. +$! +$ IF COMPILER .EQS. "DECC" +$ THEN +$ IF CCDISABLEWARNINGS .EQS. "" +$ THEN +$ CC4DISABLEWARNINGS = "DOLLARID" +$ CC6DISABLEWARNINGS = "MIXLINKAGE" +$ ELSE +$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID" +$ CC6DISABLEWARNINGS = CCDISABLEWARNINGS + ",MIXLINKAGE" +$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))" +$ ENDIF +$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))" +$ CC6DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC6DISABLEWARNINGS + "))" +$ ELSE +$ CCDISABLEWARNINGS = "" +$ CC4DISABLEWARNINGS = "" +$ CC6DISABLEWARNINGS = "" +$ ENDIF +$ CC3 = CC + "/DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS +$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS +$ IF ARCH .EQS. "VAX" .AND. COMPILER .EQS. "DECC" .AND. P2 .NES. "DEBUG" +$ THEN +$ CC5 = CC + "/OPTIMIZE=NODISJOINT" +$ ELSE +$ CC5 = CC + "/NOOPTIMIZE" +$ ENDIF +$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS +$ CC6 = CC - CCDISABLEWARNINGS + CC6DISABLEWARNINGS +$! +$! Show user the result +$! +$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC +$! +$! Else The User Entered An Invalid Arguement. +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C." +$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C." +$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Arguement Check. +$! +$ ENDIF +$! +$! Build a MACRO command for the architecture at hand +$! +$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'" +$ IF ARCH .EQS. "AXP" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'" +$! +$! Show user the result +$! +$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO +$! +$! Time to check the contents, and to make sure we get the correct library. +$! +$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" - + .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE" +$ THEN +$! +$! Check to see if SOCKETSHR was chosen +$! +$ IF P4.EQS."SOCKETSHR" +$ THEN +$! +$! Set the library to use SOCKETSHR +$! +$ TCPIP_LIB = "SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT/OPT" +$! +$! Done with SOCKETSHR +$! +$ ENDIF +$! +$! Check to see if MULTINET was chosen +$! +$ IF P4.EQS."MULTINET" +$ THEN +$! +$! Set the library to use UCX emulation. +$! +$ P4 = "UCX" +$! +$! Done with MULTINET +$! +$ ENDIF +$! +$! Check to see if UCX was chosen +$! +$ IF P4.EQS."UCX" +$ THEN +$! +$! Set the library to use UCX. +$! +$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT/OPT" +$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" +$ THEN +$ TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT/OPT" +$ ELSE +$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN - + TCPIP_LIB = "SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT/OPT" +$ ENDIF +$! +$! Done with UCX +$! +$ ENDIF +$! +$! Check to see if TCPIP was chosen +$! +$ IF P4.EQS."TCPIP" +$ THEN +$! +$! Set the library to use TCPIP (post UCX). +$! +$ TCPIP_LIB = "SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT/OPT" +$! +$! Done with TCPIP +$! +$ ENDIF +$! +$! Check to see if NONE was chosen +$! +$ IF P4.EQS."NONE" +$ THEN +$! +$! Do not use a TCPIP library. +$! +$ TCPIP_LIB = "" +$! +$! Done with TCPIP +$! +$ ENDIF +$! +$! Print info +$! +$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB +$! +$! Else The User Entered An Invalid Arguement. +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library." +$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library." +$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! Done with TCP/IP libraries +$! +$ ENDIF +$! +$! Check if the user wanted to compile just a subset of all the encryption +$! methods. +$! +$ IF P6 .NES. "" +$ THEN +$ ENCRYPT_TYPES = P6 +$ ENDIF +$! +$! Time To RETURN... +$! +$ RETURN +$! +$ INITIALISE: +$! +$! Save old value of the logical name OPENSSL +$! +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE") +$! +$! Save directory information +$! +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;" +$ __HERE = F$EDIT(__HERE,"UPCASE") +$ __TOP = __HERE - "FIPS-1_0]" +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]" +$! +$! Set up the logical name OPENSSL to point at the include directory +$! +$ DEFINE OPENSSL/NOLOG '__INCLUDE' +$! +$! Done +$! +$ RETURN +$! +$ CLEANUP: +$! +$! Restore the logical name OPENSSL if it had a value +$! +$ IF __SAVE_OPENSSL .EQS. "" +$ THEN +$ DEASSIGN OPENSSL +$ ELSE +$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL' +$ ENDIF +$! +$! Done +$! +$ RETURN diff --git a/fips/fips-nodiff.txt b/fips/fips-nodiff.txt new file mode 100644 index 0000000000..fb2944b4fc --- /dev/null +++ b/fips/fips-nodiff.txt @@ -0,0 +1,7 @@ +KeyPair.rsp +PQGGen.rsp +SigGen.rsp +SigGen15.rsp +SigGenPSS.rsp +SigGenRSA.rsp +SigGenPSS.rsp diff --git a/fips/fips.c b/fips/fips.c new file mode 100644 index 0000000000..7dcc34403f --- /dev/null +++ b/fips/fips.c @@ -0,0 +1,519 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +#include + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +static int fips_selftest_fail; +static int fips_mode; +static const void *fips_rand_check; + +static void fips_set_mode(int onoff) + { + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_w_lock(); + fips_mode = onoff; + if (!owning_thread) fips_w_unlock(); + } + } + +static void fips_set_rand_check(const void *rand_check) + { + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_w_lock(); + fips_rand_check = rand_check; + if (!owning_thread) fips_w_unlock(); + } + } + +int FIPS_mode(void) + { + int ret = 0; + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_r_lock(); + ret = fips_mode; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +const void *FIPS_rand_check(void) + { + const void *ret = 0; + int owning_thread = fips_is_owning_thread(); + + if (fips_is_started()) + { + if (!owning_thread) fips_r_lock(); + ret = fips_rand_check; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +int FIPS_selftest_failed(void) + { + int ret = 0; + if (fips_is_started()) + { + int owning_thread = fips_is_owning_thread(); + + if (!owning_thread) fips_r_lock(); + ret = fips_selftest_fail; + if (!owning_thread) fips_r_unlock(); + } + return ret; + } + +/* Selftest failure fatal exit routine. This will be called + * during *any* cryptographic operation. It has the minimum + * overhead possible to avoid too big a performance hit. + */ + +void FIPS_selftest_check(void) + { + if (fips_selftest_fail) + { + OpenSSLDie(__FILE__,__LINE__, "FATAL FIPS SELFTEST FAILURE"); + } + } + +void fips_set_selftest_fail(void) + { + fips_selftest_fail = 1; + } + +int FIPS_selftest() + { + + return FIPS_selftest_sha1() + && FIPS_selftest_hmac() + && FIPS_selftest_aes() + && FIPS_selftest_des() + && FIPS_selftest_rsa() + && FIPS_selftest_dsa(); + } + +extern const void *FIPS_text_start(), *FIPS_text_end(); +extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[]; +unsigned char FIPS_signature [20] = { 0 }; +static const char FIPS_hmac_key[]="etaonrishdlcupfm"; + +unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len) + { + const unsigned char *p1 = FIPS_text_start(); + const unsigned char *p2 = FIPS_text_end(); + const unsigned char *p3 = FIPS_rodata_start; + const unsigned char *p4 = FIPS_rodata_end; + HMAC_CTX c; + + HMAC_CTX_init(&c); + HMAC_Init(&c,FIPS_hmac_key,strlen(FIPS_hmac_key),EVP_sha1()); + + /* detect overlapping regions */ + if (p1<=p3 && p2>=p3) + p3=p1, p4=p2>p4?p2:p4, p1=NULL, p2=NULL; + else if (p3<=p1 && p4>=p1) + p3=p3, p4=p2>p4?p2:p4, p1=NULL, p2=NULL; + + if (p1) + HMAC_Update(&c,p1,(size_t)p2-(size_t)p1); + + if (FIPS_signature>=p3 && FIPS_signature=FIPS_rodata_start && FIPS_signaturetype == EVP_PKEY_RSA) + && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp))) + { + sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa)); + if (!sig) + { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (tbslen == -1) + tbslen = strlen((char *)tbs); + + if (md_flags) + M_EVP_MD_CTX_set_flags(&mctx, md_flags); + + if (!EVP_SignInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_SignUpdate(&mctx, tbs, tbslen)) + goto error; + if (!EVP_SignFinal(&mctx, sig, &siglen, pkey)) + goto error; + + if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) + goto error; + + if (!EVP_VerifyInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_VerifyUpdate(&mctx, tbs, tbslen)) + goto error; + ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey); + + error: + if (sig != sigtmp) + OPENSSL_free(sig); + EVP_MD_CTX_cleanup(&mctx); + if (ret != 1) + { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE); + if (fail_str) + ERR_add_error_data(2, "Type=", fail_str); + return 0; + } + return 1; + } + +/* Generalized symmetric cipher test routine. Encrypt data, verify result + * against known answer, decrypt and compare with original plaintext. + */ + +int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len) + { + unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; + unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; + OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0) + return 0; + EVP_Cipher(ctx, citmp, plaintext, len); + if (memcmp(citmp, ciphertext, len)) + return 0; + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0) + return 0; + EVP_Cipher(ctx, pltmp, citmp, len); + if (memcmp(pltmp, plaintext, len)) + return 0; + return 1; + } + +#if 0 +/* The purpose of this is to ensure the error code exists and the function + * name is to keep the error checking script quiet + */ +void hash_final(void) + { + FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); + } +#endif + + +#endif diff --git a/fips/fips.h b/fips/fips.h new file mode 100644 index 0000000000..42bdcf2596 --- /dev/null +++ b/fips/fips.h @@ -0,0 +1,163 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#ifndef OPENSSL_FIPS +#error FIPS is disabled. +#endif + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +struct dsa_st; +struct evp_pkey_st; +struct env_md_st; +struct evp_cipher_st; +struct evp_cipher_ctx_st; + +int FIPS_mode_set(int onoff); +int FIPS_mode(void); +const void *FIPS_rand_check(void); +int FIPS_selftest_failed(void); +void FIPS_selftest_check(void); +void FIPS_corrupt_sha1(void); +int FIPS_selftest_sha1(void); +void FIPS_corrupt_aes(void); +int FIPS_selftest_aes(void); +void FIPS_corrupt_des(void); +int FIPS_selftest_des(void); +void FIPS_corrupt_rsa(void); +void FIPS_corrupt_rsa_keygen(void); +int FIPS_selftest_rsa(void); +void FIPS_corrupt_dsa(void); +void FIPS_corrupt_dsa_keygen(void); +int FIPS_selftest_dsa(void); +void FIPS_corrupt_rng(void); +void FIPS_rng_stick(void); +int FIPS_selftest_rng(void); +int FIPS_selftest_hmac(void); + +int fips_pkey_signature_test(struct evp_pkey_st *pkey, + const unsigned char *tbs, int tbslen, + const unsigned char *kat, unsigned int katlen, + const struct env_md_st *digest, unsigned int md_flags, + const char *fail_str); + +int fips_cipher_test(struct evp_cipher_ctx_st *ctx, + const struct evp_cipher_st *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, + int len); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_FIPS_strings(void); + +/* Error codes for the FIPS functions. */ + +/* Function codes. */ +#define FIPS_F_DH_BUILTIN_GENPARAMS 100 +#define FIPS_F_DSA_BUILTIN_PARAMGEN 101 +#define FIPS_F_DSA_DO_SIGN 102 +#define FIPS_F_DSA_DO_VERIFY 103 +#define FIPS_F_EVP_CIPHERINIT_EX 124 +#define FIPS_F_EVP_DIGESTINIT_EX 125 +#define FIPS_F_FIPS_CHECK_DSA 104 +#define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT 105 +#define FIPS_F_FIPS_CHECK_RSA 106 +#define FIPS_F_FIPS_DSA_CHECK 107 +#define FIPS_F_FIPS_MODE_SET 108 +#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109 +#define FIPS_F_FIPS_SELFTEST_AES 110 +#define FIPS_F_FIPS_SELFTEST_DES 111 +#define FIPS_F_FIPS_SELFTEST_DSA 112 +#define FIPS_F_FIPS_SELFTEST_HMAC 113 +#define FIPS_F_FIPS_SELFTEST_RNG 114 +#define FIPS_F_FIPS_SELFTEST_SHA1 115 +#define FIPS_F_HASH_FINAL 123 +#define FIPS_F_RSA_BUILTIN_KEYGEN 116 +#define FIPS_F_RSA_EAY_PRIVATE_DECRYPT 117 +#define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT 118 +#define FIPS_F_RSA_EAY_PUBLIC_DECRYPT 119 +#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT 120 +#define FIPS_F_RSA_X931_GENERATE_KEY_EX 121 +#define FIPS_F_SSLEAY_RAND_BYTES 122 + +/* Reason codes. */ +#define FIPS_R_CANNOT_READ_EXE 103 +#define FIPS_R_CANNOT_READ_EXE_DIGEST 104 +#define FIPS_R_CONTRADICTING_EVIDENCE 114 +#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH 105 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH 110 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111 +#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112 +#define FIPS_R_FIPS_MODE_ALREADY_SET 102 +#define FIPS_R_FIPS_SELFTEST_FAILED 106 +#define FIPS_R_INVALID_KEY_LENGTH 109 +#define FIPS_R_KEY_TOO_SHORT 108 +#define FIPS_R_NON_FIPS_METHOD 100 +#define FIPS_R_PAIRWISE_TEST_FAILED 107 +#define FIPS_R_RSA_DECRYPT_ERROR 115 +#define FIPS_R_RSA_ENCRYPT_ERROR 116 +#define FIPS_R_SELFTEST_FAILED 101 +#define FIPS_R_TEST_FAILURE 117 +#define FIPS_R_UNSUPPORTED_PLATFORM 113 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/fips/fips_canister.c b/fips/fips_canister.c new file mode 100644 index 0000000000..64580694c4 --- /dev/null +++ b/fips/fips_canister.c @@ -0,0 +1,186 @@ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution + * and usage in source and binary forms are granted according to the + * OpenSSL license. + */ + +#include +#if defined(__DECC) +# include +# pragma __nostandard +#endif + +#include "e_os.h" + +#if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION) +# if (defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \ + (defined(__sgi) && (defined(__mips) || defined(mips))) || \ + (defined(__osf__) && defined(__alpha)) || \ + (defined(__linux) && (defined(__arm) || defined(__arm__))) || \ + (defined(__i386) || defined(__i386__)) || \ + (defined(__x86_64) || defined(__x86_64__)) || \ + (defined(vax) || defined(__vax__)) +# define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION +# endif +#endif + +#if defined(__xlC__) && __xlC__>=0x600 && (defined(_POWER) || defined(_ARCH_PPC)) +static void *instruction_pointer_xlc(void); +# pragma mc_func instruction_pointer_xlc {\ + "7c0802a6" /* mflr r0 */ \ + "48000005" /* bl $+4 */ \ + "7c6802a6" /* mflr r3 */ \ + "7c0803a6" /* mtlr r0 */ } +# pragma reg_killed_by instruction_pointer_xlc gr0 gr3 +# define INSTRUCTION_POINTER_IMPLEMENTED(ret) (ret=instruction_pointer_xlc()); +#endif + +#ifdef FIPS_START +#define FIPS_ref_point FIPS_text_start +/* Some compilers put string literals into a separate segment. As we + * are mostly interested to hash AES tables in .rodata, we declare + * reference points accordingly. In case you wonder, the values are + * big-endian encoded variable names, just to prevent these arrays + * from being merged by linker. */ +const unsigned int FIPS_rodata_start[]= + { 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 }; +#else +#define FIPS_ref_point FIPS_text_end +const unsigned int FIPS_rodata_end[]= + { 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b }; +#endif + +/* + * I declare reference function as static in order to avoid certain + * pitfalls in -dynamic linker behaviour... + */ +static void *instruction_pointer(void) +{ void *ret=NULL; +/* These are ABI-neutral CPU-specific snippets. ABI-neutrality means + * that they are designed to work under any OS running on particular + * CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in + * this function. */ +#if defined(INSTRUCTION_POINTER_IMPLEMENTED) + INSTRUCTION_POINTER_IMPLEMENTED(ret); +#elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__alpha) || defined(__alpha__) +# define INSTRUCTION_POINTER_IMPLEMENTED + __asm __volatile ( "br %0,1f\n1:" : "=r"(ret) ); +# elif defined(__i386) || defined(__i386__) +# define INSTRUCTION_POINTER_IMPLEMENTED + __asm __volatile ( "call 1f\n1: popl %0" : "=r"(ret) ); + ret = (void *)((size_t)ret&~3UL); /* align for better performance */ +# elif defined(__ia64) || defined(__ia64__) +# define INSTRUCTION_POINTER_IMPLEMENTED + __asm __volatile ( "mov %0=ip" : "=r"(ret) ); +# elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc) +# define INSTRUCTION_POINTER_IMPLEMENTED + __asm __volatile ( "blr %%r0,%0\n\tnop" : "=r"(ret) ); + ret = (void *)((size_t)ret&~3UL); /* mask privilege level */ +# elif defined(__mips) || defined(__mips__) +# define INSTRUCTION_POINTER_IMPLEMENTED + void *scratch; + __asm __volatile ( "move %1,$31\n\t" /* save ra */ + "bal .+8; nop\n\t" + "move %0,$31\n\t" + "move $31,%1" /* restore ra */ + : "=r"(ret),"=r"(scratch) ); +# elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \ + defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \ + defined(__PPC64__) || defined(__powerpc64__) +# define INSTRUCTION_POINTER_IMPLEMENTED + void *scratch; + __asm __volatile ( "mfspr %1,8\n\t" /* save lr */ + "bl $+4\n\t" + "mfspr %0,8\n\t" /* mflr ret */ + "mtspr 8,%1" /* restore lr */ + : "=r"(ret),"=r"(scratch) ); +# elif defined(__s390__) || defined(__s390x__) +# define INSTRUCTION_POINTER_IMPLEMENTED + __asm __volatile ( "bras %0,1f\n1:" : "=r"(ret) ); + ret = (void *)((size_t)ret&~3UL); +# elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9) +# define INSTRUCTION_POINTER_IMPLEMENTED + void *scratch; + __asm __volatile ( "mov %%o7,%1\n\t" + "call .+8; nop\n\t" + "mov %%o7,%0\n\t" + "mov %1,%%o7" + : "=r"(ret),"=r"(scratch) ); +# elif defined(__x86_64) || defined(__x86_64__) +# define INSTRUCTION_POINTER_IMPLEMENTED + __asm __volatile ( "leaq 0(%%rip),%0" : "=r"(ret) ); + ret = (void *)((size_t)ret&~3UL); /* align for better performance */ +# endif +#elif defined(__DECC) && defined(__alpha) +# define INSTRUCTION_POINTER_IMPLEMENTED + ret = (void *)(size_t)asm("br %v0,1f\n1:"); +#elif defined(_MSC_VER) && defined(_M_IX86) +# define INSTRUCTION_POINTER_IMPLEMENTED + void *scratch; + _asm { + call self + self: pop eax + mov scratch,eax + } + ret = (void *)((size_t)scratch&~3UL); +#endif + return ret; +} + +/* + * This function returns pointer to an instruction in the vicinity of + * its entry point, but not outside this object module. This guarantees + * that sequestered code is covered... + */ +void *FIPS_ref_point() +{ +#if defined(INSTRUCTION_POINTER_IMPLEMENTED) + return instruction_pointer(); +/* Below we essentially cover vendor compilers which do not support + * inline assembler... */ +#elif defined(_AIX) + struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer; + return p->ip; +#elif defined(_HPUX_SOURCE) +# if defined(__hppa) || defined(__hppa__) + struct { void *i[4]; } *p = (void *)FIPS_ref_point; + + if (sizeof(p) == 8) /* 64-bit */ + return p->i[2]; + else if ((size_t)p & 2) + { p = (void *)((size_t)p&~3UL); + return p->i[0]; + } + else + return (void *)p; +# elif defined(__ia64) || defined(__ia64__) + struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer; + return (void *)(size_t)p->ip; +# endif +#elif (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__)) + /* applies to both alpha and ia64 */ + struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer; + return (void *)(size_t)p->ip; +#elif defined(__VOS__) + /* applies to both pa-risc and ia32 */ + struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer; + return p->ip; +#elif defined(_WIN32) +# if defined(_WIN64) && defined(_M_IA64) + struct { void *ip,*gp; } *p = (void *)FIPS_ref_point; + return p->ip; +# else + return (void *)FIPS_ref_point; +# endif +/* + * In case you wonder why there is no #ifdef __linux. All Linux targets + * are GCC-based and therefore are covered by instruction_pointer above + * [well, some are covered by by the one below]... + */ +#elif defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION) + return (void *)instruction_pointer; +#else + return NULL; +#endif +} diff --git a/fips/fips_locl.h b/fips/fips_locl.h new file mode 100644 index 0000000000..03fed36e3c --- /dev/null +++ b/fips/fips_locl.h @@ -0,0 +1,73 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +void fips_w_lock(void); +void fips_w_unlock(void); +void fips_r_lock(void); +void fips_r_unlock(void); +int fips_is_started(void); +void fips_set_started(void); +int fips_is_owning_thread(void); +int fips_set_owning_thread(void); +void fips_set_selftest_fail(void); +int fips_clear_owning_thread(void); +unsigned char *fips_signature_witness(void); + +#define FIPS_MAX_CIPHER_TEST_SIZE 16 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/fips/fips_premain.c b/fips/fips_premain.c new file mode 100644 index 0000000000..165d2c5dc9 --- /dev/null +++ b/fips/fips_premain.c @@ -0,0 +1,176 @@ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution + * and usage in source and binary forms are granted according to the + * OpenSSL license. + */ + +#include +#include +#include +#if defined(__unix) || defined(__unix__) +#include +#endif + +#ifndef FINGERPRINT_PREMAIN_DSO_LOAD + +#if defined(__GNUC__) && __GNUC__>=2 + void FINGERPRINT_premain(void) __attribute__((constructor)); + /* Most commonly this results in pointer to premain to be dropped + * to .ctors segment, which is traversed by GCC crtbegin.o upon + * program startup. Except on a.out OpenBSD where it results in + * _GLOBAL_$I$premain() {premain();} being auto-generated by + * compiler... But one way or another this is believed to cover + * *all* GCC targets. */ +#elif defined(_MSC_VER) +# ifdef _WINDLL + __declspec(dllexport) /* this is essentially cosmetics... */ +# endif + void FINGERPRINT_premain(void); + static int premain_wrapper(void) { FINGERPRINT_premain(); return 0; } +# ifdef _WIN64 +# pragma section(".CRT$XCU",read) + __declspec(allocate(".CRT$XCU")) +# else +# pragma data_seg(".CRT$XCU") +# endif + static int (*p)(void) = premain_wrapper; + /* This results in pointer to premain to appear in .CRT segment, + * which is traversed by Visual C run-time initialization code. + * This applies to both Win32 and [all flavors of] Win64. */ +# pragma data_seg() +#elif defined(__SUNPRO_C) + void FINGERPRINT_premain(void); +# pragma init(FINGERPRINT_premain) + /* This results in a call to premain to appear in .init segment. */ +#elif defined(__DECC) && (defined(__VMS) || defined(VMS)) + void FINGERPRINT_premain(void); +# pragma __nostandard + globaldef { "LIB$INITIALIZ" } readonly _align (LONGWORD) + int spare[8] = {0}; + globaldef { "LIB$INITIALIZE" } readonly _align (LONGWORD) + void (*x_FINGERPRINT_premain)(void) = FINGERPRINT_premain; + /* Refer to LIB$INITIALIZE to ensure it exists in the image. */ + int lib$initialize(); + globaldef int (*lib_init_ref)() = lib$initialize; +# pragma __standard +#elif 0 + The rest has to be taken care of through command line: + + -Wl,-init,FINGERPRINT_premain on OSF1 and IRIX + -Wl,+init,FINGERPRINT_premain on HP-UX + -Wl,-binitfini:FINGERPRINT_premain on AIX + + On ELF platforms this results in a call to premain to appear in + .init segment... +#endif + +#ifndef HMAC_SHA1_SIG +#define HMAC_SHA1_SIG "?have to make sure this string is unique" +#endif + +static const unsigned char FINGERPRINT_ascii_value[40] = HMAC_SHA1_SIG; + +#define atox(c) ((c)>='a'?((c)-'a'+10):((c)>='A'?(c)-'A'+10:(c)-'0')) + +extern const void *FIPS_text_start(), *FIPS_text_end(); +extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[]; +extern unsigned char FIPS_signature[20]; +extern unsigned int FIPS_incore_fingerprint(unsigned char *,unsigned int); + +/* + * As name suggests this code is executed prior main(). We use this + * opportunity to fingerprint sequestered code in virtual address + * space of target application. + */ +void FINGERPRINT_premain(void) +{ unsigned char sig[sizeof(FIPS_signature)]; + const unsigned char * volatile p=FINGERPRINT_ascii_value; + unsigned int len=sizeof(sig),i; + + /* "volatilization" is done to disengage unwanted optimization... */ + if (*((volatile unsigned char *)p)=='?') + { if (FIPS_text_start()==NULL) + { fprintf(stderr,"FIPS_text_start() returns NULL\n"); + _exit(1); + } +#if defined(DEBUG_FINGERPRINT_PREMAIN) + fprintf(stderr,".text:%p+%d=%p\n",FIPS_text_start(), + (int)((size_t)FIPS_text_end()-(size_t)FIPS_text_start()), + FIPS_text_end()); + fprintf(stderr,".rodata:%p+%d=%p\n",FIPS_rodata_start, + (int)((size_t)FIPS_rodata_end-(size_t)FIPS_rodata_start), + FIPS_rodata_end); +#endif + + len=FIPS_incore_fingerprint(sig,sizeof(sig)); + + if (len!=sizeof(sig)) + { fprintf(stderr,"fingerprint length mismatch: %u\n",len); + _exit(1); + } + + for (i=0;i +#include +#include + +int main(int argc,char *argv[]) +{ DSO *dso; + DSO_FUNC_TYPE func; + BIO *bio_err; + + if (argc < 2) + { fprintf (stderr,"usage: %s libcrypto.dso\n",argv[0]); + return 1; + } + + if ((bio_err=BIO_new(BIO_s_file())) == NULL) + { fprintf (stderr,"unable to allocate BIO\n"); + return 1; + } + BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); + ERR_load_crypto_strings(); + + dso = DSO_load(NULL,argv[1],NULL,DSO_FLAG_NO_NAME_TRANSLATION); + if (dso == NULL) + { ERR_print_errors(bio_err); + return 1; + } + + /* This is not normally reached, because FINGERPRINT_premain should + * have executed and terminated application already upon DSO_load... */ + func = DSO_bind_func(dso,"FINGERPRINT_premain"); + if (func == NULL) + { ERR_print_errors(bio_err); + return 1; + } + + (*func)(); + + return 0; +} + +#endif diff --git a/fips/fips_premain.c.sha1 b/fips/fips_premain.c.sha1 new file mode 100644 index 0000000000..c16f964bb8 --- /dev/null +++ b/fips/fips_premain.c.sha1 @@ -0,0 +1 @@ +HMAC-SHA1(fips_premain.c)= 9e5ddba185ac446e0cf36fcf8e1b3acffe5d0b2c diff --git a/fips/fips_test_suite.c b/fips/fips_test_suite.c new file mode 100644 index 0000000000..2d9de5f6a6 --- /dev/null +++ b/fips/fips_test_suite.c @@ -0,0 +1,587 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * + * This command is intended as a test driver for the FIPS-140 testing + * lab performing FIPS-140 validation. It demonstrates the use of the + * OpenSSL library ito perform a variety of common cryptographic + * functions. A power-up self test is demonstrated by deliberately + * pointing to an invalid executable hash + * + * Contributed by Steve Marquess. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#ifndef OPENSSL_FIPS +int main(int argc, char *argv[]) + { + printf("No FIPS support\n"); + return(0); + } +#else + +#include +#include "fips_utl.h" + +/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext +*/ +static int FIPS_aes_test(void) + { + int ret = 0; + unsigned char pltmp[16]; + unsigned char citmp[16]; + unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + unsigned char plaintext[16] = "etaonrishdlcu"; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 16); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 16); + if (memcmp(pltmp, plaintext, 16)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; + } + +static int FIPS_des3_test(void) + { + int ret = 0; + unsigned char pltmp[8]; + unsigned char citmp[8]; + unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18, + 19,20,21,22,23,24}; + unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' }; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 8); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 8); + if (memcmp(pltmp, plaintext, 8)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; + } + +/* + * DSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_dsa_test(int bad) + { + DSA *dsa = NULL; + EVP_PKEY pk; + unsigned char dgst[] = "etaonrishdlc"; + unsigned char buf[60]; + unsigned int slen; + int r = 0; + EVP_MD_CTX mctx; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + dsa = FIPS_dsa_new(); + if (!dsa) + goto end; + if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL)) + goto end; + if (!DSA_generate_key(dsa)) + goto end; + if (bad) + BN_add_word(dsa->pub_key, 1); + + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + + if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (dsa) + FIPS_dsa_free(dsa); + if (r != 1) + return 0; + return 1; + } + +/* + * RSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_rsa_test(int bad) + { + RSA *key; + unsigned char input_ptext[] = "etaonrishdlc"; + unsigned char buf[256]; + unsigned int slen; + BIGNUM *bn; + EVP_MD_CTX mctx; + EVP_PKEY pk; + int r = 0; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + key = FIPS_rsa_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024,bn,NULL)) + return 0; + BN_free(bn); + if (bad) + BN_add_word(key->n, 1); + + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = key; + + if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (key) + FIPS_rsa_free(key); + if (r != 1) + return 0; + return 1; + } + +/* SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha1_test() + { + unsigned char digest[SHA_DIGEST_LENGTH] = + { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 }; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha1(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha256_test() + { + unsigned char digest[SHA256_DIGEST_LENGTH] = + {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91, + 0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57}; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA256_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha256(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha512_test() + { + unsigned char digest[SHA512_DIGEST_LENGTH] = + {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca, + 0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a, + 0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22, + 0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3}; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA512_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha512(), NULL)) return 0; + if (memcmp(md,digest,sizeof(md))) + return 0; + return 1; + } + +/* HMAC-SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha1_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70, + 0xb2, 0xfb, 0xec, 0xc6}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA224: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha224_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35, + 0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha256_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87, + 0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA384: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha384_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10, + 0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08, + 0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + +/* HMAC-SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha512_test() + { + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6, + 0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1, + 0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c, + 0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53}; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0; + if (memcmp(out,kaval,outlen)) + return 0; + return 1; + } + + +/* DH: generate shared parameters +*/ +static int dh_test() + { + DH *dh; + ERR_clear_error(); + dh = FIPS_dh_new(); + if (!dh) + return 0; + if (!DH_generate_parameters_ex(dh, 1024, 2, NULL)) + return 0; + FIPS_dh_free(dh); + return 1; + } + +/* Zeroize +*/ +static int Zeroize() + { + RSA *key; + BIGNUM *bn; + unsigned char userkey[16] = + { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 }; + int i, n; + + key = FIPS_rsa_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024,bn,NULL)) + return 0; + BN_free(bn); + + n = BN_num_bytes(key->d); + printf(" Generated %d byte RSA private key\n", n); + printf("\tBN key before overwriting:\n"); + do_bn_print(stdout, key->d); + BN_rand(key->d,n*8,-1,0); + printf("\tBN key after overwriting:\n"); + do_bn_print(stdout, key->d); + + printf("\tchar buffer key before overwriting: \n\t\t"); + for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); + printf("\n"); + RAND_bytes(userkey, sizeof userkey); + printf("\tchar buffer key after overwriting: \n\t\t"); + for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]); + printf("\n"); + + return 1; + } + +static int Error; +const char * Fail(const char *msg) + { + do_print_errors(); + Error++; + return msg; + } + +int main(int argc,char **argv) + { + + int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0; + int bad_rsa = 0, bad_dsa = 0; + int do_rng_stick = 0; + int no_exit = 0; + + printf("\tFIPS-mode test application\n\n"); + + /* Load entropy from external file, if any */ + RAND_load_file(".rnd", 1024); + + if (argv[1]) { + /* Corrupted KAT tests */ + if (!strcmp(argv[1], "aes")) { + FIPS_corrupt_aes(); + printf("AES encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "des")) { + FIPS_corrupt_des(); + printf("DES3-ECB encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "dsa")) { + FIPS_corrupt_dsa(); + printf("DSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsa")) { + FIPS_corrupt_rsa(); + printf("RSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsakey")) { + printf("RSA key generation and signature validation with corrupted key...\n"); + bad_rsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "rsakeygen")) { + do_corrupt_rsa_keygen = 1; + no_exit = 1; + printf("RSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "dsakey")) { + printf("DSA key generation and signature validation with corrupted key...\n"); + bad_dsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "dsakeygen")) { + do_corrupt_dsa_keygen = 1; + no_exit = 1; + printf("DSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "sha1")) { + FIPS_corrupt_sha1(); + printf("SHA-1 hash with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rng")) { + FIPS_corrupt_rng(); + } else if (!strcmp(argv[1], "rngstick")) { + do_rng_stick = 1; + no_exit = 1; + printf("RNG test with stuck continuous test...\n"); + } else { + printf("Bad argument \"%s\"\n", argv[1]); + exit(1); + } + if (!no_exit) { + if (!FIPS_mode_set(1)) { + do_print_errors(); + printf("Power-up self test failed\n"); + exit(1); + } + printf("Power-up self test successful\n"); + exit(0); + } + } + + /* Non-Approved cryptographic operation + */ + printf("1. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf( dh_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* Power-up self test + */ + ERR_clear_error(); + printf("2. Automatic power-up self test..."); + if (!FIPS_mode_set(1)) + { + do_print_errors(); + printf(Fail("FAILED!\n")); + exit(1); + } + printf("successful\n"); + if (do_corrupt_dsa_keygen) + FIPS_corrupt_dsa_keygen(); + if (do_corrupt_rsa_keygen) + FIPS_corrupt_rsa_keygen(); + if (do_rng_stick) + FIPS_rng_stick(); + + /* AES encryption/decryption + */ + printf("3. AES encryption/decryption..."); + printf( FIPS_aes_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* RSA key generation and encryption/decryption + */ + printf("4. RSA key generation and encryption/decryption..."); + printf( FIPS_rsa_test(bad_rsa) ? "successful\n" : Fail("FAILED!\n") ); + + /* DES-CBC encryption/decryption + */ + printf("5. DES-ECB encryption/decryption..."); + printf( FIPS_des3_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* DSA key generation and signature validation + */ + printf("6. DSA key generation and signature validation..."); + printf( FIPS_dsa_test(bad_dsa) ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-1 hash + */ + printf("7a. SHA-1 hash..."); + printf( FIPS_sha1_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-256 hash + */ + printf("7b. SHA-256 hash..."); + printf( FIPS_sha256_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* SHA-512 hash + */ + printf("7c. SHA-512 hash..."); + printf( FIPS_sha512_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-1 hash + */ + printf("7d. HMAC-SHA-1 hash..."); + printf( FIPS_hmac_sha1_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-224 hash + */ + printf("7e. HMAC-SHA-224 hash..."); + printf( FIPS_hmac_sha224_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-256 hash + */ + printf("7f. HMAC-SHA-256 hash..."); + printf( FIPS_hmac_sha256_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-384 hash + */ + printf("7g. HMAC-SHA-384 hash..."); + printf( FIPS_hmac_sha384_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* HMAC-SHA-512 hash + */ + printf("7h. HMAC-SHA-512 hash..."); + printf( FIPS_hmac_sha512_test() ? "successful\n" : Fail("FAILED!\n") ); + + /* Non-Approved cryptographic operation + */ + printf("8. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf( dh_test() ? "successful as expected\n" + : Fail("failed INCORRECTLY!\n") ); + + /* Zeroization + */ + printf("9. Zero-ization...\n"); + printf( Zeroize() ? "\tsuccessful as expected\n" + : Fail("\tfailed INCORRECTLY!\n") ); + + printf("\nAll tests completed with %d errors\n", Error); + return Error ? 1 : 0; + } + +#endif diff --git a/fips/fips_utl.h b/fips/fips_utl.h new file mode 100644 index 0000000000..02d4e44c82 --- /dev/null +++ b/fips/fips_utl.h @@ -0,0 +1,343 @@ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +void do_print_errors(void) + { + const char *file, *data; + int line, flags; + unsigned long l; + while ((l = ERR_get_error_line_data(&file, &line, &data, &flags))) + { + fprintf(stderr, "ERROR:%lx:lib=%d,func=%d,reason=%d" + ":file=%s:line=%d:%s\n", + l, ERR_GET_LIB(l), ERR_GET_FUNC(l), ERR_GET_REASON(l), + file, line, flags & ERR_TXT_STRING ? data : ""); + } + } + +int hex2bin(const char *in, unsigned char *out) + { + int n1, n2; + unsigned char ch; + + for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; ) + { /* first byte */ + if ((in[n1] >= '0') && (in[n1] <= '9')) + ch = in[n1++] - '0'; + else if ((in[n1] >= 'A') && (in[n1] <= 'F')) + ch = in[n1++] - 'A' + 10; + else if ((in[n1] >= 'a') && (in[n1] <= 'f')) + ch = in[n1++] - 'a' + 10; + else + return -1; + if(!in[n1]) + { + out[n2++]=ch; + break; + } + out[n2] = ch << 4; + /* second byte */ + if ((in[n1] >= '0') && (in[n1] <= '9')) + ch = in[n1++] - '0'; + else if ((in[n1] >= 'A') && (in[n1] <= 'F')) + ch = in[n1++] - 'A' + 10; + else if ((in[n1] >= 'a') && (in[n1] <= 'f')) + ch = in[n1++] - 'a' + 10; + else + return -1; + out[n2++] |= ch; + } + return n2; + } + +unsigned char *hex2bin_m(const char *in, long *plen) + { + unsigned char *p; + p = OPENSSL_malloc((strlen(in) + 1)/2); + *plen = hex2bin(in, p); + return p; + } + +int do_hex2bn(BIGNUM **pr, const char *in) + { + unsigned char *p; + long plen; + int r = 0; + p = hex2bin_m(in, &plen); + if (!p) + return 0; + if (!*pr) + *pr = BN_new(); + if (!*pr) + return 0; + if (BN_bin2bn(p, plen, *pr)) + r = 1; + OPENSSL_free(p); + return r; + } + +int do_bn_print(FILE *out, BIGNUM *bn) + { + int len, i; + unsigned char *tmp; + len = BN_num_bytes(bn); + if (len == 0) + { + fputs("00", out); + return 1; + } + + tmp = OPENSSL_malloc(len); + if (!tmp) + { + fprintf(stderr, "Memory allocation error\n"); + return 0; + } + BN_bn2bin(bn, tmp); + for (i = 0; i < len; i++) + fprintf(out, "%02x", tmp[i]); + OPENSSL_free(tmp); + return 1; + } + +int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn) + { + int r; + fprintf(out, "%s = ", name); + r = do_bn_print(out, bn); + if (!r) + return 0; + fputs("\n", out); + return 1; + } + +int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf) + { + char *keyword, *value, *p, *q; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no '=' exit */ + if (!p) + return 0; + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + *pkw = keyword; + *pval = value; + return 1; + } + +BIGNUM *hex2bn(const char *in) + { + BIGNUM *p=NULL; + + if (!do_hex2bn(&p, in)) + return NULL; + + return p; + } + +int bin2hex(const unsigned char *in,int len,char *out) + { + int n1, n2; + unsigned char ch; + + for (n1=0,n2=0 ; n1 < len ; ++n1) + { + ch=in[n1] >> 4; + if (ch <= 0x09) + out[n2++]=ch+'0'; + else + out[n2++]=ch-10+'a'; + ch=in[n1] & 0x0f; + if(ch <= 0x09) + out[n2++]=ch+'0'; + else + out[n2++]=ch-10+'a'; + } + out[n2]='\0'; + return n2; + } + +void pv(const char *tag,const unsigned char *val,int len) + { + char obuf[2048]; + + bin2hex(val,len,obuf); + printf("%s = %s\n",tag,obuf); + } + +/* To avoid extensive changes to test program at this stage just convert + * the input line into an acceptable form. Keyword lines converted to form + * "keyword = value\n" no matter what white space present, all other lines + * just have leading and trailing space removed. + */ + +int tidy_line(char *linebuf, char *olinebuf) + { + char *keyword, *value, *p, *q; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no '=' just chop leading, trailing ws */ + if (!p) + { + p = keyword + strlen(keyword) - 1; + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + strcpy(olinebuf, keyword); + strcat(olinebuf, "\n"); + return 1; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + strcpy(olinebuf, keyword); + strcat(olinebuf, " = "); + strcat(olinebuf, value); + strcat(olinebuf, "\n"); + + return 1; + } + +/* NB: this return the number of _bits_ read */ +int bint2bin(const char *in, int len, unsigned char *out) + { + int n; + + memset(out,0,len); + for(n=0 ; n < len ; ++n) + if(in[n] == '1') + out[n/8]|=(0x80 >> (n%8)); + return len; + } + +int bin2bint(const unsigned char *in,int len,char *out) + { + int n; + + for(n=0 ; n < len ; ++n) + out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0'; + return n; + } + +/*-----------------------------------------------*/ + +void PrintValue(char *tag, unsigned char *val, int len) +{ +#if VERBOSE + char obuf[2048]; + int olen; + olen = bin2hex(val, len, obuf); + printf("%s = %.*s\n", tag, olen, obuf); +#endif +} + +void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode) + { + char obuf[2048]; + int olen; + + if(bitmode) + olen=bin2bint(val,len,obuf); + else + olen=bin2hex(val,len,obuf); + + fprintf(rfp, "%s = %.*s\n", tag, olen, obuf); +#if VERBOSE + printf("%s = %.*s\n", tag, olen, obuf); +#endif + } + diff --git a/fips/fipsalgtest.pl b/fips/fipsalgtest.pl new file mode 100644 index 0000000000..44a5ccac7a --- /dev/null +++ b/fips/fipsalgtest.pl @@ -0,0 +1,848 @@ +#!/usr/bin/perl -w +# Perl utility to run or verify FIPS 140-2 CMVP algorithm tests based on the +# pathnames of input algorithm test files actually present (the unqualified +# file names are consistent but the pathnames are not). +# + +# FIPS test definitions +# List of all the unqualified file names we expect and command lines to run + +# DSA tests +my @fips_dsa_test_list = ( + + "DSA", + + [ "PQGGen", "fips_dssvs pqg" ], + [ "KeyPair", "fips_dssvs keypair" ], + [ "SigGen", "fips_dssvs siggen" ], + [ "SigVer", "fips_dssvs sigver" ] + +); + +# RSA tests + +my @fips_rsa_test_list = ( + + "RSA", + + [ "SigGen15", "fips_rsastest" ], + [ "SigVer15", "fips_rsavtest" ], + [ "SigVerRSA", "fips_rsavtest -x931" ], + [ "KeyGenRSA", "fips_rsagtest" ], + [ "SigGenRSA", "fips_rsastest -x931" ] + +); + +# Special cases for PSS. The filename itself is +# not sufficient to determine the test. Addditionally we +# need to examine the file contents to determine the salt length +# In these cases the test filename has (saltlen) appended. + +# RSA PSS salt length 0 tests + +my @fips_rsa_pss0_test_list = ( + + [ "SigGenPSS(0)", "fips_rsastest -saltlen 0" ], + [ "SigVerPSS(0)", "fips_rsavtest -saltlen 0" ] + +); + +# RSA PSS salt length 62 tests + +my @fips_rsa_pss62_test_list = ( + [ "SigGenPSS(62)", "fips_rsastest -saltlen 62" ], + [ "SigVerPSS(62)", "fips_rsavtest -saltlen 62" ] + +); + +# SHA tests + +my @fips_sha_test_list = ( + + "SHA", + + [ "SHA1LongMsg", "fips_shatest" ], + [ "SHA1Monte", "fips_shatest" ], + [ "SHA1ShortMsg", "fips_shatest" ], + [ "SHA224LongMsg", "fips_shatest" ], + [ "SHA224Monte", "fips_shatest" ], + [ "SHA224ShortMsg", "fips_shatest" ], + [ "SHA256LongMsg", "fips_shatest" ], + [ "SHA256Monte", "fips_shatest" ], + [ "SHA256ShortMsg", "fips_shatest" ], + [ "SHA384LongMsg", "fips_shatest" ], + [ "SHA384Monte", "fips_shatest" ], + [ "SHA384ShortMsg", "fips_shatest" ], + [ "SHA512LongMsg", "fips_shatest" ], + [ "SHA512Monte", "fips_shatest" ], + [ "SHA512ShortMsg", "fips_shatest" ] + +); + +# HMAC + +my @fips_hmac_test_list = ( + + "HMAC", + + [ "HMAC", "fips_hmactest" ] + +); + +# RAND tests, AES version + +my @fips_rand_aes_test_list = ( + + "RAND (AES)", + + [ "ANSI931_AES128MCT", "fips_rngvs mct" ], + [ "ANSI931_AES192MCT", "fips_rngvs mct" ], + [ "ANSI931_AES256MCT", "fips_rngvs mct" ], + [ "ANSI931_AES128VST", "fips_rngvs vst" ], + [ "ANSI931_AES192VST", "fips_rngvs vst" ], + [ "ANSI931_AES256VST", "fips_rngvs vst" ] + +); + +# RAND tests, DES2 version + +my @fips_rand_des2_test_list = ( + + "RAND (DES2)", + + [ "ANSI931_TDES2MCT", "fips_rngvs mct" ], + [ "ANSI931_TDES2VST", "fips_rngvs vst" ] + +); + +# AES tests + +my @fips_aes_test_list = ( + + "AES", + + [ "CBCGFSbox128", "fips_aesavs -f" ], + [ "CBCGFSbox192", "fips_aesavs -f" ], + [ "CBCGFSbox256", "fips_aesavs -f" ], + [ "CBCKeySbox128", "fips_aesavs -f" ], + [ "CBCKeySbox192", "fips_aesavs -f" ], + [ "CBCKeySbox256", "fips_aesavs -f" ], + [ "CBCMCT128", "fips_aesavs -f" ], + [ "CBCMCT192", "fips_aesavs -f" ], + [ "CBCMCT256", "fips_aesavs -f" ], + [ "CBCMMT128", "fips_aesavs -f" ], + [ "CBCMMT192", "fips_aesavs -f" ], + [ "CBCMMT256", "fips_aesavs -f" ], + [ "CBCVarKey128", "fips_aesavs -f" ], + [ "CBCVarKey192", "fips_aesavs -f" ], + [ "CBCVarKey256", "fips_aesavs -f" ], + [ "CBCVarTxt128", "fips_aesavs -f" ], + [ "CBCVarTxt192", "fips_aesavs -f" ], + [ "CBCVarTxt256", "fips_aesavs -f" ], + [ "CFB128GFSbox128", "fips_aesavs -f" ], + [ "CFB128GFSbox192", "fips_aesavs -f" ], + [ "CFB128GFSbox256", "fips_aesavs -f" ], + [ "CFB128KeySbox128", "fips_aesavs -f" ], + [ "CFB128KeySbox192", "fips_aesavs -f" ], + [ "CFB128KeySbox256", "fips_aesavs -f" ], + [ "CFB128MCT128", "fips_aesavs -f" ], + [ "CFB128MCT192", "fips_aesavs -f" ], + [ "CFB128MCT256", "fips_aesavs -f" ], + [ "CFB128MMT128", "fips_aesavs -f" ], + [ "CFB128MMT192", "fips_aesavs -f" ], + [ "CFB128MMT256", "fips_aesavs -f" ], + [ "CFB128VarKey128", "fips_aesavs -f" ], + [ "CFB128VarKey192", "fips_aesavs -f" ], + [ "CFB128VarKey256", "fips_aesavs -f" ], + [ "CFB128VarTxt128", "fips_aesavs -f" ], + [ "CFB128VarTxt192", "fips_aesavs -f" ], + [ "CFB128VarTxt256", "fips_aesavs -f" ], + [ "CFB8GFSbox128", "fips_aesavs -f" ], + [ "CFB8GFSbox192", "fips_aesavs -f" ], + [ "CFB8GFSbox256", "fips_aesavs -f" ], + [ "CFB8KeySbox128", "fips_aesavs -f" ], + [ "CFB8KeySbox192", "fips_aesavs -f" ], + [ "CFB8KeySbox256", "fips_aesavs -f" ], + [ "CFB8MCT128", "fips_aesavs -f" ], + [ "CFB8MCT192", "fips_aesavs -f" ], + [ "CFB8MCT256", "fips_aesavs -f" ], + [ "CFB8MMT128", "fips_aesavs -f" ], + [ "CFB8MMT192", "fips_aesavs -f" ], + [ "CFB8MMT256", "fips_aesavs -f" ], + [ "CFB8VarKey128", "fips_aesavs -f" ], + [ "CFB8VarKey192", "fips_aesavs -f" ], + [ "CFB8VarKey256", "fips_aesavs -f" ], + [ "CFB8VarTxt128", "fips_aesavs -f" ], + [ "CFB8VarTxt192", "fips_aesavs -f" ], + [ "CFB8VarTxt256", "fips_aesavs -f" ], + + [ "ECBGFSbox128", "fips_aesavs -f" ], + [ "ECBGFSbox192", "fips_aesavs -f" ], + [ "ECBGFSbox256", "fips_aesavs -f" ], + [ "ECBKeySbox128", "fips_aesavs -f" ], + [ "ECBKeySbox192", "fips_aesavs -f" ], + [ "ECBKeySbox256", "fips_aesavs -f" ], + [ "ECBMCT128", "fips_aesavs -f" ], + [ "ECBMCT192", "fips_aesavs -f" ], + [ "ECBMCT256", "fips_aesavs -f" ], + [ "ECBMMT128", "fips_aesavs -f" ], + [ "ECBMMT192", "fips_aesavs -f" ], + [ "ECBMMT256", "fips_aesavs -f" ], + [ "ECBVarKey128", "fips_aesavs -f" ], + [ "ECBVarKey192", "fips_aesavs -f" ], + [ "ECBVarKey256", "fips_aesavs -f" ], + [ "ECBVarTxt128", "fips_aesavs -f" ], + [ "ECBVarTxt192", "fips_aesavs -f" ], + [ "ECBVarTxt256", "fips_aesavs -f" ], + [ "OFBGFSbox128", "fips_aesavs -f" ], + [ "OFBGFSbox192", "fips_aesavs -f" ], + [ "OFBGFSbox256", "fips_aesavs -f" ], + [ "OFBKeySbox128", "fips_aesavs -f" ], + [ "OFBKeySbox192", "fips_aesavs -f" ], + [ "OFBKeySbox256", "fips_aesavs -f" ], + [ "OFBMCT128", "fips_aesavs -f" ], + [ "OFBMCT192", "fips_aesavs -f" ], + [ "OFBMCT256", "fips_aesavs -f" ], + [ "OFBMMT128", "fips_aesavs -f" ], + [ "OFBMMT192", "fips_aesavs -f" ], + [ "OFBMMT256", "fips_aesavs -f" ], + [ "OFBVarKey128", "fips_aesavs -f" ], + [ "OFBVarKey192", "fips_aesavs -f" ], + [ "OFBVarKey256", "fips_aesavs -f" ], + [ "OFBVarTxt128", "fips_aesavs -f" ], + [ "OFBVarTxt192", "fips_aesavs -f" ], + [ "OFBVarTxt256", "fips_aesavs -f" ] + +); + +my @fips_aes_cfb1_test_list = ( + + # AES CFB1 tests + + [ "CFB1GFSbox128", "fips_aesavs -f" ], + [ "CFB1GFSbox192", "fips_aesavs -f" ], + [ "CFB1GFSbox256", "fips_aesavs -f" ], + [ "CFB1KeySbox128", "fips_aesavs -f" ], + [ "CFB1KeySbox192", "fips_aesavs -f" ], + [ "CFB1KeySbox256", "fips_aesavs -f" ], + [ "CFB1MCT128", "fips_aesavs -f" ], + [ "CFB1MCT192", "fips_aesavs -f" ], + [ "CFB1MCT256", "fips_aesavs -f" ], + [ "CFB1MMT128", "fips_aesavs -f" ], + [ "CFB1MMT192", "fips_aesavs -f" ], + [ "CFB1MMT256", "fips_aesavs -f" ], + [ "CFB1VarKey128", "fips_aesavs -f" ], + [ "CFB1VarKey192", "fips_aesavs -f" ], + [ "CFB1VarKey256", "fips_aesavs -f" ], + [ "CFB1VarTxt128", "fips_aesavs -f" ], + [ "CFB1VarTxt192", "fips_aesavs -f" ], + [ "CFB1VarTxt256", "fips_aesavs -f" ] + +); + +# Triple DES tests + +my @fips_des3_test_list = ( + + "Triple DES", + + [ "TCBCinvperm", "fips_desmovs -f" ], + [ "TCBCMMT1", "fips_desmovs -f" ], + [ "TCBCMMT2", "fips_desmovs -f" ], + [ "TCBCMMT3", "fips_desmovs -f" ], + [ "TCBCMonte1", "fips_desmovs -f" ], + [ "TCBCMonte2", "fips_desmovs -f" ], + [ "TCBCMonte3", "fips_desmovs -f" ], + [ "TCBCpermop", "fips_desmovs -f" ], + [ "TCBCsubtab", "fips_desmovs -f" ], + [ "TCBCvarkey", "fips_desmovs -f" ], + [ "TCBCvartext", "fips_desmovs -f" ], + [ "TCFB64invperm", "fips_desmovs -f" ], + [ "TCFB64MMT1", "fips_desmovs -f" ], + [ "TCFB64MMT2", "fips_desmovs -f" ], + [ "TCFB64MMT3", "fips_desmovs -f" ], + [ "TCFB64Monte1", "fips_desmovs -f" ], + [ "TCFB64Monte2", "fips_desmovs -f" ], + [ "TCFB64Monte3", "fips_desmovs -f" ], + [ "TCFB64permop", "fips_desmovs -f" ], + [ "TCFB64subtab", "fips_desmovs -f" ], + [ "TCFB64varkey", "fips_desmovs -f" ], + [ "TCFB64vartext", "fips_desmovs -f" ], + [ "TCFB8invperm", "fips_desmovs -f" ], + [ "TCFB8MMT1", "fips_desmovs -f" ], + [ "TCFB8MMT2", "fips_desmovs -f" ], + [ "TCFB8MMT3", "fips_desmovs -f" ], + [ "TCFB8Monte1", "fips_desmovs -f" ], + [ "TCFB8Monte2", "fips_desmovs -f" ], + [ "TCFB8Monte3", "fips_desmovs -f" ], + [ "TCFB8permop", "fips_desmovs -f" ], + [ "TCFB8subtab", "fips_desmovs -f" ], + [ "TCFB8varkey", "fips_desmovs -f" ], + [ "TCFB8vartext", "fips_desmovs -f" ], + [ "TECBinvperm", "fips_desmovs -f" ], + [ "TECBMMT1", "fips_desmovs -f" ], + [ "TECBMMT2", "fips_desmovs -f" ], + [ "TECBMMT3", "fips_desmovs -f" ], + [ "TECBMonte1", "fips_desmovs -f" ], + [ "TECBMonte2", "fips_desmovs -f" ], + [ "TECBMonte3", "fips_desmovs -f" ], + [ "TECBpermop", "fips_desmovs -f" ], + [ "TECBsubtab", "fips_desmovs -f" ], + [ "TECBvarkey", "fips_desmovs -f" ], + [ "TECBvartext", "fips_desmovs -f" ], + [ "TOFBinvperm", "fips_desmovs -f" ], + [ "TOFBMMT1", "fips_desmovs -f" ], + [ "TOFBMMT2", "fips_desmovs -f" ], + [ "TOFBMMT3", "fips_desmovs -f" ], + [ "TOFBMonte1", "fips_desmovs -f" ], + [ "TOFBMonte2", "fips_desmovs -f" ], + [ "TOFBMonte3", "fips_desmovs -f" ], + [ "TOFBpermop", "fips_desmovs -f" ], + [ "TOFBsubtab", "fips_desmovs -f" ], + [ "TOFBvarkey", "fips_desmovs -f" ], + [ "TOFBvartext", "fips_desmovs -f" ] + +); + +# Verification special cases. +# In most cases the output of a test is deterministic and +# it can be compared to a known good result. A few involve +# the genration and use of random keys and the output will +# be different each time. In thoses cases we perform special tests +# to simply check their consistency. For example signature generation +# output will be run through signature verification to see if all outputs +# show as valid. +# + +my %verify_special = ( + "PQGGen" => "fips_dssvs pqgver", + "KeyPair" => "fips_dssvs keyver", + "SigGen" => "fips_dssvs sigver", + "SigGen15" => "fips_rsavtest", + "SigGenRSA" => "fips_rsavtest -x931", + "SigGenPSS(0)" => "fips_rsavtest -saltlen 0", + "SigGenPSS(62)" => "fips_rsavtest -saltlen 62", +); + +my $win32 = $^O =~ m/mswin/i; +my $onedir = 0; +my $filter = ""; +my $tvdir; +my $tprefix; +my $shwrap_prefix; +my $debug = 0; +my $quiet = 0; +my $notest = 0; +my $verify = 1; +my $rspdir = "rsp"; +my $ignore_missing = 0; +my $ignore_bogus = 0; +my $bufout = ''; +my $list_tests = 0; + +my %fips_enabled = ( + dsa => 1, + rsa => 1, + "rsa-pss0" => 0, + "rsa-pss62" => 1, + sha => 1, + hmac => 1, + "rand-aes" => 1, + "rand-des2" => 0, + aes => 1, + "aes-cfb1" => 0, + des3 => 1 +); + +foreach (@ARGV) { + if ( $_ eq "--win32" ) { + $win32 = 1; + } + elsif ( $_ eq "--onedir" ) { + $onedir = 1; + } + elsif ( $_ eq "--debug" ) { + $debug = 1; + } + elsif ( $_ eq "--ignore-missing" ) { + $ignore_missing = 1; + } + elsif ( $_ eq "--ignore-bogus" ) { + $ignore_bogus = 1; + } + elsif ( $_ eq "--generate" ) { + $verify = 0; + } + elsif ( $_ eq "--notest" ) { + $notest = 1; + } + elsif ( $_ eq "--quiet" ) { + $quiet = 1; + } + elsif (/--dir=(.*)$/) { + $tvdir = $1; + } + elsif (/--rspdir=(.*)$/) { + $rspdir = $1; + } + elsif (/--tprefix=(.*)$/) { + $tprefix = $1; + } + elsif (/--shwrap_prefix=(.*)$/) { + $shwrap_prefix = $1; + } + elsif (/^--(enable|disable)-(.*)$/) { + if ( !exists $fips_enabled{$2} ) { + print STDERR "Unknown test $2\n"; + } + if ( $1 eq "enable" ) { + $fips_enabled{$2} = 1; + } + else { + $fips_enabled{$2} = 0; + } + } + elsif (/--filter=(.*)$/) { + $filter = $1; + } + elsif (/^--list-tests$/) { + $list_tests = 1; + } + else { + Help(); + exit(1); + } +} + +my @fips_test_list; + +push @fips_test_list, @fips_dsa_test_list if $fips_enabled{"dsa"}; +push @fips_test_list, @fips_rsa_test_list if $fips_enabled{"rsa"}; +push @fips_test_list, @fips_rsa_pss0_test_list if $fips_enabled{"rsa-pss0"}; +push @fips_test_list, @fips_rsa_pss62_test_list if $fips_enabled{"rsa-pss62"}; +push @fips_test_list, @fips_sha_test_list if $fips_enabled{"sha"}; +push @fips_test_list, @fips_hmac_test_list if $fips_enabled{"hmac"}; +push @fips_test_list, @fips_rand_aes_test_list if $fips_enabled{"rand-aes"}; +push @fips_test_list, @fips_rand_des2_test_list if $fips_enabled{"rand-des2"}; +push @fips_test_list, @fips_aes_test_list if $fips_enabled{"aes"}; +push @fips_test_list, @fips_aes_cfb1_test_list if $fips_enabled{"aes-cfb1"}; +push @fips_test_list, @fips_des3_test_list if $fips_enabled{"des3"}; + +if ($list_tests) { + my ( $test, $en ); + print "=====TEST LIST=====\n"; + foreach $test ( sort keys %fips_enabled ) { + $en = $fips_enabled{$test}; + $test =~ tr/[a-z]/[A-Z]/; + printf "%-10s %s\n", $test, $en ? "enabled" : "disabled"; + } + exit(0); +} + +foreach (@fips_test_list) { + next unless ref($_); + my $nm = $_->[0]; + $_->[2] = ""; + $_->[3] = ""; + print STDERR "Duplicate test $nm\n" if exists $fips_tests{$nm}; + $fips_tests{$nm} = $_; +} + +$tvdir = "." unless defined $tvdir; + +if ($win32) { + if ( !defined $tprefix ) { + if ($onedir) { + $tprefix = ".\\"; + } + else { + $tprefix = "..\\out32dll\\"; + } + } +} +else { + if ($onedir) { + $tprefix = "./" unless defined $tprefix; + $shwrap_prefix = "./" unless defined $shwrap_prefix; + } + else { + $tprefix = "../test/" unless defined $tprefix; + $shwrap_prefix = "../util/" unless defined $shwrap_prefix; + } +} + +sanity_check_exe( $win32, $tprefix, $shwrap_prefix ); + +my $cmd_prefix = $win32 ? "" : "${shwrap_prefix}shlib_wrap.sh "; + +find_files( $filter, $tvdir ); + +sanity_check_files(); + +my ( $runerr, $cmperr, $cmpok, $scheckrunerr, $scheckerr, $scheckok, $skipcnt ) + = ( 0, 0, 0, 0, 0, 0, 0 ); + +exit(0) if $notest; + +run_tests( $verify, $win32, $tprefix, $filter, $tvdir ); + +if ($verify) { + print "ALGORITHM TEST VERIFY SUMMARY REPORT:\n"; + print "Tests skipped due to missing files: $skipcnt\n"; + print "Algorithm test program execution failures: $runerr\n"; + print "Test comparisons successful: $cmpok\n"; + print "Test comparisons failed: $cmperr\n"; + print "Test sanity checks successful: $scheckok\n"; + print "Test sanity checks failed: $scheckerr\n"; + print "Sanity check program execution failures: $scheckrunerr\n"; + + if ( $runerr || $cmperr || $scheckrunerr || $scheckerr ) { + print "***TEST FAILURE***\n"; + } + else { + print "***ALL TESTS SUCCESSFUL***\n"; + } +} +else { + print "ALGORITHM TEST SUMMARY REPORT:\n"; + print "Tests skipped due to missing files: $skipcnt\n"; + print "Algorithm test program execution failures: $runerr\n"; + + if ($runerr) { + print "***TEST FAILURE***\n"; + } + else { + print "***ALL TESTS SUCCESSFUL***\n"; + } +} + +#-------------------------------- +sub Help { + ( my $cmd ) = ( $0 =~ m#([^/]+)$# ); + print < Optional root for *.req file search + --filter= + --onedir Assume all components in current directory + --rspdir= Name of subdirectories containing *.rsp files, default "resp" + --shwrap_prefix= + --tprefix= + --ignore-bogus Ignore duplicate or bogus files + --ignore-missing Ignore missing test files + --quiet Shhh.... + --generate Generate algorithm test output + --win32 Win32 environment +EOF +} + +# Sanity check to see if all necessary executables exist + +sub sanity_check_exe { + my ( $win32, $tprefix, $shwrap_prefix ) = @_; + my %exe_list; + my $bad = 0; + $exe_list{ $shwrap_prefix . "shlib_wrap.sh" } = 1 unless $win32; + foreach (@fips_test_list) { + next unless ref($_); + my $cmd = $_->[1]; + $cmd =~ s/ .*$//; + $cmd = $tprefix . $cmd; + $cmd .= ".exe" if $win32; + $exe_list{$cmd} = 1; + } + + foreach ( sort keys %exe_list ) { + if ( !-f $_ ) { + print STDERR "ERROR: can't find executable $_\n"; + $bad = 1; + } + } + if ($bad) { + print STDERR "FATAL ERROR: executables missing\n"; + exit(1); + } + elsif ($debug) { + print STDERR "Executable sanity check passed OK\n"; + } +} + +# Search for all request and response files + +sub find_files { + my ( $filter, $dir ) = @_; + my ( $dirh, $testname ); + opendir( $dirh, $dir ); + while ( $_ = readdir($dirh) ) { + next if ( $_ eq "." || $_ eq ".." ); + $_ = "$dir/$_"; + if ( -f "$_" ) { + if (/\/([^\/]*)\.rsp$/) { + $testname = fix_pss( $1, $_ ); + if ( exists $fips_tests{$testname} ) { + if ( $fips_tests{$testname}->[3] eq "" ) { + $fips_tests{$testname}->[3] = $_; + } + else { + print STDERR +"WARNING: duplicate response file $_ for test $testname\n"; + $nbogus++; + } + } + else { + print STDERR "WARNING: bogus file $_\n"; + $nbogus++; + } + } + next unless /$filter.*\.req$/i; + if (/\/([^\/]*)\.req$/) { + $testname = fix_pss( $1, $_ ); + if ( exists $fips_tests{$testname} ) { + if ( $fips_tests{$testname}->[2] eq "" ) { + $fips_tests{$testname}->[2] = $_; + } + else { + print STDERR +"WARNING: duplicate request file $_ for test $testname\n"; + $nbogus++; + } + + } + elsif ( !/SHAmix\.req$/ ) { + print STDERR "WARNING: unrecognized filename $_\n"; + $nbogus++; + } + } + } + elsif ( -d "$_" ) { + find_files( $filter, $_ ); + } + } + closedir($dirh); +} + +sub fix_pss { + my ( $test, $path ) = @_; + my $sl = ""; + local $_; + if ( $test =~ /PSS/ ) { + open( IN, $path ) || die "Can't Open File $path"; + while () { + if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i) { + $sl = $1; + last; + } + } + close IN; + if ( $sl eq "" ) { + print STDERR "WARNING: No Salt length detected for file $path\n"; + } + else { + return $test . "($sl)"; + } + } + return $test; +} + +sub sanity_check_files { + my $bad = 0; + foreach (@fips_test_list) { + next unless ref($_); + my ( $tst, $cmd, $req, $resp ) = @$_; + + #print STDERR "FILES $tst, $cmd, $req, $resp\n"; + if ( $req eq "" ) { + print STDERR "WARNING: missing request file for $tst\n"; + $bad = 1; + next; + } + if ( $verify && $resp eq "" ) { + print STDERR "WARNING: no response file for test $tst\n"; + $bad = 1; + } + elsif ( !$verify && $resp ne "" ) { + print STDERR "WARNING: response file $resp will be overwritten\n"; + } + } + if ($bad) { + print STDERR "ERROR: test vector file set not complete\n"; + exit(1) unless $ignore_missing; + } + if ($nbogus) { + print STDERR + "ERROR: $nbogus bogus or duplicate request and response files\n"; + exit(1) unless $ignore_bogus; + } + if ( $debug && !$nbogus && !$bad ) { + print STDERR "test vector file set complete\n"; + } +} + +sub run_tests { + my ( $verify, $win32, $tprefix, $filter, $tvdir ) = @_; + my ( $tname, $tref ); + my $bad = 0; + foreach (@fips_test_list) { + if ( !ref($_) ) { + print "Running $_ tests\n" unless $quiet; + next; + } + my ( $tname, $tcmd, $req, $rsp ) = @$_; + my $out = $rsp; + if ($verify) { + $out =~ s/\.rsp$/.tst/; + } + if ( $req eq "" ) { + print STDERR + "WARNING: Request file for $tname missing: test skipped\n"; + $skipcnt++; + next; + } + if ( $verify && $rsp eq "" ) { + print STDERR + "WARNING: Response file for $tname missing: test skipped\n"; + $skipcnt++; + next; + } + elsif ( !$verify ) { + if ( $rsp ne "" ) { + print STDERR "WARNING: Response file for $tname deleted\n"; + unlink $rsp; + } + $out = $req; + $out =~ s|/req/(\S+)\.req|/$rspdir/$1.rsp|; + my $outdir = $out; + $outdir =~ s|/[^/]*$||; + if ( !-d $outdir ) { + print STDERR "DEBUG: Creating directory $outdir\n" if $debug; + mkdir($outdir) || die "Can't create directory $outdir"; + } + } + my $cmd = "$cmd_prefix$tprefix$tcmd "; + if ( $tcmd =~ /-f$/ ) { + $cmd .= "$req $out"; + } + else { + $cmd .= "<$req >$out"; + } + print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify ); + system($cmd); + if ( $? != 0 ) { + print STDERR + "WARNING: error executing test $tname for command: $cmd\n"; + $runerr++; + next; + } + if ($verify) { + if ( exists $verify_special{$tname} ) { + my $vout = $rsp; + $vout =~ s/\.rsp$/.ver/; + $tcmd = $verify_special{$tname}; + $cmd = "$cmd_prefix$tprefix$tcmd "; + $cmd .= "<$out >$vout"; + system($cmd); + if ( $? != 0 ) { + print STDERR + "WARNING: error executing verify test $tname $cmd\n"; + $scheckrunerr++; + next; + } + my ( $fcount, $pcount ) = ( 0, 0 ); + open VER, "$vout"; + while () { + if (/^Result\s*=\s*(\S*)\s*$/i) + + { + if ( $1 eq "F" ) { + $fcount++; + } + else { + $pcount++; + } + } + } + close VER; + + unlink $vout; + if ( $fcount || $debug ) { + print STDERR "DEBUG: $tname, Pass=$pcount, Fail=$fcount\n"; + } + if ( $fcount || !$pcount ) { + $scheckerr++; + } + else { + $scheckok++; + } + + } + elsif ( !cmp_file( $tname, $rsp, $out ) ) { + $cmperr++; + } + else { + $cmpok++; + } + unlink $out; + } + } +} + +sub cmp_file { + my ( $tname, $rsp, $tst ) = @_; + my ( $rspf, $tstf ); + my ( $rspline, $tstline ); + if ( !open( $rspf, $rsp ) ) { + print STDERR "ERROR: can't open request file $rsp\n"; + return 0; + } + if ( !open( $tstf, $tst ) ) { + print STDERR "ERROR: can't open output file $tst\n"; + return 0; + } + for ( ; ; ) { + $rspline = next_line($rspf); + $tstline = next_line($tstf); + if ( !defined($rspline) && !defined($tstline) ) { + print STDERR "DEBUG: $tname file comparison OK\n" if $debug; + return 1; + } + if ( !defined($rspline) ) { + print STDERR "ERROR: $tname EOF on $rspf\n"; + return 0; + } + if ( !defined($tstline) ) { + print STDERR "ERROR: $tname EOF on $tstf\n"; + return 0; + } + + # Workaround for bug in RAND des2 test output */ + if ( $tstline =~ /^Key2 =/ && $rspline =~ /^Key1 =/ ) { + $rspline =~ s/^Key1/Key2/; + } + + if ( $tstline ne $rspline ) { + print STDERR "ERROR: $tname mismatch:\n"; + print STDERR "\t $tstline != $rspline\n"; + return 0; + } + } + return 1; +} + +sub next_line { + my ($in) = @_; + + while (<$in>) { + chomp; + + # Delete comments + s/#.*$//; + + # Ignore blank lines + next if (/^\s*$/); + + # Translate multiple space into one + s/\s+/ /g; + return $_; + } + return undef; +} diff --git a/fips/fipsld b/fips/fipsld new file mode 100755 index 0000000000..c71d4d95a5 --- /dev/null +++ b/fips/fipsld @@ -0,0 +1,170 @@ +#!/bin/sh -e +# +# Copyright (c) 2005-2007 The OpenSSL Project. +# +# Depending on output file name, the script either embeds fingerprint +# into libcrypto.so or static application. "Static" refers to static +# libcrypto.a, not [necessarily] application per se. +# +# Even though this script is called fipsld, it expects C compiler +# command line syntax and $FIPSLD_CC or $CC environment variable set +# and can even be used to compile source files. + +#set -x + +CC=${FIPSLD_CC:-${CC}} +[ -n "${CC}" ] || { echo '$CC is not defined'; exit 1; } + +# Initially -c wasn't intended to be interpreted here, but it might +# make life easier for those who want to build FIPS-ified applications +# with minimal [if any] modifications to their Makefiles... +( while [ "x$1" != "x" -a "x$1" != "x-c" -a "x$1" != "x-E" ]; do shift; done; + [ $# -ge 1 ] +) && exec ${CC} "$@" + +TARGET=`(while [ "x$1" != "x" -a "x$1" != "x-o" ]; do shift; done; echo $2)` + +# If using an auto-tooled (autoconf/automake/libtool) project, +# configure will fail when testing the compiler or even performing +# simple checks. Pass-through to compiler directly if application is +# is not being linked with libcrypto, allowing auto-tooled applications +# to utilize fipsld (e.g. CC=/usr/local/ssl/bin/fipsld FIPSLD_CC=gcc +# ./configure && make). But keep in mind[!] that if certified code +# resides in a shared library, then fipsld *may not* be used and +# end-developer should not modify application configuration and build +# procedures. This is because in-core fingerprint and associated +# procedures are already embedded into and executed in shared library +# context. +case `basename "${TARGET}"` in +libcrypto*|libfips*|*.dll) ;; +*) case "$*" in + *libcrypto.a*|*-lcrypto*|*fipscanister.o*) ;; + *) exec ${CC} "$@" ;; + esac +esac + +[ -n "${TARGET}" ] || { echo 'no -o specified'; exit 1; } + +# Turn on debugging output? +( while [ "x$1" != "x" -a "x$1" != "x-DDEBUG_FINGERPRINT_PREMAIN" ]; do shift; done; + [ $# -ge 1 ] +) && set -x + +THERE="`echo $0 | sed -e 's|[^/]*$||'`".. + +# fipscanister.o can appear in command line +CANISTER_O=`(while [ "x$1" != "x" ]; do case "$1" in *fipscanister.o) echo $1; exit;; esac; shift; done)` +if [ -z "${CANISTER_O}" ]; then + # If set, FIPSLIBDIR is location of installed validated FIPS module + if [ -n "${FIPSLIBDIR}" ]; then + CANISTER_O="${FIPSLIBDIR}/fipscanister.o" + elif [ -f "${THERE}/fips/fipscanister.o" ]; then + CANISTER_O="${THERE}/fips/fipscanister.o" + elif [ -f "${THERE}/lib/fipscanister.o" ]; then + CANISTER_O="${THERE}/lib/fipscanister.o" + fi + CANISTER_O_CMD="${CANISTER_O}" +fi +[ -f ${CANISTER_O} ] || { echo "unable to find ${CANISTER_O}"; exit 1; } + +PREMAIN_C=`dirname "${CANISTER_O}"`/fips_premain.c + +HMAC_KEY="etaonrishdlcupfm" + +case "`(uname -s) 2>/dev/null`" in +OSF1|IRIX*) _WL_PREMAIN="-Wl,-init,FINGERPRINT_premain" ;; +HP-UX) _WL_PREMAIN="-Wl,+init,FINGERPRINT_premain" ;; +AIX) _WL_PREMAIN="-Wl,-binitfini:FINGERPRINT_premain,-bnoobjreorder";; +Darwin) ( while [ "x$1" != "x" -a "x$1" != "x-dynamiclib" ]; do shift; done; + [ $# -ge 1 ] + ) && _WL_PREMAIN="-Wl,-init,_FINGERPRINT_premain" ;; +esac + +case "${TARGET}" in +[!/]*) TARGET=./${TARGET} ;; +esac + +case `basename "${TARGET}"` in +lib*|*.dll) # must be linking a shared lib... + # Shared lib creation can be taking place in the source + # directory only, but fipscanister.o can reside elsewhere... + FINGERTYPE="${THERE}/fips/fips_standalone_sha1" + + # verify fipspremain.c against its detached signature... + ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \ + diff -w "${PREMAIN_C}.sha1" - || \ + { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; } + # verify fipscanister.o against its detached signature... + ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \ + diff -w "${CANISTER_O}.sha1" - || \ + { echo "${CANISTER_O} fingerprint mismatch"; exit 1; } + + # Temporarily remove fipscanister.o from libcrypto.a! + # We are required to use the standalone copy... + if [ -f "${THERE}/libcrypto.a" ]; then + if ar d "${THERE}/libcrypto.a" fipscanister.o; then + (ranlib "${THERE}/libcrypto.a") 2>/dev/null || : + trap 'ar r "${THERE}/libcrypto.a" "${CANISTER_O}"; + (ranlib "${THERE}/libcrypto.a") 2>/dev/null || :; + sleep 1; + touch -c "${TARGET}"' 0 + fi + fi + + /bin/rm -f "${TARGET}" + ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \ + "${PREMAIN_C}" \ + ${_WL_PREMAIN} "$@" + + # generate signature... + SIG=`"${THERE}/fips/fips_premain_dso" "${TARGET}"` + /bin/rm -f "${TARGET}" + if [ -z "${SIG}" ]; then + echo "unable to collect signature"; exit 1 + fi + + # recompile with signature... + ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \ + -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \ + ${_WL_PREMAIN} "$@" + ;; + +*) # must be linking statically... + # Static linking can be taking place either in the source + # directory or off the installed binary target destination. + if [ -x "${THERE}/fips/fips_standalone_sha1" ]; then + FINGERTYPE="${THERE}/fips/fips_standalone_sha1" + else # Installed tree is expected to contain + # lib/fipscanister.o, lib/fipscanister.o.sha1 and + # lib/fips_premain.c [not to mention bin/openssl]. + FINGERTYPE="${THERE}/bin/openssl sha1 -hmac ${HMAC_KEY}" + fi + + # verify fipscanister.o against its detached signature... + ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \ + diff -w "${CANISTER_O}.sha1" - || \ + { echo "${CANISTER_O} fingerprint mismatch"; exit 1; } + + # verify fips_premain.c against its detached signature... + ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \ + diff -w "${PREMAIN_C}.sha1" - || \ + { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; } + + /bin/rm -f "${TARGET}" + ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \ + "${PREMAIN_C}" \ + ${_WL_PREMAIN} "$@" + + # generate signature... + SIG=`"${TARGET}"` + /bin/rm -f "${TARGET}" + if [ -z "${SIG}" ]; then + echo "unable to collect signature"; exit 1 + fi + + # recompile with signature... + ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \ + -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \ + ${_WL_PREMAIN} "$@" + ;; +esac diff --git a/fips/fipstests.bat b/fips/fipstests.bat new file mode 100644 index 0000000000..aae3b13fd1 --- /dev/null +++ b/fips/fipstests.bat @@ -0,0 +1,229 @@ +@echo off +rem Test vector run script +rem Auto generated by mkfipsscr.pl script +rem Do not edit + + +echo Running tests in .\testvectors\AES\req +if exist ".\testvectors\AES\rsp" rd /s /q ".\testvectors\AES\rsp" +md ".\testvectors\AES\rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCGFSbox128.req" ".\testvectors\AES\rsp\CBCGFSbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCGFSbox192.req" ".\testvectors\AES\rsp\CBCGFSbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCGFSbox256.req" ".\testvectors\AES\rsp\CBCGFSbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCKeySbox128.req" ".\testvectors\AES\rsp\CBCKeySbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCKeySbox192.req" ".\testvectors\AES\rsp\CBCKeySbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCKeySbox256.req" ".\testvectors\AES\rsp\CBCKeySbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCMCT128.req" ".\testvectors\AES\rsp\CBCMCT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCMCT192.req" ".\testvectors\AES\rsp\CBCMCT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCMCT256.req" ".\testvectors\AES\rsp\CBCMCT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCMMT128.req" ".\testvectors\AES\rsp\CBCMMT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCMMT192.req" ".\testvectors\AES\rsp\CBCMMT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCMMT256.req" ".\testvectors\AES\rsp\CBCMMT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCVarKey128.req" ".\testvectors\AES\rsp\CBCVarKey128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCVarKey192.req" ".\testvectors\AES\rsp\CBCVarKey192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCVarKey256.req" ".\testvectors\AES\rsp\CBCVarKey256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCVarTxt128.req" ".\testvectors\AES\rsp\CBCVarTxt128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCVarTxt192.req" ".\testvectors\AES\rsp\CBCVarTxt192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CBCVarTxt256.req" ".\testvectors\AES\rsp\CBCVarTxt256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128GFSbox128.req" ".\testvectors\AES\rsp\CFB128GFSbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128GFSbox192.req" ".\testvectors\AES\rsp\CFB128GFSbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128GFSbox256.req" ".\testvectors\AES\rsp\CFB128GFSbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128KeySbox128.req" ".\testvectors\AES\rsp\CFB128KeySbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128KeySbox192.req" ".\testvectors\AES\rsp\CFB128KeySbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128KeySbox256.req" ".\testvectors\AES\rsp\CFB128KeySbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128MCT128.req" ".\testvectors\AES\rsp\CFB128MCT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128MCT192.req" ".\testvectors\AES\rsp\CFB128MCT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128MCT256.req" ".\testvectors\AES\rsp\CFB128MCT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128MMT128.req" ".\testvectors\AES\rsp\CFB128MMT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128MMT192.req" ".\testvectors\AES\rsp\CFB128MMT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128MMT256.req" ".\testvectors\AES\rsp\CFB128MMT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128VarKey128.req" ".\testvectors\AES\rsp\CFB128VarKey128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128VarKey192.req" ".\testvectors\AES\rsp\CFB128VarKey192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128VarKey256.req" ".\testvectors\AES\rsp\CFB128VarKey256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128VarTxt128.req" ".\testvectors\AES\rsp\CFB128VarTxt128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128VarTxt192.req" ".\testvectors\AES\rsp\CFB128VarTxt192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB128VarTxt256.req" ".\testvectors\AES\rsp\CFB128VarTxt256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1GFSbox128.req" ".\testvectors\AES\rsp\CFB1GFSbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1GFSbox192.req" ".\testvectors\AES\rsp\CFB1GFSbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1GFSbox256.req" ".\testvectors\AES\rsp\CFB1GFSbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1KeySbox128.req" ".\testvectors\AES\rsp\CFB1KeySbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1KeySbox192.req" ".\testvectors\AES\rsp\CFB1KeySbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1KeySbox256.req" ".\testvectors\AES\rsp\CFB1KeySbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1MCT128.req" ".\testvectors\AES\rsp\CFB1MCT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1MCT192.req" ".\testvectors\AES\rsp\CFB1MCT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1MCT256.req" ".\testvectors\AES\rsp\CFB1MCT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1MMT128.req" ".\testvectors\AES\rsp\CFB1MMT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1MMT192.req" ".\testvectors\AES\rsp\CFB1MMT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1MMT256.req" ".\testvectors\AES\rsp\CFB1MMT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1VarKey128.req" ".\testvectors\AES\rsp\CFB1VarKey128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1VarKey192.req" ".\testvectors\AES\rsp\CFB1VarKey192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1VarKey256.req" ".\testvectors\AES\rsp\CFB1VarKey256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1VarTxt128.req" ".\testvectors\AES\rsp\CFB1VarTxt128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1VarTxt192.req" ".\testvectors\AES\rsp\CFB1VarTxt192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB1VarTxt256.req" ".\testvectors\AES\rsp\CFB1VarTxt256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8GFSbox128.req" ".\testvectors\AES\rsp\CFB8GFSbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8GFSbox192.req" ".\testvectors\AES\rsp\CFB8GFSbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8GFSbox256.req" ".\testvectors\AES\rsp\CFB8GFSbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8KeySbox128.req" ".\testvectors\AES\rsp\CFB8KeySbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8KeySbox192.req" ".\testvectors\AES\rsp\CFB8KeySbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8KeySbox256.req" ".\testvectors\AES\rsp\CFB8KeySbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8MCT128.req" ".\testvectors\AES\rsp\CFB8MCT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8MCT192.req" ".\testvectors\AES\rsp\CFB8MCT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8MCT256.req" ".\testvectors\AES\rsp\CFB8MCT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8MMT128.req" ".\testvectors\AES\rsp\CFB8MMT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8MMT192.req" ".\testvectors\AES\rsp\CFB8MMT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8MMT256.req" ".\testvectors\AES\rsp\CFB8MMT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8VarKey128.req" ".\testvectors\AES\rsp\CFB8VarKey128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8VarKey192.req" ".\testvectors\AES\rsp\CFB8VarKey192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8VarKey256.req" ".\testvectors\AES\rsp\CFB8VarKey256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8VarTxt128.req" ".\testvectors\AES\rsp\CFB8VarTxt128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8VarTxt192.req" ".\testvectors\AES\rsp\CFB8VarTxt192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\CFB8VarTxt256.req" ".\testvectors\AES\rsp\CFB8VarTxt256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBGFSbox128.req" ".\testvectors\AES\rsp\ECBGFSbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBGFSbox192.req" ".\testvectors\AES\rsp\ECBGFSbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBGFSbox256.req" ".\testvectors\AES\rsp\ECBGFSbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBKeySbox128.req" ".\testvectors\AES\rsp\ECBKeySbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBKeySbox192.req" ".\testvectors\AES\rsp\ECBKeySbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBKeySbox256.req" ".\testvectors\AES\rsp\ECBKeySbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBMCT128.req" ".\testvectors\AES\rsp\ECBMCT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBMCT192.req" ".\testvectors\AES\rsp\ECBMCT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBMCT256.req" ".\testvectors\AES\rsp\ECBMCT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBMMT128.req" ".\testvectors\AES\rsp\ECBMMT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBMMT192.req" ".\testvectors\AES\rsp\ECBMMT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBMMT256.req" ".\testvectors\AES\rsp\ECBMMT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBVarKey128.req" ".\testvectors\AES\rsp\ECBVarKey128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBVarKey192.req" ".\testvectors\AES\rsp\ECBVarKey192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBVarKey256.req" ".\testvectors\AES\rsp\ECBVarKey256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBVarTxt128.req" ".\testvectors\AES\rsp\ECBVarTxt128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBVarTxt192.req" ".\testvectors\AES\rsp\ECBVarTxt192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\ECBVarTxt256.req" ".\testvectors\AES\rsp\ECBVarTxt256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBGFSbox128.req" ".\testvectors\AES\rsp\OFBGFSbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBGFSbox192.req" ".\testvectors\AES\rsp\OFBGFSbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBGFSbox256.req" ".\testvectors\AES\rsp\OFBGFSbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBKeySbox128.req" ".\testvectors\AES\rsp\OFBKeySbox128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBKeySbox192.req" ".\testvectors\AES\rsp\OFBKeySbox192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBKeySbox256.req" ".\testvectors\AES\rsp\OFBKeySbox256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBMCT128.req" ".\testvectors\AES\rsp\OFBMCT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBMCT192.req" ".\testvectors\AES\rsp\OFBMCT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBMCT256.req" ".\testvectors\AES\rsp\OFBMCT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBMMT128.req" ".\testvectors\AES\rsp\OFBMMT128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBMMT192.req" ".\testvectors\AES\rsp\OFBMMT192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBMMT256.req" ".\testvectors\AES\rsp\OFBMMT256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBVarKey128.req" ".\testvectors\AES\rsp\OFBVarKey128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBVarKey192.req" ".\testvectors\AES\rsp\OFBVarKey192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBVarKey256.req" ".\testvectors\AES\rsp\OFBVarKey256.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBVarTxt128.req" ".\testvectors\AES\rsp\OFBVarTxt128.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBVarTxt192.req" ".\testvectors\AES\rsp\OFBVarTxt192.rsp" +..\out32dll\fips_aesavs -f ".\testvectors\AES\req\OFBVarTxt256.req" ".\testvectors\AES\rsp\OFBVarTxt256.rsp" + +echo Running tests in .\testvectors\DSA\req +if exist ".\testvectors\DSA\rsp" rd /s /q ".\testvectors\DSA\rsp" +md ".\testvectors\DSA\rsp" +..\out32dll\fips_dssvs keypair < ".\testvectors\DSA\req\KeyPair.req" > ".\testvectors\DSA\rsp\KeyPair.rsp" +..\out32dll\fips_dssvs pqg < ".\testvectors\DSA\req\PQGGen.req" > ".\testvectors\DSA\rsp\PQGGen.rsp" +..\out32dll\fips_dssvs siggen < ".\testvectors\DSA\req\SigGen.req" > ".\testvectors\DSA\rsp\SigGen.rsp" +..\out32dll\fips_dssvs sigver < ".\testvectors\DSA\req\SigVer.req" > ".\testvectors\DSA\rsp\SigVer.rsp" + +echo Running tests in .\testvectors\HMAC\req +if exist ".\testvectors\HMAC\rsp" rd /s /q ".\testvectors\HMAC\rsp" +md ".\testvectors\HMAC\rsp" +..\out32dll\fips_hmactest < ".\testvectors\HMAC\req\HMAC.req" > ".\testvectors\HMAC\rsp\HMAC.rsp" + +echo Running tests in .\testvectors\RNG\req +if exist ".\testvectors\RNG\rsp" rd /s /q ".\testvectors\RNG\rsp" +md ".\testvectors\RNG\rsp" +..\out32dll\fips_rngvs mct < ".\testvectors\RNG\req\ANSI931_AES128MCT.req" > ".\testvectors\RNG\rsp\ANSI931_AES128MCT.rsp" +..\out32dll\fips_rngvs vst < ".\testvectors\RNG\req\ANSI931_AES128VST.req" > ".\testvectors\RNG\rsp\ANSI931_AES128VST.rsp" +..\out32dll\fips_rngvs mct < ".\testvectors\RNG\req\ANSI931_AES192MCT.req" > ".\testvectors\RNG\rsp\ANSI931_AES192MCT.rsp" +..\out32dll\fips_rngvs vst < ".\testvectors\RNG\req\ANSI931_AES192VST.req" > ".\testvectors\RNG\rsp\ANSI931_AES192VST.rsp" +..\out32dll\fips_rngvs mct < ".\testvectors\RNG\req\ANSI931_AES256MCT.req" > ".\testvectors\RNG\rsp\ANSI931_AES256MCT.rsp" +..\out32dll\fips_rngvs vst < ".\testvectors\RNG\req\ANSI931_AES256VST.req" > ".\testvectors\RNG\rsp\ANSI931_AES256VST.rsp" + +echo Running tests in .\testvectors\RSA\req +if exist ".\testvectors\RSA\rsp" rd /s /q ".\testvectors\RSA\rsp" +md ".\testvectors\RSA\rsp" +..\out32dll\fips_rsagtest < ".\testvectors\RSA\req\KeyGenRSA.req" > ".\testvectors\RSA\rsp\KeyGenRSA.rsp" +..\out32dll\fips_rsastest < ".\testvectors\RSA\req\SigGen15.req" > ".\testvectors\RSA\rsp\SigGen15.rsp" +..\out32dll\fips_rsastest -saltlen 0 < ".\testvectors\RSA\req\SigGenPSS.req" > ".\testvectors\RSA\rsp\SigGenPSS.rsp" +..\out32dll\fips_rsastest -x931 < ".\testvectors\RSA\req\SigGenRSA.req" > ".\testvectors\RSA\rsp\SigGenRSA.rsp" +..\out32dll\fips_rsavtest < ".\testvectors\RSA\req\SigVer15.req" > ".\testvectors\RSA\rsp\SigVer15.rsp" +..\out32dll\fips_rsavtest -saltlen 0 < ".\testvectors\RSA\req\SigVerPSS.req" > ".\testvectors\RSA\rsp\SigVerPSS.rsp" +..\out32dll\fips_rsavtest -x931 < ".\testvectors\RSA\req\SigVerRSA.req" > ".\testvectors\RSA\rsp\SigVerRSA.rsp" + +echo Running tests in .\testvectors\SHA\req +if exist ".\testvectors\SHA\rsp" rd /s /q ".\testvectors\SHA\rsp" +md ".\testvectors\SHA\rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA1LongMsg.req" > ".\testvectors\SHA\rsp\SHA1LongMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA1Monte.req" > ".\testvectors\SHA\rsp\SHA1Monte.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA1ShortMsg.req" > ".\testvectors\SHA\rsp\SHA1ShortMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA224LongMsg.req" > ".\testvectors\SHA\rsp\SHA224LongMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA224Monte.req" > ".\testvectors\SHA\rsp\SHA224Monte.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA224ShortMsg.req" > ".\testvectors\SHA\rsp\SHA224ShortMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA256LongMsg.req" > ".\testvectors\SHA\rsp\SHA256LongMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA256Monte.req" > ".\testvectors\SHA\rsp\SHA256Monte.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA256ShortMsg.req" > ".\testvectors\SHA\rsp\SHA256ShortMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA384LongMsg.req" > ".\testvectors\SHA\rsp\SHA384LongMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA384Monte.req" > ".\testvectors\SHA\rsp\SHA384Monte.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA384ShortMsg.req" > ".\testvectors\SHA\rsp\SHA384ShortMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA512LongMsg.req" > ".\testvectors\SHA\rsp\SHA512LongMsg.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA512Monte.req" > ".\testvectors\SHA\rsp\SHA512Monte.rsp" +..\out32dll\fips_shatest < ".\testvectors\SHA\req\SHA512ShortMsg.req" > ".\testvectors\SHA\rsp\SHA512ShortMsg.rsp" + +echo Running tests in .\testvectors\TDES\req +if exist ".\testvectors\TDES\rsp" rd /s /q ".\testvectors\TDES\rsp" +md ".\testvectors\TDES\rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCinvperm.req" ".\testvectors\TDES\rsp\TCBCinvperm.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCMMT1.req" ".\testvectors\TDES\rsp\TCBCMMT1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCMMT2.req" ".\testvectors\TDES\rsp\TCBCMMT2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCMMT3.req" ".\testvectors\TDES\rsp\TCBCMMT3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCMonte1.req" ".\testvectors\TDES\rsp\TCBCMonte1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCMonte2.req" ".\testvectors\TDES\rsp\TCBCMonte2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCMonte3.req" ".\testvectors\TDES\rsp\TCBCMonte3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCpermop.req" ".\testvectors\TDES\rsp\TCBCpermop.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCsubtab.req" ".\testvectors\TDES\rsp\TCBCsubtab.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCvarkey.req" ".\testvectors\TDES\rsp\TCBCvarkey.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCBCvartext.req" ".\testvectors\TDES\rsp\TCBCvartext.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64invperm.req" ".\testvectors\TDES\rsp\TCFB64invperm.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64MMT1.req" ".\testvectors\TDES\rsp\TCFB64MMT1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64MMT2.req" ".\testvectors\TDES\rsp\TCFB64MMT2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64MMT3.req" ".\testvectors\TDES\rsp\TCFB64MMT3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64Monte1.req" ".\testvectors\TDES\rsp\TCFB64Monte1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64Monte2.req" ".\testvectors\TDES\rsp\TCFB64Monte2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64Monte3.req" ".\testvectors\TDES\rsp\TCFB64Monte3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64permop.req" ".\testvectors\TDES\rsp\TCFB64permop.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64subtab.req" ".\testvectors\TDES\rsp\TCFB64subtab.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64varkey.req" ".\testvectors\TDES\rsp\TCFB64varkey.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB64vartext.req" ".\testvectors\TDES\rsp\TCFB64vartext.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8invperm.req" ".\testvectors\TDES\rsp\TCFB8invperm.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8MMT1.req" ".\testvectors\TDES\rsp\TCFB8MMT1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8MMT2.req" ".\testvectors\TDES\rsp\TCFB8MMT2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8MMT3.req" ".\testvectors\TDES\rsp\TCFB8MMT3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8Monte1.req" ".\testvectors\TDES\rsp\TCFB8Monte1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8Monte2.req" ".\testvectors\TDES\rsp\TCFB8Monte2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8Monte3.req" ".\testvectors\TDES\rsp\TCFB8Monte3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8permop.req" ".\testvectors\TDES\rsp\TCFB8permop.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8subtab.req" ".\testvectors\TDES\rsp\TCFB8subtab.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8varkey.req" ".\testvectors\TDES\rsp\TCFB8varkey.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TCFB8vartext.req" ".\testvectors\TDES\rsp\TCFB8vartext.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBinvperm.req" ".\testvectors\TDES\rsp\TECBinvperm.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBMMT1.req" ".\testvectors\TDES\rsp\TECBMMT1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBMMT2.req" ".\testvectors\TDES\rsp\TECBMMT2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBMMT3.req" ".\testvectors\TDES\rsp\TECBMMT3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBMonte1.req" ".\testvectors\TDES\rsp\TECBMonte1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBMonte2.req" ".\testvectors\TDES\rsp\TECBMonte2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBMonte3.req" ".\testvectors\TDES\rsp\TECBMonte3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBpermop.req" ".\testvectors\TDES\rsp\TECBpermop.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBsubtab.req" ".\testvectors\TDES\rsp\TECBsubtab.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBvarkey.req" ".\testvectors\TDES\rsp\TECBvarkey.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TECBvartext.req" ".\testvectors\TDES\rsp\TECBvartext.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBinvperm.req" ".\testvectors\TDES\rsp\TOFBinvperm.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBMMT1.req" ".\testvectors\TDES\rsp\TOFBMMT1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBMMT2.req" ".\testvectors\TDES\rsp\TOFBMMT2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBMMT3.req" ".\testvectors\TDES\rsp\TOFBMMT3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBMonte1.req" ".\testvectors\TDES\rsp\TOFBMonte1.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBMonte2.req" ".\testvectors\TDES\rsp\TOFBMonte2.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBMonte3.req" ".\testvectors\TDES\rsp\TOFBMonte3.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBpermop.req" ".\testvectors\TDES\rsp\TOFBpermop.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBsubtab.req" ".\testvectors\TDES\rsp\TOFBsubtab.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBvarkey.req" ".\testvectors\TDES\rsp\TOFBvarkey.rsp" +..\out32dll\fips_desmovs -f ".\testvectors\TDES\req\TOFBvartext.req" ".\testvectors\TDES\rsp\TOFBvartext.rsp" diff --git a/fips/fipstests.sh b/fips/fipstests.sh new file mode 100644 index 0000000000..a351446942 --- /dev/null +++ b/fips/fipstests.sh @@ -0,0 +1,400 @@ +#!/bin/sh + +# Test vector run script +# Auto generated by mkfipsscr.pl script +# Do not edit + + +echo Running tests in "./testvectors/AES/req" +rm -rf "./testvectors/AES/rsp" +mkdir "./testvectors/AES/rsp" + +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox128.req" "./testvectors/AES/rsp/CBCGFSbox128.rsp" || { echo "./testvectors/AES/req/CBCGFSbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox192.req" "./testvectors/AES/rsp/CBCGFSbox192.rsp" || { echo "./testvectors/AES/req/CBCGFSbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox256.req" "./testvectors/AES/rsp/CBCGFSbox256.rsp" || { echo "./testvectors/AES/req/CBCGFSbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox128.req" "./testvectors/AES/rsp/CBCKeySbox128.rsp" || { echo "./testvectors/AES/req/CBCKeySbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox192.req" "./testvectors/AES/rsp/CBCKeySbox192.rsp" || { echo "./testvectors/AES/req/CBCKeySbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox256.req" "./testvectors/AES/rsp/CBCKeySbox256.rsp" || { echo "./testvectors/AES/req/CBCKeySbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT128.req" "./testvectors/AES/rsp/CBCMCT128.rsp" || { echo "./testvectors/AES/req/CBCMCT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT192.req" "./testvectors/AES/rsp/CBCMCT192.rsp" || { echo "./testvectors/AES/req/CBCMCT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT256.req" "./testvectors/AES/rsp/CBCMCT256.rsp" || { echo "./testvectors/AES/req/CBCMCT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT128.req" "./testvectors/AES/rsp/CBCMMT128.rsp" || { echo "./testvectors/AES/req/CBCMMT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT192.req" "./testvectors/AES/rsp/CBCMMT192.rsp" || { echo "./testvectors/AES/req/CBCMMT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT256.req" "./testvectors/AES/rsp/CBCMMT256.rsp" || { echo "./testvectors/AES/req/CBCMMT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey128.req" "./testvectors/AES/rsp/CBCVarKey128.rsp" || { echo "./testvectors/AES/req/CBCVarKey128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey192.req" "./testvectors/AES/rsp/CBCVarKey192.rsp" || { echo "./testvectors/AES/req/CBCVarKey192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey256.req" "./testvectors/AES/rsp/CBCVarKey256.rsp" || { echo "./testvectors/AES/req/CBCVarKey256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt128.req" "./testvectors/AES/rsp/CBCVarTxt128.rsp" || { echo "./testvectors/AES/req/CBCVarTxt128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt192.req" "./testvectors/AES/rsp/CBCVarTxt192.rsp" || { echo "./testvectors/AES/req/CBCVarTxt192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt256.req" "./testvectors/AES/rsp/CBCVarTxt256.rsp" || { echo "./testvectors/AES/req/CBCVarTxt256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox128.req" "./testvectors/AES/rsp/CFB128GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox192.req" "./testvectors/AES/rsp/CFB128GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox256.req" "./testvectors/AES/rsp/CFB128GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox128.req" "./testvectors/AES/rsp/CFB128KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox192.req" "./testvectors/AES/rsp/CFB128KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox256.req" "./testvectors/AES/rsp/CFB128KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT128.req" "./testvectors/AES/rsp/CFB128MCT128.rsp" || { echo "./testvectors/AES/req/CFB128MCT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT192.req" "./testvectors/AES/rsp/CFB128MCT192.rsp" || { echo "./testvectors/AES/req/CFB128MCT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT256.req" "./testvectors/AES/rsp/CFB128MCT256.rsp" || { echo "./testvectors/AES/req/CFB128MCT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT128.req" "./testvectors/AES/rsp/CFB128MMT128.rsp" || { echo "./testvectors/AES/req/CFB128MMT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT192.req" "./testvectors/AES/rsp/CFB128MMT192.rsp" || { echo "./testvectors/AES/req/CFB128MMT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT256.req" "./testvectors/AES/rsp/CFB128MMT256.rsp" || { echo "./testvectors/AES/req/CFB128MMT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey128.req" "./testvectors/AES/rsp/CFB128VarKey128.rsp" || { echo "./testvectors/AES/req/CFB128VarKey128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey192.req" "./testvectors/AES/rsp/CFB128VarKey192.rsp" || { echo "./testvectors/AES/req/CFB128VarKey192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey256.req" "./testvectors/AES/rsp/CFB128VarKey256.rsp" || { echo "./testvectors/AES/req/CFB128VarKey256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt128.req" "./testvectors/AES/rsp/CFB128VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt192.req" "./testvectors/AES/rsp/CFB128VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt256.req" "./testvectors/AES/rsp/CFB128VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox128.req" "./testvectors/AES/rsp/CFB1GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox192.req" "./testvectors/AES/rsp/CFB1GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox256.req" "./testvectors/AES/rsp/CFB1GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox128.req" "./testvectors/AES/rsp/CFB1KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox192.req" "./testvectors/AES/rsp/CFB1KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox256.req" "./testvectors/AES/rsp/CFB1KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT128.req" "./testvectors/AES/rsp/CFB1MCT128.rsp" || { echo "./testvectors/AES/req/CFB1MCT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT192.req" "./testvectors/AES/rsp/CFB1MCT192.rsp" || { echo "./testvectors/AES/req/CFB1MCT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT256.req" "./testvectors/AES/rsp/CFB1MCT256.rsp" || { echo "./testvectors/AES/req/CFB1MCT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT128.req" "./testvectors/AES/rsp/CFB1MMT128.rsp" || { echo "./testvectors/AES/req/CFB1MMT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT192.req" "./testvectors/AES/rsp/CFB1MMT192.rsp" || { echo "./testvectors/AES/req/CFB1MMT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT256.req" "./testvectors/AES/rsp/CFB1MMT256.rsp" || { echo "./testvectors/AES/req/CFB1MMT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey128.req" "./testvectors/AES/rsp/CFB1VarKey128.rsp" || { echo "./testvectors/AES/req/CFB1VarKey128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey192.req" "./testvectors/AES/rsp/CFB1VarKey192.rsp" || { echo "./testvectors/AES/req/CFB1VarKey192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey256.req" "./testvectors/AES/rsp/CFB1VarKey256.rsp" || { echo "./testvectors/AES/req/CFB1VarKey256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt128.req" "./testvectors/AES/rsp/CFB1VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt192.req" "./testvectors/AES/rsp/CFB1VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt256.req" "./testvectors/AES/rsp/CFB1VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox128.req" "./testvectors/AES/rsp/CFB8GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox192.req" "./testvectors/AES/rsp/CFB8GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox256.req" "./testvectors/AES/rsp/CFB8GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox128.req" "./testvectors/AES/rsp/CFB8KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox192.req" "./testvectors/AES/rsp/CFB8KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox256.req" "./testvectors/AES/rsp/CFB8KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT128.req" "./testvectors/AES/rsp/CFB8MCT128.rsp" || { echo "./testvectors/AES/req/CFB8MCT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT192.req" "./testvectors/AES/rsp/CFB8MCT192.rsp" || { echo "./testvectors/AES/req/CFB8MCT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT256.req" "./testvectors/AES/rsp/CFB8MCT256.rsp" || { echo "./testvectors/AES/req/CFB8MCT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT128.req" "./testvectors/AES/rsp/CFB8MMT128.rsp" || { echo "./testvectors/AES/req/CFB8MMT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT192.req" "./testvectors/AES/rsp/CFB8MMT192.rsp" || { echo "./testvectors/AES/req/CFB8MMT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT256.req" "./testvectors/AES/rsp/CFB8MMT256.rsp" || { echo "./testvectors/AES/req/CFB8MMT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey128.req" "./testvectors/AES/rsp/CFB8VarKey128.rsp" || { echo "./testvectors/AES/req/CFB8VarKey128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey192.req" "./testvectors/AES/rsp/CFB8VarKey192.rsp" || { echo "./testvectors/AES/req/CFB8VarKey192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey256.req" "./testvectors/AES/rsp/CFB8VarKey256.rsp" || { echo "./testvectors/AES/req/CFB8VarKey256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt128.req" "./testvectors/AES/rsp/CFB8VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt192.req" "./testvectors/AES/rsp/CFB8VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt256.req" "./testvectors/AES/rsp/CFB8VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox128.req" "./testvectors/AES/rsp/ECBGFSbox128.rsp" || { echo "./testvectors/AES/req/ECBGFSbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox192.req" "./testvectors/AES/rsp/ECBGFSbox192.rsp" || { echo "./testvectors/AES/req/ECBGFSbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox256.req" "./testvectors/AES/rsp/ECBGFSbox256.rsp" || { echo "./testvectors/AES/req/ECBGFSbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox128.req" "./testvectors/AES/rsp/ECBKeySbox128.rsp" || { echo "./testvectors/AES/req/ECBKeySbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox192.req" "./testvectors/AES/rsp/ECBKeySbox192.rsp" || { echo "./testvectors/AES/req/ECBKeySbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox256.req" "./testvectors/AES/rsp/ECBKeySbox256.rsp" || { echo "./testvectors/AES/req/ECBKeySbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT128.req" "./testvectors/AES/rsp/ECBMCT128.rsp" || { echo "./testvectors/AES/req/ECBMCT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT192.req" "./testvectors/AES/rsp/ECBMCT192.rsp" || { echo "./testvectors/AES/req/ECBMCT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT256.req" "./testvectors/AES/rsp/ECBMCT256.rsp" || { echo "./testvectors/AES/req/ECBMCT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT128.req" "./testvectors/AES/rsp/ECBMMT128.rsp" || { echo "./testvectors/AES/req/ECBMMT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT192.req" "./testvectors/AES/rsp/ECBMMT192.rsp" || { echo "./testvectors/AES/req/ECBMMT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT256.req" "./testvectors/AES/rsp/ECBMMT256.rsp" || { echo "./testvectors/AES/req/ECBMMT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey128.req" "./testvectors/AES/rsp/ECBVarKey128.rsp" || { echo "./testvectors/AES/req/ECBVarKey128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey192.req" "./testvectors/AES/rsp/ECBVarKey192.rsp" || { echo "./testvectors/AES/req/ECBVarKey192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey256.req" "./testvectors/AES/rsp/ECBVarKey256.rsp" || { echo "./testvectors/AES/req/ECBVarKey256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt128.req" "./testvectors/AES/rsp/ECBVarTxt128.rsp" || { echo "./testvectors/AES/req/ECBVarTxt128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt192.req" "./testvectors/AES/rsp/ECBVarTxt192.rsp" || { echo "./testvectors/AES/req/ECBVarTxt192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt256.req" "./testvectors/AES/rsp/ECBVarTxt256.rsp" || { echo "./testvectors/AES/req/ECBVarTxt256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox128.req" "./testvectors/AES/rsp/OFBGFSbox128.rsp" || { echo "./testvectors/AES/req/OFBGFSbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox192.req" "./testvectors/AES/rsp/OFBGFSbox192.rsp" || { echo "./testvectors/AES/req/OFBGFSbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox256.req" "./testvectors/AES/rsp/OFBGFSbox256.rsp" || { echo "./testvectors/AES/req/OFBGFSbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox128.req" "./testvectors/AES/rsp/OFBKeySbox128.rsp" || { echo "./testvectors/AES/req/OFBKeySbox128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox192.req" "./testvectors/AES/rsp/OFBKeySbox192.rsp" || { echo "./testvectors/AES/req/OFBKeySbox192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox256.req" "./testvectors/AES/rsp/OFBKeySbox256.rsp" || { echo "./testvectors/AES/req/OFBKeySbox256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT128.req" "./testvectors/AES/rsp/OFBMCT128.rsp" || { echo "./testvectors/AES/req/OFBMCT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT192.req" "./testvectors/AES/rsp/OFBMCT192.rsp" || { echo "./testvectors/AES/req/OFBMCT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT256.req" "./testvectors/AES/rsp/OFBMCT256.rsp" || { echo "./testvectors/AES/req/OFBMCT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT128.req" "./testvectors/AES/rsp/OFBMMT128.rsp" || { echo "./testvectors/AES/req/OFBMMT128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT192.req" "./testvectors/AES/rsp/OFBMMT192.rsp" || { echo "./testvectors/AES/req/OFBMMT192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT256.req" "./testvectors/AES/rsp/OFBMMT256.rsp" || { echo "./testvectors/AES/req/OFBMMT256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey128.req" "./testvectors/AES/rsp/OFBVarKey128.rsp" || { echo "./testvectors/AES/req/OFBVarKey128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey192.req" "./testvectors/AES/rsp/OFBVarKey192.rsp" || { echo "./testvectors/AES/req/OFBVarKey192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey256.req" "./testvectors/AES/rsp/OFBVarKey256.rsp" || { echo "./testvectors/AES/req/OFBVarKey256.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt128.req" "./testvectors/AES/rsp/OFBVarTxt128.rsp" || { echo "./testvectors/AES/req/OFBVarTxt128.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt192.req" "./testvectors/AES/rsp/OFBVarTxt192.rsp" || { echo "./testvectors/AES/req/OFBVarTxt192.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt256.req" "./testvectors/AES/rsp/OFBVarTxt256.rsp" || { echo "./testvectors/AES/req/OFBVarTxt256.req failure" ; exit 1 +} + +echo Running tests in "./testvectors/DSA/req" +rm -rf "./testvectors/DSA/rsp" +mkdir "./testvectors/DSA/rsp" + +../util/shlib_wrap.sh ../test/fips_dssvs keypair < "./testvectors/DSA/req/KeyPair.req" > "./testvectors/DSA/rsp/KeyPair.rsp" || { echo "./testvectors/DSA/req/KeyPair.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_dssvs pqg < "./testvectors/DSA/req/PQGGen.req" > "./testvectors/DSA/rsp/PQGGen.rsp" || { echo "./testvectors/DSA/req/PQGGen.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_dssvs siggen < "./testvectors/DSA/req/SigGen.req" > "./testvectors/DSA/rsp/SigGen.rsp" || { echo "./testvectors/DSA/req/SigGen.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_dssvs sigver < "./testvectors/DSA/req/SigVer.req" > "./testvectors/DSA/rsp/SigVer.rsp" || { echo "./testvectors/DSA/req/SigVer.req failure" ; exit 1; } + +echo Running tests in "./testvectors/HMAC/req" +rm -rf "./testvectors/HMAC/rsp" +mkdir "./testvectors/HMAC/rsp" + +../util/shlib_wrap.sh ../test/fips_hmactest < "./testvectors/HMAC/req/HMAC.req" > "./testvectors/HMAC/rsp/HMAC.rsp" || { echo "./testvectors/HMAC/req/HMAC.req failure" ; exit 1; } + +echo Running tests in "./testvectors/RNG/req" +rm -rf "./testvectors/RNG/rsp" +mkdir "./testvectors/RNG/rsp" + +../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES128MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES128MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES128MCT.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES128VST.req" > "./testvectors/RNG/rsp/ANSI931_AES128VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES128VST.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES192MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES192MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES192MCT.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES192VST.req" > "./testvectors/RNG/rsp/ANSI931_AES192VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES192VST.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES256MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES256MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES256MCT.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES256VST.req" > "./testvectors/RNG/rsp/ANSI931_AES256VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES256VST.req failure" ; exit 1; } + +echo Running tests in "./testvectors/RSA/req" +rm -rf "./testvectors/RSA/rsp" +mkdir "./testvectors/RSA/rsp" + +../util/shlib_wrap.sh ../test/fips_rsagtest < "./testvectors/RSA/req/KeyGenRSA.req" > "./testvectors/RSA/rsp/KeyGenRSA.rsp" || { echo "./testvectors/RSA/req/KeyGenRSA.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rsastest < "./testvectors/RSA/req/SigGen15.req" > "./testvectors/RSA/rsp/SigGen15.rsp" || { echo "./testvectors/RSA/req/SigGen15.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rsastest -saltlen 0 < "./testvectors/RSA/req/SigGenPSS.req" > "./testvectors/RSA/rsp/SigGenPSS.rsp" || { echo "./testvectors/RSA/req/SigGenPSS.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rsastest -x931 < "./testvectors/RSA/req/SigGenRSA.req" > "./testvectors/RSA/rsp/SigGenRSA.rsp" || { echo "./testvectors/RSA/req/SigGenRSA.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rsavtest < "./testvectors/RSA/req/SigVer15.req" > "./testvectors/RSA/rsp/SigVer15.rsp" || { echo "./testvectors/RSA/req/SigVer15.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rsavtest -saltlen 0 < "./testvectors/RSA/req/SigVerPSS.req" > "./testvectors/RSA/rsp/SigVerPSS.rsp" || { echo "./testvectors/RSA/req/SigVerPSS.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_rsavtest -x931 < "./testvectors/RSA/req/SigVerRSA.req" > "./testvectors/RSA/rsp/SigVerRSA.rsp" || { echo "./testvectors/RSA/req/SigVerRSA.req failure" ; exit 1; } + +echo Running tests in "./testvectors/SHA/req" +rm -rf "./testvectors/SHA/rsp" +mkdir "./testvectors/SHA/rsp" + +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1LongMsg.req" > "./testvectors/SHA/rsp/SHA1LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA1LongMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1Monte.req" > "./testvectors/SHA/rsp/SHA1Monte.rsp" || { echo "./testvectors/SHA/req/SHA1Monte.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1ShortMsg.req" > "./testvectors/SHA/rsp/SHA1ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA1ShortMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224LongMsg.req" > "./testvectors/SHA/rsp/SHA224LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA224LongMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224Monte.req" > "./testvectors/SHA/rsp/SHA224Monte.rsp" || { echo "./testvectors/SHA/req/SHA224Monte.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224ShortMsg.req" > "./testvectors/SHA/rsp/SHA224ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA224ShortMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256LongMsg.req" > "./testvectors/SHA/rsp/SHA256LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA256LongMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256Monte.req" > "./testvectors/SHA/rsp/SHA256Monte.rsp" || { echo "./testvectors/SHA/req/SHA256Monte.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256ShortMsg.req" > "./testvectors/SHA/rsp/SHA256ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA256ShortMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384LongMsg.req" > "./testvectors/SHA/rsp/SHA384LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA384LongMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384Monte.req" > "./testvectors/SHA/rsp/SHA384Monte.rsp" || { echo "./testvectors/SHA/req/SHA384Monte.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384ShortMsg.req" > "./testvectors/SHA/rsp/SHA384ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA384ShortMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512LongMsg.req" > "./testvectors/SHA/rsp/SHA512LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA512LongMsg.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512Monte.req" > "./testvectors/SHA/rsp/SHA512Monte.rsp" || { echo "./testvectors/SHA/req/SHA512Monte.req failure" ; exit 1; } +../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512ShortMsg.req" > "./testvectors/SHA/rsp/SHA512ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA512ShortMsg.req failure" ; exit 1; } + +echo Running tests in "./testvectors/TDES/req" +rm -rf "./testvectors/TDES/rsp" +mkdir "./testvectors/TDES/rsp" + +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCinvperm.req" "./testvectors/TDES/rsp/TCBCinvperm.rsp" || { echo "./testvectors/TDES/req/TCBCinvperm.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT1.req" "./testvectors/TDES/rsp/TCBCMMT1.rsp" || { echo "./testvectors/TDES/req/TCBCMMT1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT2.req" "./testvectors/TDES/rsp/TCBCMMT2.rsp" || { echo "./testvectors/TDES/req/TCBCMMT2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT3.req" "./testvectors/TDES/rsp/TCBCMMT3.rsp" || { echo "./testvectors/TDES/req/TCBCMMT3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte1.req" "./testvectors/TDES/rsp/TCBCMonte1.rsp" || { echo "./testvectors/TDES/req/TCBCMonte1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte2.req" "./testvectors/TDES/rsp/TCBCMonte2.rsp" || { echo "./testvectors/TDES/req/TCBCMonte2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte3.req" "./testvectors/TDES/rsp/TCBCMonte3.rsp" || { echo "./testvectors/TDES/req/TCBCMonte3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCpermop.req" "./testvectors/TDES/rsp/TCBCpermop.rsp" || { echo "./testvectors/TDES/req/TCBCpermop.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCsubtab.req" "./testvectors/TDES/rsp/TCBCsubtab.rsp" || { echo "./testvectors/TDES/req/TCBCsubtab.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCvarkey.req" "./testvectors/TDES/rsp/TCBCvarkey.rsp" || { echo "./testvectors/TDES/req/TCBCvarkey.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCvartext.req" "./testvectors/TDES/rsp/TCBCvartext.rsp" || { echo "./testvectors/TDES/req/TCBCvartext.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64invperm.req" "./testvectors/TDES/rsp/TCFB64invperm.rsp" || { echo "./testvectors/TDES/req/TCFB64invperm.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT1.req" "./testvectors/TDES/rsp/TCFB64MMT1.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT2.req" "./testvectors/TDES/rsp/TCFB64MMT2.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT3.req" "./testvectors/TDES/rsp/TCFB64MMT3.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte1.req" "./testvectors/TDES/rsp/TCFB64Monte1.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte2.req" "./testvectors/TDES/rsp/TCFB64Monte2.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte3.req" "./testvectors/TDES/rsp/TCFB64Monte3.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64permop.req" "./testvectors/TDES/rsp/TCFB64permop.rsp" || { echo "./testvectors/TDES/req/TCFB64permop.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64subtab.req" "./testvectors/TDES/rsp/TCFB64subtab.rsp" || { echo "./testvectors/TDES/req/TCFB64subtab.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64varkey.req" "./testvectors/TDES/rsp/TCFB64varkey.rsp" || { echo "./testvectors/TDES/req/TCFB64varkey.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64vartext.req" "./testvectors/TDES/rsp/TCFB64vartext.rsp" || { echo "./testvectors/TDES/req/TCFB64vartext.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8invperm.req" "./testvectors/TDES/rsp/TCFB8invperm.rsp" || { echo "./testvectors/TDES/req/TCFB8invperm.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT1.req" "./testvectors/TDES/rsp/TCFB8MMT1.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT2.req" "./testvectors/TDES/rsp/TCFB8MMT2.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT3.req" "./testvectors/TDES/rsp/TCFB8MMT3.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte1.req" "./testvectors/TDES/rsp/TCFB8Monte1.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte2.req" "./testvectors/TDES/rsp/TCFB8Monte2.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte3.req" "./testvectors/TDES/rsp/TCFB8Monte3.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8permop.req" "./testvectors/TDES/rsp/TCFB8permop.rsp" || { echo "./testvectors/TDES/req/TCFB8permop.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8subtab.req" "./testvectors/TDES/rsp/TCFB8subtab.rsp" || { echo "./testvectors/TDES/req/TCFB8subtab.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8varkey.req" "./testvectors/TDES/rsp/TCFB8varkey.rsp" || { echo "./testvectors/TDES/req/TCFB8varkey.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8vartext.req" "./testvectors/TDES/rsp/TCFB8vartext.rsp" || { echo "./testvectors/TDES/req/TCFB8vartext.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBinvperm.req" "./testvectors/TDES/rsp/TECBinvperm.rsp" || { echo "./testvectors/TDES/req/TECBinvperm.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT1.req" "./testvectors/TDES/rsp/TECBMMT1.rsp" || { echo "./testvectors/TDES/req/TECBMMT1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT2.req" "./testvectors/TDES/rsp/TECBMMT2.rsp" || { echo "./testvectors/TDES/req/TECBMMT2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT3.req" "./testvectors/TDES/rsp/TECBMMT3.rsp" || { echo "./testvectors/TDES/req/TECBMMT3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte1.req" "./testvectors/TDES/rsp/TECBMonte1.rsp" || { echo "./testvectors/TDES/req/TECBMonte1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte2.req" "./testvectors/TDES/rsp/TECBMonte2.rsp" || { echo "./testvectors/TDES/req/TECBMonte2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte3.req" "./testvectors/TDES/rsp/TECBMonte3.rsp" || { echo "./testvectors/TDES/req/TECBMonte3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBpermop.req" "./testvectors/TDES/rsp/TECBpermop.rsp" || { echo "./testvectors/TDES/req/TECBpermop.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBsubtab.req" "./testvectors/TDES/rsp/TECBsubtab.rsp" || { echo "./testvectors/TDES/req/TECBsubtab.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBvarkey.req" "./testvectors/TDES/rsp/TECBvarkey.rsp" || { echo "./testvectors/TDES/req/TECBvarkey.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBvartext.req" "./testvectors/TDES/rsp/TECBvartext.rsp" || { echo "./testvectors/TDES/req/TECBvartext.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBinvperm.req" "./testvectors/TDES/rsp/TOFBinvperm.rsp" || { echo "./testvectors/TDES/req/TOFBinvperm.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT1.req" "./testvectors/TDES/rsp/TOFBMMT1.rsp" || { echo "./testvectors/TDES/req/TOFBMMT1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT2.req" "./testvectors/TDES/rsp/TOFBMMT2.rsp" || { echo "./testvectors/TDES/req/TOFBMMT2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT3.req" "./testvectors/TDES/rsp/TOFBMMT3.rsp" || { echo "./testvectors/TDES/req/TOFBMMT3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte1.req" "./testvectors/TDES/rsp/TOFBMonte1.rsp" || { echo "./testvectors/TDES/req/TOFBMonte1.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte2.req" "./testvectors/TDES/rsp/TOFBMonte2.rsp" || { echo "./testvectors/TDES/req/TOFBMonte2.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte3.req" "./testvectors/TDES/rsp/TOFBMonte3.rsp" || { echo "./testvectors/TDES/req/TOFBMonte3.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBpermop.req" "./testvectors/TDES/rsp/TOFBpermop.rsp" || { echo "./testvectors/TDES/req/TOFBpermop.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBsubtab.req" "./testvectors/TDES/rsp/TOFBsubtab.rsp" || { echo "./testvectors/TDES/req/TOFBsubtab.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBvarkey.req" "./testvectors/TDES/rsp/TOFBvarkey.rsp" || { echo "./testvectors/TDES/req/TOFBvarkey.req failure" ; exit 1 +} +../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBvartext.req" "./testvectors/TDES/rsp/TOFBvartext.rsp" || { echo "./testvectors/TDES/req/TOFBvartext.req failure" ; exit 1 +} diff --git a/fips/hmac/.cvsignore b/fips/hmac/.cvsignore new file mode 100644 index 0000000000..439e6d3eb6 --- /dev/null +++ b/fips/hmac/.cvsignore @@ -0,0 +1,4 @@ +lib +Makefile.save +*.flc +semantic.cache diff --git a/fips/hmac/Makefile b/fips/hmac/Makefile new file mode 100644 index 0000000000..bc8d825e0c --- /dev/null +++ b/fips/hmac/Makefile @@ -0,0 +1,123 @@ +# +# OpenSSL/fips/hmac/Makefile +# + +DIR= hmac +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=fips_hmactest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_hmac.c fips_hmac_selftest.c +LIBOBJ=fips_hmac.o fips_hmac_selftest.o + +SRC= $(LIBSRC) + +EXHEADER= +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +Q=../testvectors/hmac/req +A=../testvectors/hmac/rsp + +fips_test: + -rm -rf $(A) + mkdir $(A) + if [ -f $(Q)/HMAC.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_hmactest < $(Q)/HMAC.req > $(A)/HMAC.rsp; fi + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_hmac.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_hmac.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_hmac.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h +fips_hmac.o: ../../include/openssl/objects.h +fips_hmac.o: ../../include/openssl/opensslconf.h +fips_hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +fips_hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_hmac.o: ../../include/openssl/symhacks.h fips_hmac.c +fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_hmac_selftest.o: ../../include/openssl/crypto.h +fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_hmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_hmac_selftest.o: ../../include/openssl/hmac.h +fips_hmac_selftest.o: ../../include/openssl/lhash.h +fips_hmac_selftest.o: ../../include/openssl/obj_mac.h +fips_hmac_selftest.o: ../../include/openssl/objects.h +fips_hmac_selftest.o: ../../include/openssl/opensslconf.h +fips_hmac_selftest.o: ../../include/openssl/opensslv.h +fips_hmac_selftest.o: ../../include/openssl/ossl_typ.h +fips_hmac_selftest.o: ../../include/openssl/safestack.h +fips_hmac_selftest.o: ../../include/openssl/stack.h +fips_hmac_selftest.o: ../../include/openssl/symhacks.h fips_hmac_selftest.c +fips_hmactest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_hmactest.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +fips_hmactest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_hmactest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +fips_hmactest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +fips_hmactest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_hmactest.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_hmactest.o: ../../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 ../../include/openssl/pkcs7.h +fips_hmactest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_hmactest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_hmactest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +fips_hmactest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_hmactest.c diff --git a/fips/hmac/fips_hmac.c b/fips/hmac/fips_hmac.c new file mode 100644 index 0000000000..7c49c9882a --- /dev/null +++ b/fips/hmac/fips_hmac.c @@ -0,0 +1,191 @@ +/* crypto/hmac/hmac.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl) + { + int i,j,reset=0; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + + if (md != NULL) + { + reset=1; + ctx->md=md; + } + else + md=ctx->md; + + if (key != NULL) + { + if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS) + && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))) + OpenSSLDie(__FILE__,__LINE__, + "HMAC: digest not allowed in FIPS mode"); + + reset=1; + j=M_EVP_MD_block_size(md); + OPENSSL_assert(j <= sizeof ctx->key); + if (j < len) + { + EVP_DigestInit_ex(&ctx->md_ctx,md, impl); + EVP_DigestUpdate(&ctx->md_ctx,key,len); + EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key, + &ctx->key_length); + } + else + { + OPENSSL_assert(len <= sizeof ctx->key); + memcpy(ctx->key,key,len); + ctx->key_length=len; + } + if(ctx->key_length != HMAC_MAX_MD_CBLOCK) + memset(&ctx->key[ctx->key_length], 0, + HMAC_MAX_MD_CBLOCK - ctx->key_length); + } + + if (reset) + { + for (i=0; ikey[i]; + EVP_DigestInit_ex(&ctx->i_ctx,md, impl); + EVP_DigestUpdate(&ctx->i_ctx,pad,M_EVP_MD_block_size(md)); + + for (i=0; ikey[i]; + EVP_DigestInit_ex(&ctx->o_ctx,md, impl); + EVP_DigestUpdate(&ctx->o_ctx,pad,M_EVP_MD_block_size(md)); + } + EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx); + } + +void HMAC_Init(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md) + { + if(key && md) + HMAC_CTX_init(ctx); + HMAC_Init_ex(ctx,key,len,md, NULL); + } + +void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) + { + EVP_DigestUpdate(&ctx->md_ctx,data,len); + } + +void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) + { + int j; + unsigned int i; + unsigned char buf[EVP_MAX_MD_SIZE]; + + j=M_EVP_MD_block_size(ctx->md); + + EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i); + EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx); + EVP_DigestUpdate(&ctx->md_ctx,buf,i); + EVP_DigestFinal_ex(&ctx->md_ctx,md,len); + } + +void HMAC_CTX_init(HMAC_CTX *ctx) + { + EVP_MD_CTX_init(&ctx->i_ctx); + EVP_MD_CTX_init(&ctx->o_ctx); + EVP_MD_CTX_init(&ctx->md_ctx); + } + +void HMAC_CTX_cleanup(HMAC_CTX *ctx) + { + EVP_MD_CTX_cleanup(&ctx->i_ctx); + EVP_MD_CTX_cleanup(&ctx->o_ctx); + EVP_MD_CTX_cleanup(&ctx->md_ctx); + memset(ctx,0,sizeof *ctx); + } + +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len) + { + HMAC_CTX c; + static unsigned char m[EVP_MAX_MD_SIZE]; + + if (md == NULL) md=m; + HMAC_CTX_init(&c); + HMAC_Init(&c,key,key_len,evp_md); + HMAC_Update(&c,d,n); + HMAC_Final(&c,md,md_len); + HMAC_CTX_cleanup(&c); + return(md); + } + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) + { + M_EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); + M_EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); + M_EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); + } + +#endif + diff --git a/fips/hmac/fips_hmac_selftest.c b/fips/hmac/fips_hmac_selftest.c new file mode 100644 index 0000000000..a697770732 --- /dev/null +++ b/fips/hmac/fips_hmac_selftest.c @@ -0,0 +1,135 @@ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS +typedef struct { + const EVP_MD *(*alg)(void); + const char *key, *iv; + unsigned char kaval[EVP_MAX_MD_SIZE]; +} HMAC_KAT; + +static const HMAC_KAT vector[] = { + { EVP_sha1, + /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */ + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x09,0x22,0xd3,0x40,0x5f,0xaa,0x3d,0x19, + 0x4f,0x82,0xa4,0x58,0x30,0x73,0x7d,0x5c, + 0xc6,0xc7,0x5d,0x24 } + }, + { EVP_sha224, + /* just keep extending the above... */ + "0123456789:;<=>?@ABC", + "Sample #2", + { 0xdd,0xef,0x0a,0x40,0xcb,0x7d,0x50,0xfb, + 0x6e,0xe6,0xce,0xa1,0x20,0xba,0x26,0xaa, + 0x08,0xf3,0x07,0x75,0x87,0xb8,0xad,0x1b, + 0x8c,0x8d,0x12,0xc7 } + }, + { EVP_sha256, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0xb8,0xf2,0x0d,0xb5,0x41,0xea,0x43,0x09, + 0xca,0x4e,0xa9,0x38,0x0c,0xd0,0xe8,0x34, + 0xf7,0x1f,0xbe,0x91,0x74,0xa2,0x61,0x38, + 0x0d,0xc1,0x7e,0xae,0x6a,0x34,0x51,0xd9 } + }, + { EVP_sha384, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x08,0xbc,0xb0,0xda,0x49,0x1e,0x87,0xad, + 0x9a,0x1d,0x6a,0xce,0x23,0xc5,0x0b,0xf6, + 0xb7,0x18,0x06,0xa5,0x77,0xcd,0x49,0x04, + 0x89,0xf1,0xe6,0x23,0x44,0x51,0x51,0x9f, + 0x85,0x56,0x80,0x79,0x0c,0xbd,0x4d,0x50, + 0xa4,0x5f,0x29,0xe3,0x93,0xf0,0xe8,0x7f } + }, + { EVP_sha512, + "0123456789:;<=>?@ABC", + "Sample #2", + { 0x80,0x9d,0x44,0x05,0x7c,0x5b,0x95,0x41, + 0x05,0xbd,0x04,0x13,0x16,0xdb,0x0f,0xac, + 0x44,0xd5,0xa4,0xd5,0xd0,0x89,0x2b,0xd0, + 0x4e,0x86,0x64,0x12,0xc0,0x90,0x77,0x68, + 0xf1,0x87,0xb7,0x7c,0x4f,0xae,0x2c,0x2f, + 0x21,0xa5,0xb5,0x65,0x9a,0x4f,0x4b,0xa7, + 0x47,0x02,0xa3,0xde,0x9b,0x51,0xf1,0x45, + 0xbd,0x4f,0x25,0x27,0x42,0x98,0x99,0x05 } + }, +}; + +int FIPS_selftest_hmac() + { + int n; + unsigned int outlen; + unsigned char out[EVP_MAX_MD_SIZE]; + const EVP_MD *md; + const HMAC_KAT *t; + + for(n=0,t=vector; nalg)(); + HMAC(md,t->key,strlen(t->key), + (const unsigned char *)t->iv,strlen(t->iv), + out,&outlen); + + if(memcmp(out,t->kaval,outlen)) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED); + return 0; + } + } + return 1; + } +#endif diff --git a/fips/hmac/fips_hmactest.c b/fips/hmac/fips_hmactest.c new file mode 100644 index 0000000000..d02a38f826 --- /dev/null +++ b/fips/hmac/fips_hmactest.c @@ -0,0 +1,327 @@ +/* fips_hmactest.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS HMAC support\n"); + return(0); +} + +#else + +#include +#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); + +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 (!hmac_test(EVP_sha1(), out, in)) + { + fprintf(stderr, "FATAL hmac 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 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("\n", out); + return 1; + } + +#endif diff --git a/fips/install.com b/fips/install.com new file mode 100644 index 0000000000..a2d22d387f --- /dev/null +++ b/fips/install.com @@ -0,0 +1,57 @@ +$! INSTALL.COM -- Installs the files in a given directory tree +$! +$! Author: Richard Levitte +$! Time of creation: 27-MAY-2004 11:47 +$! +$! P1 root of the directory tree +$! +$ IF P1 .EQS. "" +$ THEN +$ WRITE SYS$OUTPUT "First argument missing." +$ WRITE SYS$OUTPUT "Should be the directory where you want things installed." +$ EXIT +$ ENDIF +$ +$ ROOT = F$PARSE(P1,"[]A.;0",,,"SYNTAX_ONLY,NO_CONCEAL") - "A.;0" +$ ROOT_DEV = F$PARSE(ROOT,,,"DEVICE","SYNTAX_ONLY") +$ ROOT_DIR = F$PARSE(ROOT,,,"DIRECTORY","SYNTAX_ONLY") - + - "[000000." - "][" - "[" - "]" +$ ROOT = ROOT_DEV + "[" + ROOT_DIR +$ +$ DEFINE/NOLOG WRK_SSLROOT 'ROOT'.] /TRANS=CONC +$ DEFINE/NOLOG WRK_SSLINCLUDE WRK_SSLROOT:[INCLUDE] +$ +$ IF F$PARSE("WRK_SSLROOT:[000000]") .EQS. "" THEN - + CREATE/DIR/LOG WRK_SSLROOT:[000000] +$ IF F$PARSE("WRK_SSLINCLUDE:") .EQS. "" THEN - + CREATE/DIR/LOG WRK_SSLINCLUDE: +$ +$ FDIRS := ,RAND,SHA,DES,AES,DSA,RSA,DH,HMAC +$ EXHEADER_ := fips.h +$ EXHEADER_SHA := fips_sha.h +$ EXHEADER_RAND := fips_rand.h +$ EXHEADER_DES := +$ EXHEADER_AES := +$ EXHEADER_DSA := +$ EXHEADER_RSA := +$ EXHEADER_DH := +$ EXHEADER_HMAC := +$ +$ I = 0 +$ LOOP_FDIRS: +$ D = F$EDIT(F$ELEMENT(I, ",", FDIRS),"TRIM") +$ I = I + 1 +$ IF D .EQS. "," THEN GOTO LOOP_FDIRS_END +$ tmp = EXHEADER_'D' +$ IF tmp .EQS. "" THEN GOTO LOOP_FDIRS +$ IF D .EQS. "" +$ THEN +$ COPY 'tmp' WRK_SSLINCLUDE: /LOG +$ ELSE +$ COPY [.'D']'tmp' WRK_SSLINCLUDE: /LOG +$ ENDIF +$ SET FILE/PROT=WORLD:RE WRK_SSLINCLUDE:'tmp' +$ GOTO LOOP_FDIRS +$ LOOP_FDIRS_END: +$ +$ EXIT diff --git a/fips/mkfipsscr.pl b/fips/mkfipsscr.pl new file mode 100644 index 0000000000..dc60cdf580 --- /dev/null +++ b/fips/mkfipsscr.pl @@ -0,0 +1,632 @@ +#!/usr/local/bin/perl -w +# Quick & dirty utility to generate a script for executing the +# FIPS 140-2 CMVP algorithm tests based on the pathnames of +# input algorithm test files actually present (the unqualified +# file names are consistent but the pathnames are not). +# + +# List of all the unqualified file names we expect. +my %fips_tests = ( + +# FIPS test definitions + +# DSA tests + +"PQGGen" => "fips_dssvs pqg", +"KeyPair" => "fips_dssvs keypair", +"SigGen" => "fips_dssvs siggen", +"SigVer" => "fips_dssvs sigver", + +# SHA tests + +"SHA1LongMsg" => "fips_shatest", +"SHA1Monte" => "fips_shatest", +"SHA1ShortMsg" => "fips_shatest", +"SHA224LongMsg" => "fips_shatest", +"SHA224Monte" => "fips_shatest", +"SHA224ShortMsg" => "fips_shatest", +"SHA256LongMsg" => "fips_shatest", +"SHA256Monte" => "fips_shatest", +"SHA256ShortMsg" => "fips_shatest", +"SHA384LongMsg" => "fips_shatest", +"SHA384Monte" => "fips_shatest", +"SHA384ShortMsg" => "fips_shatest", +"SHA512LongMsg" => "fips_shatest", +"SHA512Monte" => "fips_shatest", +"SHA512ShortMsg" => "fips_shatest", + +# HMAC + +"HMAC" => "fips_hmactest", + +# RAND tests + +"ANSI931_AES128MCT" => "fips_rngvs mct", +"ANSI931_AES192MCT" => "fips_rngvs mct", +"ANSI931_AES256MCT" => "fips_rngvs mct", +"ANSI931_AES128VST" => "fips_rngvs vst", +"ANSI931_AES192VST" => "fips_rngvs vst", +"ANSI931_AES256VST" => "fips_rngvs vst", + +# RSA tests + +"SigGen15" => "fips_rsastest", +"SigVer15" => "fips_rsavtest", +"SigGenPSS" => "fips_rsastest -saltlen SALT", +"SigVerPSS" => "fips_rsavtest -saltlen SALT", +"SigGenRSA" => "fips_rsastest -x931", +"SigVerRSA" => "fips_rsavtest -x931", +"KeyGenRSA" => "fips_rsagtest", + +# AES tests + +"CBCGFSbox128" => "fips_aesavs -f", +"CBCGFSbox192" => "fips_aesavs -f", +"CBCGFSbox256" => "fips_aesavs -f", +"CBCKeySbox128" => "fips_aesavs -f", +"CBCKeySbox192" => "fips_aesavs -f", +"CBCKeySbox256" => "fips_aesavs -f", +"CBCMCT128" => "fips_aesavs -f", +"CBCMCT192" => "fips_aesavs -f", +"CBCMCT256" => "fips_aesavs -f", +"CBCMMT128" => "fips_aesavs -f", +"CBCMMT192" => "fips_aesavs -f", +"CBCMMT256" => "fips_aesavs -f", +"CBCVarKey128" => "fips_aesavs -f", +"CBCVarKey192" => "fips_aesavs -f", +"CBCVarKey256" => "fips_aesavs -f", +"CBCVarTxt128" => "fips_aesavs -f", +"CBCVarTxt192" => "fips_aesavs -f", +"CBCVarTxt256" => "fips_aesavs -f", +"CFB128GFSbox128" => "fips_aesavs -f", +"CFB128GFSbox192" => "fips_aesavs -f", +"CFB128GFSbox256" => "fips_aesavs -f", +"CFB128KeySbox128" => "fips_aesavs -f", +"CFB128KeySbox192" => "fips_aesavs -f", +"CFB128KeySbox256" => "fips_aesavs -f", +"CFB128MCT128" => "fips_aesavs -f", +"CFB128MCT192" => "fips_aesavs -f", +"CFB128MCT256" => "fips_aesavs -f", +"CFB128MMT128" => "fips_aesavs -f", +"CFB128MMT192" => "fips_aesavs -f", +"CFB128MMT256" => "fips_aesavs -f", +"CFB128VarKey128" => "fips_aesavs -f", +"CFB128VarKey192" => "fips_aesavs -f", +"CFB128VarKey256" => "fips_aesavs -f", +"CFB128VarTxt128" => "fips_aesavs -f", +"CFB128VarTxt192" => "fips_aesavs -f", +"CFB128VarTxt256" => "fips_aesavs -f", +"CFB8GFSbox128" => "fips_aesavs -f", +"CFB8GFSbox192" => "fips_aesavs -f", +"CFB8GFSbox256" => "fips_aesavs -f", +"CFB8KeySbox128" => "fips_aesavs -f", +"CFB8KeySbox192" => "fips_aesavs -f", +"CFB8KeySbox256" => "fips_aesavs -f", +"CFB8MCT128" => "fips_aesavs -f", +"CFB8MCT192" => "fips_aesavs -f", +"CFB8MCT256" => "fips_aesavs -f", +"CFB8MMT128" => "fips_aesavs -f", +"CFB8MMT192" => "fips_aesavs -f", +"CFB8MMT256" => "fips_aesavs -f", +"CFB8VarKey128" => "fips_aesavs -f", +"CFB8VarKey192" => "fips_aesavs -f", +"CFB8VarKey256" => "fips_aesavs -f", +"CFB8VarTxt128" => "fips_aesavs -f", +"CFB8VarTxt192" => "fips_aesavs -f", +"CFB8VarTxt256" => "fips_aesavs -f", +#"CFB1GFSbox128" => "fips_aesavs -f", +#"CFB1GFSbox192" => "fips_aesavs -f", +#"CFB1GFSbox256" => "fips_aesavs -f", +#"CFB1KeySbox128" => "fips_aesavs -f", +#"CFB1KeySbox192" => "fips_aesavs -f", +#"CFB1KeySbox256" => "fips_aesavs -f", +#"CFB1MCT128" => "fips_aesavs -f", +#"CFB1MCT192" => "fips_aesavs -f", +#"CFB1MCT256" => "fips_aesavs -f", +#"CFB1MMT128" => "fips_aesavs -f", +#"CFB1MMT192" => "fips_aesavs -f", +#"CFB1MMT256" => "fips_aesavs -f", +#"CFB1VarKey128" => "fips_aesavs -f", +#"CFB1VarKey192" => "fips_aesavs -f", +#"CFB1VarKey256" => "fips_aesavs -f", +#"CFB1VarTxt128" => "fips_aesavs -f", +#"CFB1VarTxt192" => "fips_aesavs -f", +#"CFB1VarTxt256" => "fips_aesavs -f", +"ECBGFSbox128" => "fips_aesavs -f", +"ECBGFSbox192" => "fips_aesavs -f", +"ECBGFSbox256" => "fips_aesavs -f", +"ECBKeySbox128" => "fips_aesavs -f", +"ECBKeySbox192" => "fips_aesavs -f", +"ECBKeySbox256" => "fips_aesavs -f", +"ECBMCT128" => "fips_aesavs -f", +"ECBMCT192" => "fips_aesavs -f", +"ECBMCT256" => "fips_aesavs -f", +"ECBMMT128" => "fips_aesavs -f", +"ECBMMT192" => "fips_aesavs -f", +"ECBMMT256" => "fips_aesavs -f", +"ECBVarKey128" => "fips_aesavs -f", +"ECBVarKey192" => "fips_aesavs -f", +"ECBVarKey256" => "fips_aesavs -f", +"ECBVarTxt128" => "fips_aesavs -f", +"ECBVarTxt192" => "fips_aesavs -f", +"ECBVarTxt256" => "fips_aesavs -f", +"OFBGFSbox128" => "fips_aesavs -f", +"OFBGFSbox192" => "fips_aesavs -f", +"OFBGFSbox256" => "fips_aesavs -f", +"OFBKeySbox128" => "fips_aesavs -f", +"OFBKeySbox192" => "fips_aesavs -f", +"OFBKeySbox256" => "fips_aesavs -f", +"OFBMCT128" => "fips_aesavs -f", +"OFBMCT192" => "fips_aesavs -f", +"OFBMCT256" => "fips_aesavs -f", +"OFBMMT128" => "fips_aesavs -f", +"OFBMMT192" => "fips_aesavs -f", +"OFBMMT256" => "fips_aesavs -f", +"OFBVarKey128" => "fips_aesavs -f", +"OFBVarKey192" => "fips_aesavs -f", +"OFBVarKey256" => "fips_aesavs -f", +"OFBVarTxt128" => "fips_aesavs -f", +"OFBVarTxt192" => "fips_aesavs -f", +"OFBVarTxt256" => "fips_aesavs -f", + +# Triple DES tests + +"TCBCinvperm" => "fips_desmovs -f", +"TCBCMMT1" => "fips_desmovs -f", +"TCBCMMT2" => "fips_desmovs -f", +"TCBCMMT3" => "fips_desmovs -f", +"TCBCMonte1" => "fips_desmovs -f", +"TCBCMonte2" => "fips_desmovs -f", +"TCBCMonte3" => "fips_desmovs -f", +"TCBCpermop" => "fips_desmovs -f", +"TCBCsubtab" => "fips_desmovs -f", +"TCBCvarkey" => "fips_desmovs -f", +"TCBCvartext" => "fips_desmovs -f", +"TCFB64invperm" => "fips_desmovs -f", +"TCFB64MMT1" => "fips_desmovs -f", +"TCFB64MMT2" => "fips_desmovs -f", +"TCFB64MMT3" => "fips_desmovs -f", +"TCFB64Monte1" => "fips_desmovs -f", +"TCFB64Monte2" => "fips_desmovs -f", +"TCFB64Monte3" => "fips_desmovs -f", +"TCFB64permop" => "fips_desmovs -f", +"TCFB64subtab" => "fips_desmovs -f", +"TCFB64varkey" => "fips_desmovs -f", +"TCFB64vartext" => "fips_desmovs -f", +"TCFB8invperm" => "fips_desmovs -f", +"TCFB8MMT1" => "fips_desmovs -f", +"TCFB8MMT2" => "fips_desmovs -f", +"TCFB8MMT3" => "fips_desmovs -f", +"TCFB8Monte1" => "fips_desmovs -f", +"TCFB8Monte2" => "fips_desmovs -f", +"TCFB8Monte3" => "fips_desmovs -f", +"TCFB8permop" => "fips_desmovs -f", +"TCFB8subtab" => "fips_desmovs -f", +"TCFB8varkey" => "fips_desmovs -f", +"TCFB8vartext" => "fips_desmovs -f", +"TECBinvperm" => "fips_desmovs -f", +"TECBMMT1" => "fips_desmovs -f", +"TECBMMT2" => "fips_desmovs -f", +"TECBMMT3" => "fips_desmovs -f", +"TECBMonte1" => "fips_desmovs -f", +"TECBMonte2" => "fips_desmovs -f", +"TECBMonte3" => "fips_desmovs -f", +"TECBpermop" => "fips_desmovs -f", +"TECBsubtab" => "fips_desmovs -f", +"TECBvarkey" => "fips_desmovs -f", +"TECBvartext" => "fips_desmovs -f", +"TOFBinvperm" => "fips_desmovs -f", +"TOFBMMT1" => "fips_desmovs -f", +"TOFBMMT2" => "fips_desmovs -f", +"TOFBMMT3" => "fips_desmovs -f", +"TOFBMonte1" => "fips_desmovs -f", +"TOFBMonte2" => "fips_desmovs -f", +"TOFBMonte3" => "fips_desmovs -f", +"TOFBpermop" => "fips_desmovs -f", +"TOFBsubtab" => "fips_desmovs -f", +"TOFBvarkey" => "fips_desmovs -f", +"TOFBvartext" => "fips_desmovs -f", +"TCBCinvperm" => "fips_desmovs -f", +"TCBCMMT1" => "fips_desmovs -f", +"TCBCMMT2" => "fips_desmovs -f", +"TCBCMMT3" => "fips_desmovs -f", +"TCBCMonte1" => "fips_desmovs -f", +"TCBCMonte2" => "fips_desmovs -f", +"TCBCMonte3" => "fips_desmovs -f", +"TCBCpermop" => "fips_desmovs -f", +"TCBCsubtab" => "fips_desmovs -f", +"TCBCvarkey" => "fips_desmovs -f", +"TCBCvartext" => "fips_desmovs -f", +"TCFB64invperm" => "fips_desmovs -f", +"TCFB64MMT1" => "fips_desmovs -f", +"TCFB64MMT2" => "fips_desmovs -f", +"TCFB64MMT3" => "fips_desmovs -f", +"TCFB64Monte1" => "fips_desmovs -f", +"TCFB64Monte2" => "fips_desmovs -f", +"TCFB64Monte3" => "fips_desmovs -f", +"TCFB64permop" => "fips_desmovs -f", +"TCFB64subtab" => "fips_desmovs -f", +"TCFB64varkey" => "fips_desmovs -f", +"TCFB64vartext" => "fips_desmovs -f", +"TCFB8invperm" => "fips_desmovs -f", +"TCFB8MMT1" => "fips_desmovs -f", +"TCFB8MMT2" => "fips_desmovs -f", +"TCFB8MMT3" => "fips_desmovs -f", +"TCFB8Monte1" => "fips_desmovs -f", +"TCFB8Monte2" => "fips_desmovs -f", +"TCFB8Monte3" => "fips_desmovs -f", +"TCFB8permop" => "fips_desmovs -f", +"TCFB8subtab" => "fips_desmovs -f", +"TCFB8varkey" => "fips_desmovs -f", +"TCFB8vartext" => "fips_desmovs -f", +"TECBinvperm" => "fips_desmovs -f", +"TECBMMT1" => "fips_desmovs -f", +"TECBMMT2" => "fips_desmovs -f", +"TECBMMT3" => "fips_desmovs -f", +"TECBMonte1" => "fips_desmovs -f", +"TECBMonte2" => "fips_desmovs -f", +"TECBMonte3" => "fips_desmovs -f", +"TECBpermop" => "fips_desmovs -f", +"TECBsubtab" => "fips_desmovs -f", +"TECBvarkey" => "fips_desmovs -f", +"TECBvartext" => "fips_desmovs -f", +"TOFBinvperm" => "fips_desmovs -f", +"TOFBMMT1" => "fips_desmovs -f", +"TOFBMMT2" => "fips_desmovs -f", +"TOFBMMT3" => "fips_desmovs -f", +"TOFBMonte1" => "fips_desmovs -f", +"TOFBMonte2" => "fips_desmovs -f", +"TOFBMonte3" => "fips_desmovs -f", +"TOFBpermop" => "fips_desmovs -f", +"TOFBsubtab" => "fips_desmovs -f", +"TOFBvarkey" => "fips_desmovs -f", +"TOFBvartext" => "fips_desmovs -f" + +); +my %salt_names = ( +"SigVerPSS (salt 0)" => "SigVerPSS", +"SigVerPSS (salt 62)" => "SigVerPSS", +"SigGenPSS (salt 0)" => "SigGenPSS", +"SigGenPSS (salt 62)" => "SigGenPSS", +); + + +my $win32 = $^O =~ m/mswin/i; +my $onedir = 0; +my $filter = ""; +my $tvdir; +my $tprefix; +my $shwrap_prefix; +my $debug = 0; +my $quiet = 0; +my $rspdir = "rsp"; +my $rspignore = 0; +my @bogus = (); # list of unmatched *.rsp files +my $bufout = ''; +my %_programs = (); # list of external programs to check + +foreach (@ARGV) + { + if ($_ eq "--win32") + { + $win32 = 1; + } + elsif ($_ eq "--onedir") + { + $onedir = 1; + } + elsif ($_ eq "--debug") + { + $debug = 1; + } + elsif ($_ eq "--quiet") + { + $quiet = 1; + } + elsif (/--dir=(.*)$/) + { + $tvdir = $1; + } + elsif (/--rspdir=(.*)$/) + { + $rspdir = $1; + } + elsif (/--rspignore$/) + { + $rspignore = 1; + } + elsif (/--tprefix=(.*)$/) + { + $tprefix = $1; + } + elsif (/--shwrap_prefix=(.*)$/) + { + $shwrap_prefix = $1; + } + elsif (/--filter=(.*)$/) + { + $filter = $1; + } + elsif (/--outfile=(.*)$/) + { + $outfile = $1; + } + else + { + &Help(); + exit(1); + } + } + +$tvdir = "." unless defined $tvdir; + +if ($win32) + { + if (!defined $tprefix) + { + if ($onedir) + { + $tprefix = ".\\"; + } + else + { + $tprefix = "..\\out32dll\\"; + } + } + + $bufinit .= <$outfile") || die "Error opening $outfile: $!"; + print OUT $bufinit; + if (!$rspignore && @bogus) + { + print STDERR "ERROR: please remove bogus *.rsp files\n"; + print OUT < Optional root for *.req file search + --filter= + --onedir Assume all components in current directory + --outfile= Optional name of output script, default fipstests.{sh|bat} + --rspdir= Name of subdirectories containing *.rsp files, default "resp" + --rspignore Ignore any bogus *.rsp files + --shwrap_prefix= + --tprefix= + --quiet Shhh.... + --win32 Generate script for Win32 environment +EOF +} + +#-------------------------------- +sub countentry { + my ($key,$value) = @_; + if ($value == 0) + { + print STDERR "WARNING: test file $key not found\n" unless $quiet; + } + elsif ($value > 1) + { + print STDERR "WARNING: test file $key found $value times\n" unless $quiet; + } + else + { + print STDERR "Found test file $key\n" if $debug; + } + } + +#-------------------------------- +sub recurse_test + { + my ($win32, $tprefix, $filter, $dir) = @_; + my $dirh; + opendir($dirh, $dir); + while ($_ = readdir($dirh)) + { + next if ($_ eq "." || $_ eq ".."); + $_ = "$dir/$_"; + if (-f "$_") + { + if (/\/([^\/]*)\.rsp$/) + { + if (exists $fips_tests{$1}) + { + $debug && print "DEBUG: $1 found, will be overwritten\n"; + } + else + { + print STDERR "ERROR: bogus file $_\n"; + push @bogus, $_; + } + } + next unless /$filter.*\.req$/i; + if (/\/([^\/]*)\.req$/ && exists $fips_tests{$1}) + { + $fips_found{$1}++; + test_line($win32, $_, $tprefix, $1); + } + elsif (! /SHAmix\.req$/) + { + print STDERR "WARNING: unrecognized filename $_\n"; + } + } + elsif (-d "$_") + { + if (/$filter.*req$/i) + { + test_dir($win32, $_); + } + recurse_test($win32, $tprefix, $filter, $_); + } + } + closedir($dirh); + } + +#-------------------------------- +sub test_dir + { + my ($win32, $req) = @_; + my $rsp = $req; + $rsp =~ s/req$/$rspdir/; + if ($win32) + { + $rsp =~ tr|/|\\|; + $req =~ tr|/|\\|; + $bufout .= <) + { + if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i) + { + my $sl = $1; + print STDERR "$req salt length $sl\n" if $debug; + $tcmd =~ s/SALT$/$sl/; + $salt_found{"$tnam (salt $sl)"}++; + last; + } + } + close IN; + if ($tcmd =~ /SALT$/) + { + die "Can't detect salt length for $req"; + } + } + + if ($win32) + { + $req =~ tr|/|\\|; + $rsp =~ tr|/|\\|; + $bufout .= "$tprefix$tcmd < \"$req\" > \"$rsp\"\n"; + $_programs{"$tprefix$tcmd.exe"} = 1; + } + else + { + $bufout .= < "$rsp" || { echo "$req failure" ; exit 1; } +END + $_programs{"$tprefix$tcmd"} = 1; + } + } + diff --git a/fips/openssl_fips_fingerprint b/fips/openssl_fips_fingerprint new file mode 100755 index 0000000000..f59a67d537 --- /dev/null +++ b/fips/openssl_fips_fingerprint @@ -0,0 +1,31 @@ +#!/bin/sh +# +# Check the library fingerprint and generate an executable fingerprint, or +# return an error + +lib=$1 +exe=$2 +ext=${HMAC_EXT:-sha1} + +# deal with the case where we're run from within the build and OpenSSL is +# not yet installed. Also, make sure LD_LIBRARY_PATH is properly set in +# case shared libraries are built. +if [ "X$TOP" != "X" ] +then + if test "$OSTYPE" = msdosdjgpp; then + PATH="$TOP/apps;$TOP;$PATH" + else + PATH="$TOP/apps:$TOP:$PATH" + fi + LD_LIBRARY_PATH=$TOP; export LD_LIBRARY_PATH +else + LD_LIBRARY_PATH=.; export LD_LIBRARY_PATH +fi + +echo "Checking library fingerprint for $lib" +openssl sha1 -hmac etaonrishdlcupfm $lib | sed "s/(.*\//(/" | diff -w $lib.sha1 - || { echo "$libs fingerprint mismatch"; exit 1; } + +[ -x $exe.exe ] && exe=$exe.exe + +echo "Making fingerprint for $exe" +openssl sha1 -hmac etaonrishdlcupfm -binary $exe > $exe.$ext || rm $exe.$ext diff --git a/fips/rand/.cvsignore b/fips/rand/.cvsignore new file mode 100644 index 0000000000..439e6d3eb6 --- /dev/null +++ b/fips/rand/.cvsignore @@ -0,0 +1,4 @@ +lib +Makefile.save +*.flc +semantic.cache diff --git a/fips/rand/Makefile b/fips/rand/Makefile new file mode 100644 index 0000000000..5f9da71bdc --- /dev/null +++ b/fips/rand/Makefile @@ -0,0 +1,149 @@ +# +# OpenSSL/fips/rand/Makefile +# + +DIR= rand +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= fips_randtest.c fips_rngvs.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_rand.c fips_rand_selftest.c +LIBOBJ=fips_rand.o fips_rand_selftest.o + +SRC= $(LIBSRC) + +EXHEADER= fips_rand.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +Q=../testvectors/rng/req +A=../testvectors/rng/rsp + +fips_test: + -rm -rf $(A) + mkdir $(A) + if [ -f $(Q)/ANSI931_AES128MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES128MCT.req > $(A)/ANSI931_AES128MCT.rsp; fi + if [ -f $(Q)/ANSI931_AES192MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES192MCT.req > $(A)/ANSI931_AES192MCT.rsp; fi + if [ -f $(Q)/ANSI931_AES256MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES256MCT.req > $(A)/ANSI931_AES256MCT.rsp; fi + if [ -f $(Q)/ANSI931_AES128VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES128VST.req > $(A)/ANSI931_AES128VST.rsp; fi + if [ -f $(Q)/ANSI931_AES192VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES192VST.req > $(A)/ANSI931_AES192VST.rsp; fi + if [ -f $(Q)/ANSI931_AES256VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES256VST.req > $(A)/ANSI931_AES256VST.rsp; fi + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_rand.o: ../../e_os.h ../../include/openssl/aes.h +fips_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_rand.o: ../../include/openssl/des.h ../../include/openssl/des_old.h +fips_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +fips_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +fips_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h +fips_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rand.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h +fips_rand.o: fips_rand.c +fips_rand_selftest.o: ../../include/openssl/bio.h +fips_rand_selftest.o: ../../include/openssl/crypto.h +fips_rand_selftest.o: ../../include/openssl/des.h +fips_rand_selftest.o: ../../include/openssl/des_old.h +fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rand_selftest.o: ../../include/openssl/fips.h +fips_rand_selftest.o: ../../include/openssl/fips_rand.h +fips_rand_selftest.o: ../../include/openssl/lhash.h +fips_rand_selftest.o: ../../include/openssl/opensslconf.h +fips_rand_selftest.o: ../../include/openssl/opensslv.h +fips_rand_selftest.o: ../../include/openssl/ossl_typ.h +fips_rand_selftest.o: ../../include/openssl/rand.h +fips_rand_selftest.o: ../../include/openssl/safestack.h +fips_rand_selftest.o: ../../include/openssl/stack.h +fips_rand_selftest.o: ../../include/openssl/symhacks.h +fips_rand_selftest.o: ../../include/openssl/ui.h +fips_rand_selftest.o: ../../include/openssl/ui_compat.h fips_rand_selftest.c +fips_randtest.o: ../../e_os.h ../../include/openssl/bio.h +fips_randtest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_randtest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h +fips_randtest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_randtest.o: ../../include/openssl/fips_rand.h +fips_randtest.o: ../../include/openssl/lhash.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: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h +fips_randtest.o: ../fips_utl.h fips_randtest.c +fips_rngvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rngvs.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h +fips_rngvs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +fips_rngvs.o: ../../include/openssl/des.h ../../include/openssl/des_old.h +fips_rngvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_rngvs.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +fips_rngvs.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +fips_rngvs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rngvs.o: ../../include/openssl/fips_rand.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/pkcs7.h ../../include/openssl/rand.h +fips_rngvs.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_rngvs.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rngvs.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h +fips_rngvs.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +fips_rngvs.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rngvs.c diff --git a/fips/rand/fips_rand.c b/fips/rand/fips_rand.c new file mode 100644 index 0000000000..58453e996d --- /dev/null +++ b/fips/rand/fips_rand.c @@ -0,0 +1,410 @@ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4. + */ + +#include "e_os.h" + +/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't + be defined and gettimeofday() won't be declared with strict compilers + like DEC C in ANSI C mode. */ +#ifndef _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED 1 +#endif + +#include +#include +#include +#include +#ifndef OPENSSL_SYS_WIN32 +#include +#endif +#include +#ifndef OPENSSL_SYS_WIN32 +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +#endif +#include +#include +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +void *OPENSSL_stderr(void); + +#define AES_BLOCK_LENGTH 16 + + +/* AES FIPS PRNG implementation */ + +typedef struct + { + int seeded; + int keyed; + int test_mode; + int second; + int error; + unsigned long counter; + AES_KEY ks; + int vpos; + /* Temporary storage for key if it equals seed length */ + unsigned char tmp_key[AES_BLOCK_LENGTH]; + unsigned char V[AES_BLOCK_LENGTH]; + unsigned char DT[AES_BLOCK_LENGTH]; + unsigned char last[AES_BLOCK_LENGTH]; + } FIPS_PRNG_CTX; + +static FIPS_PRNG_CTX sctx; + +static int fips_prng_fail = 0; + +void FIPS_rng_stick(void) + { + fips_prng_fail = 1; + } + +void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx) + { + ctx->seeded = 0; + ctx->keyed = 0; + ctx->test_mode = 0; + ctx->counter = 0; + ctx->second = 0; + ctx->error = 0; + ctx->vpos = 0; + OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH); + OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY)); + } + + +static int fips_set_prng_key(FIPS_PRNG_CTX *ctx, + const unsigned char *key, FIPS_RAND_SIZE_T keylen) + { + FIPS_selftest_check(); + if (keylen != 16 && keylen != 24 && keylen != 32) + { + /* error: invalid key size */ + return 0; + } + AES_set_encrypt_key(key, keylen << 3, &ctx->ks); + if (keylen == 16) + { + memcpy(ctx->tmp_key, key, 16); + ctx->keyed = 2; + } + else + ctx->keyed = 1; + ctx->seeded = 0; + ctx->second = 0; + return 1; + } + +static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx, + const unsigned char *seed, FIPS_RAND_SIZE_T seedlen) + { + int i; + if (!ctx->keyed) + return 0; + /* In test mode seed is just supplied data */ + if (ctx->test_mode) + { + if (seedlen != AES_BLOCK_LENGTH) + return 0; + memcpy(ctx->V, seed, AES_BLOCK_LENGTH); + ctx->seeded = 1; + return 1; + } + /* Outside test mode XOR supplied data with existing seed */ + for (i = 0; i < seedlen; i++) + { + ctx->V[ctx->vpos++] ^= seed[i]; + if (ctx->vpos == AES_BLOCK_LENGTH) + { + ctx->vpos = 0; + /* Special case if first seed and key length equals + * block size check key and seed do not match. + */ + if (ctx->keyed == 2) + { + if (!memcmp(ctx->tmp_key, ctx->V, 16)) + { + RANDerr(RAND_F_FIPS_SET_PRNG_SEED, + RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY); + return 0; + } + OPENSSL_cleanse(ctx->tmp_key, 16); + ctx->keyed = 1; + } + ctx->seeded = 1; + } + } + return 1; + } + +int fips_set_test_mode(FIPS_PRNG_CTX *ctx) + { + if (ctx->keyed) + { + RANDerr(RAND_F_FIPS_SET_TEST_MODE,RAND_R_PRNG_KEYED); + return 0; + } + ctx->test_mode = 1; + return 1; + } + +int FIPS_rand_test_mode(void) + { + return fips_set_test_mode(&sctx); + } + +int FIPS_rand_set_dt(unsigned char *dt) + { + if (!sctx.test_mode) + { + RANDerr(RAND_F_FIPS_RAND_SET_DT,RAND_R_NOT_IN_TEST_MODE); + return 0; + } + memcpy(sctx.DT, dt, AES_BLOCK_LENGTH); + return 1; + } + +static void fips_get_dt(FIPS_PRNG_CTX *ctx) + { +#ifdef OPENSSL_SYS_WIN32 + FILETIME ft; +#else + struct timeval tv; +#endif + unsigned char *buf = ctx->DT; + +#ifndef GETPID_IS_MEANINGLESS + unsigned long pid; +#endif + +#ifdef OPENSSL_SYS_WIN32 + GetSystemTimeAsFileTime(&ft); + buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff); + buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff); + buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff); + buf[3] = (unsigned char) ((ft.dwHighDateTime >> 24) & 0xff); + buf[4] = (unsigned char) (ft.dwLowDateTime & 0xff); + buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff); + buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff); + buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff); +#else + gettimeofday(&tv,NULL); + buf[0] = (unsigned char) (tv.tv_sec & 0xff); + buf[1] = (unsigned char) ((tv.tv_sec >> 8) & 0xff); + buf[2] = (unsigned char) ((tv.tv_sec >> 16) & 0xff); + buf[3] = (unsigned char) ((tv.tv_sec >> 24) & 0xff); + buf[4] = (unsigned char) (tv.tv_usec & 0xff); + buf[5] = (unsigned char) ((tv.tv_usec >> 8) & 0xff); + buf[6] = (unsigned char) ((tv.tv_usec >> 16) & 0xff); + buf[7] = (unsigned char) ((tv.tv_usec >> 24) & 0xff); +#endif + buf[8] = (unsigned char) (ctx->counter & 0xff); + buf[9] = (unsigned char) ((ctx->counter >> 8) & 0xff); + buf[10] = (unsigned char) ((ctx->counter >> 16) & 0xff); + buf[11] = (unsigned char) ((ctx->counter >> 24) & 0xff); + + ctx->counter++; + + +#ifndef GETPID_IS_MEANINGLESS + pid=(unsigned long)getpid(); + buf[12] = (unsigned char) (pid & 0xff); + buf[13] = (unsigned char) ((pid >> 8) & 0xff); + buf[14] = (unsigned char) ((pid >> 16) & 0xff); + buf[15] = (unsigned char) ((pid >> 24) & 0xff); +#endif + } + +static int fips_rand(FIPS_PRNG_CTX *ctx, + unsigned char *out, FIPS_RAND_SIZE_T outlen) + { + unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH]; + unsigned char tmp[AES_BLOCK_LENGTH]; + int i; + if (ctx->error) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR); + return 0; + } + if (!ctx->keyed) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_NO_KEY_SET); + return 0; + } + if (!ctx->seeded) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_NOT_SEEDED); + return 0; + } + for (;;) + { + if (!ctx->test_mode) + fips_get_dt(ctx); + AES_encrypt(ctx->DT, I, &ctx->ks); + for (i = 0; i < AES_BLOCK_LENGTH; i++) + tmp[i] = I[i] ^ ctx->V[i]; + AES_encrypt(tmp, R, &ctx->ks); + for (i = 0; i < AES_BLOCK_LENGTH; i++) + tmp[i] = R[i] ^ I[i]; + AES_encrypt(tmp, ctx->V, &ctx->ks); + /* Continuous PRNG test */ + if (ctx->second) + { + if (fips_prng_fail) + memcpy(ctx->last, R, AES_BLOCK_LENGTH); + if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH)) + { + RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_STUCK); + ctx->error = 1; + fips_set_selftest_fail(); + return 0; + } + } + memcpy(ctx->last, R, AES_BLOCK_LENGTH); + if (!ctx->second) + { + ctx->second = 1; + if (!ctx->test_mode) + continue; + } + + if (outlen <= AES_BLOCK_LENGTH) + { + memcpy(out, R, outlen); + break; + } + + memcpy(out, R, AES_BLOCK_LENGTH); + out += AES_BLOCK_LENGTH; + outlen -= AES_BLOCK_LENGTH; + } + return 1; + } + + +int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_set_prng_key(&sctx, key, keylen); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +int FIPS_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_set_prng_seed(&sctx, seed, seedlen); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + + +int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T count) + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + ret = fips_rand(&sctx, out, count); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +int FIPS_rand_status(void) + { + int ret; + CRYPTO_r_lock(CRYPTO_LOCK_RAND); + ret = sctx.seeded; + CRYPTO_r_unlock(CRYPTO_LOCK_RAND); + return ret; + } + +void FIPS_rand_reset(void) + { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + fips_rand_prng_reset(&sctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + +static void fips_do_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen) + { + FIPS_rand_seed(seed, seedlen); + } + +static void fips_do_rand_add(const void *seed, FIPS_RAND_SIZE_T seedlen, + double add_entropy) + { + FIPS_rand_seed(seed, seedlen); + } + +static const RAND_METHOD rand_fips_meth= + { + fips_do_rand_seed, + FIPS_rand_bytes, + FIPS_rand_reset, + fips_do_rand_add, + FIPS_rand_bytes, + FIPS_rand_status + }; + +const RAND_METHOD *FIPS_rand_method(void) +{ + return &rand_fips_meth; +} + +#endif diff --git a/fips/rand/fips_rand.h b/fips/rand/fips_rand.h new file mode 100644 index 0000000000..a175aaf6c5 --- /dev/null +++ b/fips/rand/fips_rand.h @@ -0,0 +1,77 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef HEADER_FIPS_RAND_H +#define HEADER_FIPS_RAND_H + +#include "des.h" + +#ifdef OPENSSL_FIPS + +#ifdef __cplusplus +extern "C" { +#endif + +int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen); +int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num); +int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen); + +int FIPS_rand_test_mode(void); +void FIPS_rand_reset(void); +int FIPS_rand_set_dt(unsigned char *dt); + +int FIPS_rand_status(void); + +const RAND_METHOD *FIPS_rand_method(void); + +#ifdef __cplusplus +} +#endif +#endif +#endif diff --git a/fips/rand/fips_rand_selftest.c b/fips/rand/fips_rand_selftest.c new file mode 100644 index 0000000000..2194a76cd1 --- /dev/null +++ b/fips/rand/fips_rand_selftest.c @@ -0,0 +1,371 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + + + +typedef struct + { + unsigned char DT[16]; + unsigned char V[16]; + unsigned char R[16]; + } AES_PRNG_TV; + +/* The following test vectors are taken directly from the RGNVS spec */ + +static unsigned char aes_128_key[16] = + {0xf3,0xb1,0x66,0x6d,0x13,0x60,0x72,0x42, + 0xed,0x06,0x1c,0xab,0xb8,0xd4,0x62,0x02}; + +static AES_PRNG_TV aes_128_tv[] = { + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xf9}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x59,0x53,0x1e,0xd1,0x3b,0xb0,0xc0,0x55, + 0x84,0x79,0x66,0x85,0xc1,0x2f,0x76,0x41} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfa}, + /* V */ + {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x7c,0x22,0x2c,0xf4,0xca,0x8f,0xa2,0x4c, + 0x1c,0x9c,0xb6,0x41,0xa9,0xf3,0x22,0x0d} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfb}, + /* V */ + {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x8a,0xaa,0x00,0x39,0x66,0x67,0x5b,0xe5, + 0x29,0x14,0x28,0x81,0xa9,0x4d,0x4e,0xc7} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfc}, + /* V */ + {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x88,0xdd,0xa4,0x56,0x30,0x24,0x23,0xe5, + 0xf6,0x9d,0xa5,0x7e,0x7b,0x95,0xc7,0x3a} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfd}, + /* V */ + {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x05,0x25,0x92,0x46,0x61,0x79,0xd2,0xcb, + 0x78,0xc4,0x0b,0x14,0x0a,0x5a,0x9a,0xc8} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x77}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe}, + /* R */ + {0x0d,0xd5,0xa0,0x36,0x7a,0x59,0x26,0xbc, + 0x48,0xd9,0x38,0xbf,0xf0,0x85,0x8f,0xea} + }, + { + /* DT */ + {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62, + 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x78}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + /* R */ + {0xae,0x53,0x87,0xee,0x8c,0xd9,0x12,0xf5, + 0x73,0x53,0xae,0x03,0xf9,0xd5,0x13,0x33} + }, +}; + +static unsigned char aes_192_key[24] = + {0x15,0xd8,0x78,0x0d,0x62,0xd3,0x25,0x6e, + 0x44,0x64,0x10,0x13,0x60,0x2b,0xa9,0xbc, + 0x4a,0xfb,0xca,0xeb,0x4c,0x8b,0x99,0x3b}; + +static AES_PRNG_TV aes_192_tv[] = { + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4b}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x17,0x07,0xd5,0x28,0x19,0x79,0x1e,0xef, + 0xa5,0x0c,0xbf,0x25,0xe5,0x56,0xb4,0x93} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4c}, + /* V */ + {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x92,0x8d,0xbe,0x07,0xdd,0xc7,0x58,0xc0, + 0x6f,0x35,0x41,0x9b,0x17,0xc9,0xbd,0x9b} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4d}, + /* V */ + {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0xd5,0xde,0xf4,0x50,0xf3,0xb7,0x10,0x4e, + 0xb8,0xc6,0xf8,0xcf,0xe2,0xb1,0xca,0xa2} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4e}, + /* V */ + {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0xce,0x29,0x08,0x43,0xfc,0x34,0x41,0xe7, + 0x47,0x8f,0xb3,0x66,0x2b,0x46,0xb1,0xbb} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4f}, + /* V */ + {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0xb3,0x26,0x0f,0xf5,0xd6,0xca,0xa8,0xbf, + 0x89,0xb8,0x5e,0x2f,0x22,0x56,0x92,0x2f} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xc9}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe}, + /* R */ + {0x05,0xeb,0x18,0x52,0x34,0x43,0x00,0x43, + 0x6e,0x5a,0xa5,0xfe,0x7b,0x32,0xc4,0x2d} + }, + { + /* DT */ + {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1, + 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xca}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + /* R */ + {0x15,0x3c,0xe8,0xd1,0x04,0xc7,0xad,0x50, + 0x0b,0xf0,0x07,0x16,0xe7,0x56,0x7a,0xea} + }, +}; + +static unsigned char aes_256_key[32] = + {0x6d,0x14,0x06,0x6c,0xb6,0xd8,0x21,0x2d, + 0x82,0x8d,0xfa,0xf2,0x7a,0x03,0xb7,0x9f, + 0x0c,0xc7,0x3e,0xcd,0x76,0xeb,0xee,0xb5, + 0x21,0x05,0x8c,0x4f,0x31,0x7a,0x80,0xbb}; + +static AES_PRNG_TV aes_256_tv[] = { + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x88}, + /* V */ + {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x35,0xc7,0xef,0xa7,0x78,0x4d,0x29,0xbc, + 0x82,0x79,0x99,0xfb,0xd0,0xb3,0x3b,0x72} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x89}, + /* V */ + {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x6c,0xf4,0x42,0x5d,0xc7,0x04,0x1a,0x41, + 0x28,0x2a,0x78,0xa9,0xb0,0x12,0xc4,0x95} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8a}, + /* V */ + {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x16,0x90,0xa4,0xff,0x7b,0x7e,0xb9,0x30, + 0xdb,0x67,0x4b,0xac,0x2d,0xe1,0xd1,0x75} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8b}, + /* V */ + {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x14,0x6f,0xf5,0x95,0xa1,0x46,0x65,0x30, + 0xbc,0x57,0xe2,0x4a,0xf7,0x45,0x62,0x05} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8c}, + /* V */ + {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + /* R */ + {0x96,0xe2,0xb4,0x1e,0x66,0x5e,0x0f,0xa4, + 0xc5,0xcd,0xa2,0x07,0xcc,0xb7,0x94,0x40} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x06}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe}, + /* R */ + {0x61,0xce,0x1d,0x6a,0x48,0x75,0x97,0x28, + 0x4b,0x41,0xde,0x18,0x44,0x4f,0x56,0xec} + }, + { + /* DT */ + {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5, + 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x07}, + /* V */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + /* R */ + {0x52,0x89,0x59,0x79,0x2d,0xaa,0x28,0xb3, + 0xb0,0x8a,0x3e,0x70,0xfa,0x71,0x59,0x84} + }, +}; + + +void FIPS_corrupt_rng() + { + aes_192_tv[0].V[0]++; + } + +#define fips_rand_test(key, tv) \ + do_rand_test(key, sizeof key, tv, sizeof(tv)/sizeof(AES_PRNG_TV)) + +static int do_rand_test(unsigned char *key, int keylen, + AES_PRNG_TV *tv, int ntv) + { + unsigned char R[16]; + int i; + if (!FIPS_rand_set_key(key, keylen)) + return 0; + for (i = 0; i < ntv; i++) + { + FIPS_rand_seed(tv[i].V, 16); + FIPS_rand_set_dt(tv[i].DT); + FIPS_rand_bytes(R, 16); + if (memcmp(R, tv[i].R, 16)) + return 0; + } + return 1; + } + + +int FIPS_selftest_rng() + { + FIPS_rand_reset(); + if (!FIPS_rand_test_mode()) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED); + return 0; + } + if (!fips_rand_test(aes_128_key,aes_128_tv) + || !fips_rand_test(aes_192_key, aes_192_tv) + || !fips_rand_test(aes_256_key, aes_256_tv)) + { + FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED); + return 0; + } + FIPS_rand_reset(); + return 1; + } + +#endif diff --git a/fips/rand/fips_randtest.c b/fips/rand/fips_randtest.c new file mode 100644 index 0000000000..5582941c11 --- /dev/null +++ b/fips/rand/fips_randtest.c @@ -0,0 +1,248 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "e_os.h" + +#ifndef OPENSSL_FIPS +int main(int argc, char *argv[]) +{ + printf("No FIPS RAND support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +typedef struct + { + unsigned char DT[16]; + unsigned char V[16]; + unsigned char R[16]; + } AES_PRNG_MCT; + +static unsigned char aes_128_mct_key[16] = + {0x9f,0x5b,0x51,0x20,0x0b,0xf3,0x34,0xb5, + 0xd8,0x2b,0xe8,0xc3,0x72,0x55,0xc8,0x48}; + +static AES_PRNG_MCT aes_128_mct_tv = { + /* DT */ + {0x63,0x76,0xbb,0xe5,0x29,0x02,0xba,0x3b, + 0x67,0xc9,0x25,0xfa,0x70,0x1f,0x11,0xac}, + /* V */ + {0x57,0x2c,0x8e,0x76,0x87,0x26,0x47,0x97, + 0x7e,0x74,0xfb,0xdd,0xc4,0x95,0x01,0xd1}, + /* R */ + {0x48,0xe9,0xbd,0x0d,0x06,0xee,0x18,0xfb, + 0xe4,0x57,0x90,0xd5,0xc3,0xfc,0x9b,0x73} +}; + +static unsigned char aes_192_mct_key[24] = + {0xb7,0x6c,0x34,0xd1,0x09,0x67,0xab,0x73, + 0x4d,0x5a,0xd5,0x34,0x98,0x16,0x0b,0x91, + 0xbc,0x35,0x51,0x16,0x6b,0xae,0x93,0x8a}; + +static AES_PRNG_MCT aes_192_mct_tv = { + /* DT */ + {0x84,0xce,0x22,0x7d,0x91,0x5a,0xa3,0xc9, + 0x84,0x3c,0x0a,0xb3,0xa9,0x63,0x15,0x52}, + /* V */ + {0xb6,0xaf,0xe6,0x8f,0x99,0x9e,0x90,0x64, + 0xdd,0xc7,0x7a,0xc1,0xbb,0x90,0x3a,0x6d}, + /* R */ + {0xfc,0x85,0x60,0x9a,0x29,0x6f,0xef,0x21, + 0xdd,0x86,0x20,0x32,0x8a,0x29,0x6f,0x47} +}; + +static unsigned char aes_256_mct_key[32] = + {0x9b,0x05,0xc8,0x68,0xff,0x47,0xf8,0x3a, + 0xa6,0x3a,0xa8,0xcb,0x4e,0x71,0xb2,0xe0, + 0xb8,0x7e,0xf1,0x37,0xb6,0xb4,0xf6,0x6d, + 0x86,0x32,0xfc,0x1f,0x5e,0x1d,0x1e,0x50}; + +static AES_PRNG_MCT aes_256_mct_tv = { + /* DT */ + {0x31,0x6e,0x35,0x9a,0xb1,0x44,0xf0,0xee, + 0x62,0x6d,0x04,0x46,0xe0,0xa3,0x92,0x4c}, + /* V */ + {0x4f,0xcd,0xc1,0x87,0x82,0x1f,0x4d,0xa1, + 0x3e,0x0e,0x56,0x44,0x59,0xe8,0x83,0xca}, + /* R */ + {0xc8,0x87,0xc2,0x61,0x5b,0xd0,0xb9,0xe1, + 0xe7,0xf3,0x8b,0xd7,0x5b,0xd5,0xf1,0x8d} +}; + +static void dump(const unsigned char *b,int n) + { + while(n-- > 0) + { + printf(" %02x",*b++); + } + } + +static void compare(const unsigned char *result,const unsigned char *expected, + int n) + { + int i; + + for(i=0 ; i < n ; ++i) + if(result[i] != expected[i]) + { + puts("Random test failed, got:"); + dump(result,n); + puts("\n expected:"); + dump(expected,n); + putchar('\n'); + EXIT(1); + } + } + + +static void run_test(unsigned char *key, int keylen, AES_PRNG_MCT *tv) + { + unsigned char buf[16], dt[16]; + int i, j; + FIPS_rand_reset(); + FIPS_rand_test_mode(); + FIPS_rand_set_key(key, keylen); + FIPS_rand_seed(tv->V, 16); + memcpy(dt, tv->DT, 16); + for (i = 0; i < 10000; i++) + { + FIPS_rand_set_dt(dt); + FIPS_rand_bytes(buf, 16); + /* Increment DT */ + for (j = 15; j >= 0; j--) + { + dt[j]++; + if (dt[j]) + break; + } + } + + compare(buf,tv->R, 16); + } + +int main() + { + run_test(aes_128_mct_key, 16, &aes_128_mct_tv); + printf("FIPS PRNG test 1 done\n"); + run_test(aes_192_mct_key, 24, &aes_192_mct_tv); + printf("FIPS PRNG test 2 done\n"); + run_test(aes_256_mct_key, 32, &aes_256_mct_tv); + printf("FIPS PRNG test 3 done\n"); + return 0; + } + +#endif diff --git a/fips/rand/fips_rngvs.c b/fips/rand/fips_rngvs.c new file mode 100644 index 0000000000..5b454aa7d1 --- /dev/null +++ b/fips/rand/fips_rngvs.c @@ -0,0 +1,229 @@ +/* + * Crude test driver for processing the VST and MCT testvector files + * generated by the CMVP RNGVS product. + * + * Note the input files are assumed to have a _very_ specific format + * as described in the NIST document "The Random Number Generator + * Validation System (RNGVS)", May 25, 2004. + * + */ +#include + +#ifndef OPENSSL_FIPS +#include +int main() +{ + printf("No FIPS RNG support\n"); + return 0; +} +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fips_utl.h" + +void vst() + { + unsigned char *key = NULL; + unsigned char *v = NULL; + unsigned char *dt = NULL; + unsigned char ret[16]; + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + long i, keylen; + + keylen = 0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if(!strncmp(buf,"[AES 128-Key]", 13)) + keylen = 16; + else if(!strncmp(buf,"[AES 192-Key]", 13)) + keylen = 24; + else if(!strncmp(buf,"[AES 256-Key]", 13)) + keylen = 32; + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Key")) + { + key=hex2bin_m(value,&i); + if (i != keylen) + { + fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); + return; + } + } + else if(!strcmp(keyword,"DT")) + { + dt=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid DT length\n"); + return; + } + } + else if(!strcmp(keyword,"V")) + { + v=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid V length\n"); + return; + } + + if (!key || !dt) + { + fprintf(stderr, "Missing key or DT\n"); + return; + } + + FIPS_rand_set_key(key, keylen); + FIPS_rand_seed(v,16); + FIPS_rand_set_dt(dt); + if (FIPS_rand_bytes(ret,16) <= 0) + { + fprintf(stderr, "Error getting PRNG value\n"); + return; + } + + pv("R",ret,16); + OPENSSL_free(key); + key = NULL; + OPENSSL_free(dt); + dt = NULL; + OPENSSL_free(v); + v = NULL; + } + } + } + +void mct() + { + unsigned char *key = NULL; + unsigned char *v = NULL; + unsigned char *dt = NULL; + unsigned char ret[16]; + char buf[1024]; + char lbuf[1024]; + char *keyword, *value; + long i, keylen; + int j; + + keylen = 0; + + while(fgets(buf,sizeof buf,stdin) != NULL) + { + fputs(buf,stdout); + if(!strncmp(buf,"[AES 128-Key]", 13)) + keylen = 16; + else if(!strncmp(buf,"[AES 192-Key]", 13)) + keylen = 24; + else if(!strncmp(buf,"[AES 256-Key]", 13)) + keylen = 32; + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + if(!strcmp(keyword,"Key")) + { + key=hex2bin_m(value,&i); + if (i != keylen) + { + fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); + return; + } + } + else if(!strcmp(keyword,"DT")) + { + dt=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid DT length\n"); + return; + } + } + else if(!strcmp(keyword,"V")) + { + v=hex2bin_m(value,&i); + if (i != 16) + { + fprintf(stderr, "Invalid V length\n"); + return; + } + + if (!key || !dt) + { + fprintf(stderr, "Missing key or DT\n"); + return; + } + + FIPS_rand_set_key(key, keylen); + FIPS_rand_seed(v,16); + for (i = 0; i < 10000; i++) + { + FIPS_rand_set_dt(dt); + if (FIPS_rand_bytes(ret,16) <= 0) + { + fprintf(stderr, "Error getting PRNG value\n"); + return; + } + /* Increment DT */ + for (j = 15; j >= 0; j--) + { + dt[j]++; + if (dt[j]) + break; + } + } + + pv("R",ret,16); + OPENSSL_free(key); + key = NULL; + OPENSSL_free(dt); + dt = NULL; + OPENSSL_free(v); + v = NULL; + } + } + } + +int main(int argc,char **argv) + { + if(argc != 2) + { + fprintf(stderr,"%s [mct|vst]\n",argv[0]); + exit(1); + } + if(!FIPS_mode_set(1)) + { + do_print_errors(); + exit(1); + } + FIPS_rand_reset(); + if (!FIPS_rand_test_mode()) + { + fprintf(stderr, "Error setting PRNG test mode\n"); + do_print_errors(); + exit(1); + } + if(!strcmp(argv[1],"mct")) + mct(); + else if(!strcmp(argv[1],"vst")) + vst(); + else + { + fprintf(stderr,"Don't know how to %s.\n",argv[1]); + exit(1); + } + + return 0; + } +#endif diff --git a/fips/rsa/.cvsignore b/fips/rsa/.cvsignore new file mode 100644 index 0000000000..439e6d3eb6 --- /dev/null +++ b/fips/rsa/.cvsignore @@ -0,0 +1,4 @@ +lib +Makefile.save +*.flc +semantic.cache diff --git a/fips/rsa/Makefile b/fips/rsa/Makefile new file mode 100644 index 0000000000..398878a0d9 --- /dev/null +++ b/fips/rsa/Makefile @@ -0,0 +1,211 @@ +# +# OpenSSL/fips/rsa/Makefile +# + +DIR= rsa +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= fips_rsavtest.c fips_rsastest.c fips_rsagtest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_rsa_eay.c fips_rsa_gen.c fips_rsa_selftest.c fips_rsa_x931g.c \ + fips_rsa_sign.c fips_rsa_lib.c +LIBOBJ=fips_rsa_eay.o fips_rsa_gen.o fips_rsa_selftest.o fips_rsa_x931g.o \ + fips_rsa_sign.o fips_rsa_lib.o + +SRC= $(LIBSRC) + +EXHEADER= +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +Q=../testvectors/rsa/req +A=../testvectors/rsa/rsp +Q62=../testvectors/rsa_salt_62/req +A62=../testvectors/rsa_salt_62/rsp + +fips_test: + -rm -rf $(A) $(A62) + mkdir $(A) $(A62) + if [ -f $(Q)/SigGen15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest < $(Q)/SigGen15.req > $(A)/SigGen15.rsp; fi + if [ -f $(Q)/SigVer15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest < $(Q)/SigVer15.req > $(A)/SigVer15.rsp; fi + if [ -f $(Q)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 0 < $(Q)/SigGenPSS.req > $(A)/SigGenPSS.rsp; fi + if [ -f $(Q)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 0 < $(Q)/SigVerPSS.req > $(A)/SigVerPSS.rsp; fi + if [ -f $(Q)/SigGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -x931 < $(Q)/SigGenRSA.req > $(A)/SigGenRSA.rsp; fi + if [ -f $(Q)/SigVerRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -x931 < $(Q)/SigVerRSA.req > $(A)/SigVerRSA.rsp; fi + if [ -f $(Q62)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 62 < $(Q62)/SigGenPSS.req >$(A62)/SigGenPSS.rsp; fi + if [ -f $(Q62)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 62 <$(Q62)/SigVerPSS.req >$(A62)/SigVerPSS.rsp; fi + if [ -f $(Q)/KeyGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsagtest < $(Q)/KeyGenRSA.req > $(A)/KeyGenRSA.rsp; fi + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_rsa_eay.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_eay.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_eay.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_rsa_eay.o: ../../include/openssl/opensslconf.h +fips_rsa_eay.o: ../../include/openssl/opensslv.h +fips_rsa_eay.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_rsa_eay.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +fips_rsa_eay.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rsa_eay.o: fips_rsa_eay.c +fips_rsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_gen.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_rsa_gen.o: ../../include/openssl/objects.h +fips_rsa_gen.o: ../../include/openssl/opensslconf.h +fips_rsa_gen.o: ../../include/openssl/opensslv.h +fips_rsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h +fips_rsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_rsa_gen.o: ../../include/openssl/symhacks.h fips_rsa_gen.c +fips_rsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rsa_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rsa_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_rsa_lib.o: ../../include/openssl/obj_mac.h ../../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_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_selftest.o: ../../include/openssl/crypto.h +fips_rsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsa_selftest.o: ../../include/openssl/lhash.h +fips_rsa_selftest.o: ../../include/openssl/obj_mac.h +fips_rsa_selftest.o: ../../include/openssl/objects.h +fips_rsa_selftest.o: ../../include/openssl/opensslconf.h +fips_rsa_selftest.o: ../../include/openssl/opensslv.h +fips_rsa_selftest.o: ../../include/openssl/ossl_typ.h +fips_rsa_selftest.o: ../../include/openssl/rsa.h +fips_rsa_selftest.o: ../../include/openssl/safestack.h +fips_rsa_selftest.o: ../../include/openssl/stack.h +fips_rsa_selftest.o: ../../include/openssl/symhacks.h fips_rsa_selftest.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_rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rsa_x931g.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +fips_rsa_x931g.o: ../../include/openssl/opensslconf.h +fips_rsa_x931g.o: ../../include/openssl/opensslv.h +fips_rsa_x931g.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h +fips_rsa_x931g.o: ../../include/openssl/safestack.h +fips_rsa_x931g.o: ../../include/openssl/stack.h +fips_rsa_x931g.o: ../../include/openssl/symhacks.h fips_rsa_x931g.c +fips_rsagtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsagtest.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +fips_rsagtest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rsagtest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +fips_rsagtest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +fips_rsagtest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsagtest.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_rsagtest.o: ../../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/pkcs7.h +fips_rsagtest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_rsagtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rsagtest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +fips_rsagtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsagtest.c +fips_rsastest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsastest.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +fips_rsastest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rsastest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +fips_rsastest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +fips_rsastest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsastest.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_rsastest.o: ../../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/pkcs7.h +fips_rsastest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_rsastest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rsastest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +fips_rsastest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsastest.c +fips_rsavtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsavtest.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +fips_rsavtest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rsavtest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +fips_rsavtest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +fips_rsavtest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rsavtest.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_rsavtest.o: ../../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/pkcs7.h +fips_rsavtest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_rsavtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rsavtest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +fips_rsavtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsavtest.c diff --git a/fips/rsa/fips_rsa_eay.c b/fips/rsa/fips_rsa_eay.c new file mode 100644 index 0000000000..937a14e684 --- /dev/null +++ b/fips/rsa/fips_rsa_eay.c @@ -0,0 +1,934 @@ +/* crypto/rsa/rsa_eay.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +#if !defined(RSA_NULL) && defined(OPENSSL_FIPS) + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx); +static int RSA_eay_init(RSA *rsa); +static int RSA_eay_finish(RSA *rsa); +static RSA_METHOD rsa_pkcs1_eay_meth={ + "Eric Young's PKCS#1 RSA", + RSA_eay_public_encrypt, + RSA_eay_public_decrypt, /* signature verification */ + RSA_eay_private_encrypt, /* signing */ + RSA_eay_private_decrypt, + RSA_eay_mod_exp, + BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */ + RSA_eay_init, + RSA_eay_finish, + RSA_FLAG_FIPS_METHOD, /* flags */ + NULL, + 0, /* rsa_sign */ + 0, /* rsa_verify */ + NULL /* rsa_keygen */ + }; + +const RSA_METHOD *RSA_PKCS1_SSLeay(void) + { + return(&rsa_pkcs1_eay_meth); + } + +/* Usage example; + * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + */ +#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \ + if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \ + !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \ + CRYPTO_LOCK_RSA, \ + (rsa)->m, (ctx))) \ + err_instr + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f,*ret; + int i,j,k,num=0,r= -1; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) + { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx=BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num=BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) + { + case RSA_PKCS1_PADDING: + i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen); + break; +#ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0); + break; +#endif + case RSA_SSLV23_PADDING: + i=RSA_padding_add_SSLv23(buf,num,from,flen); + break; + case RSA_NO_PADDING: + i=RSA_padding_add_none(buf,num,from,flen); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) goto err; + + if (BN_bin2bn(buf,num,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + + /* put in leading 0 bytes if the number is less than the + * length of the modulus */ + j=BN_num_bytes(ret); + i=BN_bn2bin(ret,&(to[num-j])); + for (k=0; k<(num-i); k++) + to[k]=0; + + r=num; +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) +{ + BN_BLINDING *ret; + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_RSA); + + if (rsa->blinding == NULL) + { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + + if (rsa->blinding == NULL) + rsa->blinding = RSA_setup_blinding(rsa, ctx); + } + + ret = rsa->blinding; + if (ret == NULL) + goto err; + + if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) + { + /* rsa->blinding is ours! */ + + *local = 1; + } + else + { + /* resort to rsa->mt_blinding instead */ + + *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert() + * that the BN_BLINDING is shared, meaning that accesses + * require locks, and that the blinding factor must be + * stored outside the BN_BLINDING + */ + + if (rsa->mt_blinding == NULL) + { + if (!got_write_lock) + { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + } + + if (rsa->mt_blinding == NULL) + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + } + ret = rsa->mt_blinding; + } + + err: + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RSA); + else + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + return ret; +} + +static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f, + BIGNUM *r, BN_CTX *ctx) +{ + if (local) + return BN_BLINDING_convert_ex(f, NULL, b, ctx); + else + { + int ret; + CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING); + ret = BN_BLINDING_convert_ex(f, r, b, ctx); + CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING); + return ret; + } +} + +static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f, + BIGNUM *r, BN_CTX *ctx) +{ + if (local) + return BN_BLINDING_invert_ex(f, NULL, b, ctx); + else + { + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); + ret = BN_BLINDING_invert_ex(f, r, b, ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); + return ret; + } +} + +/* signing */ +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f, *ret, *br, *res; + int i,j,k,num=0,r= -1; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + int local_blinding = 0; + BN_BLINDING *blinding = NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if ((ctx=BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + br = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if(!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) + { + case RSA_PKCS1_PADDING: + i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen); + break; + case RSA_X931_PADDING: + i=RSA_padding_add_X931(buf,num,from,flen); + break; + case RSA_NO_PADDING: + i=RSA_padding_add_none(buf,num,from,flen); + break; + case RSA_SSLV23_PADDING: + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) goto err; + + if (BN_bin2bn(buf,num,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) + { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) + if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + goto err; + + if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && + (rsa->dmq1 != NULL) && + (rsa->iqmp != NULL)) ) + { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; + } + else + { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + BN_init(&local_d); + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + goto err; + + if (padding == RSA_X931_PADDING) + { + BN_sub(f, rsa->n, ret); + if (BN_cmp(ret, f)) + res = f; + else + res = ret; + } + else + res = ret; + + /* put in leading 0 bytes if the number is less than the + * length of the modulus */ + j=BN_num_bytes(res); + i=BN_bn2bin(res,&(to[num-j])); + for (k=0; k<(num-i); k++) + to[k]=0; + + r=num; +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f, *ret, *br; + int j,num=0,r= -1; + unsigned char *p; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + int local_blinding = 0; + BN_BLINDING *blinding = NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if((ctx = BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + br = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if(!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* make data into a big number */ + if (BN_bin2bn(from,(int)flen,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) + { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) + if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx)) + goto err; + + /* do the decrypt */ + if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && + (rsa->dmq1 != NULL) && + (rsa->iqmp != NULL)) ) + { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; + } + else + { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx, + rsa->_method_mod_n)) + goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx)) + goto err; + + p=buf; + j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */ + + switch (padding) + { + case RSA_PKCS1_PADDING: + r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); + break; +#ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); + break; +#endif + case RSA_SSLV23_PADDING: + r=RSA_padding_check_SSLv23(to,num,buf,j,num); + break; + case RSA_NO_PADDING: + r=RSA_padding_check_none(to,num,buf,j,num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED); + +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +/* signature verification */ +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f,*ret; + int i,num=0,r= -1; + unsigned char *p; + unsigned char *buf=NULL; + BN_CTX *ctx=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) + { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if((ctx = BN_CTX_new()) == NULL) goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num=BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if(!f || !ret || !buf) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* This check was for equality but PGP does evil things + * and chops off the top '0' bytes */ + if (flen > num) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + if (BN_bin2bn(from,flen,f) == NULL) goto err; + + if (BN_ucmp(f, rsa->n) >= 0) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + + if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12)) + BN_sub(ret, rsa->n, ret); + + p=buf; + i=BN_bn2bin(ret,p); + + switch (padding) + { + case RSA_PKCS1_PADDING: + r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num); + break; + case RSA_X931_PADDING: + r=RSA_padding_check_X931(to,num,buf,i,num); + break; + case RSA_NO_PADDING: + r=RSA_padding_check_none(to,num,buf,i,num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED); + +err: + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) + { + OPENSSL_cleanse(buf,num); + OPENSSL_free(buf); + } + return(r); + } + +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) + { + BIGNUM *r1,*m1,*vrfy; + BIGNUM local_dmp1,local_dmq1,local_c,local_r1; + BIGNUM *dmp1,*dmq1,*c,*pr1; + int bn_flags; + int ret=0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->p->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->p->flags |= BN_FLG_CONSTTIME; + } + MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->p->flags = bn_flags; + + /* Make sure mod_inverse in montgomerey intialization use correct + * BN_FLG_CONSTTIME flag. + */ + bn_flags = rsa->q->flags; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + rsa->q->flags |= BN_FLG_CONSTTIME; + } + MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); + /* We restore bn_flags back */ + rsa->q->flags = bn_flags; + + MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err); + + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1,c,rsa->q,ctx)) goto err; + } + else + { + if (!BN_mod(r1,I,rsa->q,ctx)) goto err; + } + + /* compute r1^dmq1 mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + dmq1 = &local_dmq1; + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + } + else + dmq1 = rsa->dmq1; + if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx, + rsa->_method_mod_q)) goto err; + + /* compute I mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1,c,rsa->p,ctx)) goto err; + } + else + { + if (!BN_mod(r1,I,rsa->p,ctx)) goto err; + } + + /* compute r1^dmp1 mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + dmp1 = &local_dmp1; + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + } + else + dmp1 = rsa->dmp1; + if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx, + rsa->_method_mod_p)) goto err; + + if (!BN_sub(r0,r0,m1)) goto err; + /* This will help stop the size of r0 increasing, which does + * affect the multiply if it optimised for a power of 2 size */ + if (BN_is_negative(r0)) + if (!BN_add(r0,r0,rsa->p)) goto err; + + if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err; + + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + pr1 = &local_r1; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + } + else + pr1 = r1; + if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err; + + /* If p < q it is occasionally possible for the correction of + * adding 'p' if r0 is negative above to leave the result still + * negative. This can break the private key operations: the following + * second correction should *always* correct this rare occurrence. + * This will *never* happen with OpenSSL generated keys because + * they ensure p > q [steve] + */ + if (BN_is_negative(r0)) + if (!BN_add(r0,r0,rsa->p)) goto err; + if (!BN_mul(r1,r0,rsa->q,ctx)) goto err; + if (!BN_add(r0,r1,m1)) goto err; + + if (rsa->e && rsa->n) + { + if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err; + /* If 'I' was greater than (or equal to) rsa->n, the operation + * will be equivalent to using 'I mod n'. However, the result of + * the verify will *always* be less than 'n' so we don't check + * for absolute equality, just congruency. */ + if (!BN_sub(vrfy, vrfy, I)) goto err; + if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; + if (BN_is_negative(vrfy)) + if (!BN_add(vrfy, vrfy, rsa->n)) goto err; + if (!BN_is_zero(vrfy)) + { + /* 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) + * mod_exp and return that instead. */ + + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx, + rsa->_method_mod_n)) goto err; + } + } + ret=1; +err: + BN_CTX_end(ctx); + return(ret); + } + +static int RSA_eay_init(RSA *rsa) + { + FIPS_selftest_check(); + rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE; + return(1); + } + +static int RSA_eay_finish(RSA *rsa) + { + if (rsa->_method_mod_n != NULL) + BN_MONT_CTX_free(rsa->_method_mod_n); + if (rsa->_method_mod_p != NULL) + BN_MONT_CTX_free(rsa->_method_mod_p); + if (rsa->_method_mod_q != NULL) + BN_MONT_CTX_free(rsa->_method_mod_q); + return(1); + } + +#endif diff --git a/fips/rsa/fips_rsa_gen.c b/fips/rsa/fips_rsa_gen.c new file mode 100644 index 0000000000..90aaa2f095 --- /dev/null +++ b/fips/rsa/fips_rsa_gen.c @@ -0,0 +1,310 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + +/* NB: these functions have been "upgraded", the deprecated versions (which are + * compatibility wrappers using these functions) are in rsa_depr.c. + * - Geoff + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +static int fips_rsa_pairwise_fail = 0; + +void FIPS_corrupt_rsa_keygen(void) + { + fips_rsa_pairwise_fail = 1; + } + +int fips_check_rsa(RSA *rsa) + { + const unsigned char tbs[] = "RSA Pairwise Check Data"; + unsigned char *ctbuf = NULL, *ptbuf = NULL; + int len, ret = 0; + EVP_PKEY pk; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa; + + /* Perform pairwise consistency signature test */ + if (!fips_pkey_signature_test(&pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, NULL) + || !fips_pkey_signature_test(&pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, NULL) + || !fips_pkey_signature_test(&pk, tbs, -1, + NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, NULL)) + goto err; + /* Now perform pairwise consistency encrypt/decrypt test */ + ctbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!ctbuf) + goto err; + + len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING); + if (len <= 0) + goto err; + /* Check ciphertext doesn't match plaintext */ + if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len)) + goto err; + ptbuf = OPENSSL_malloc(RSA_size(rsa)); + + if (!ptbuf) + goto err; + len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); + if (len != (sizeof(tbs) - 1)) + goto err; + if (memcmp(ptbuf, tbs, len)) + goto err; + + ret = 1; + + if (!ptbuf) + goto err; + + err: + if (ret == 0) + { + fips_set_selftest_fail(); + FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED); + } + + if (ctbuf) + OPENSSL_free(ctbuf); + if (ptbuf) + OPENSSL_free(ptbuf); + + return ret; + } + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb); + +/* NB: this wrapper would normally be placed in rsa_lib.c and the static + * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so + * that we don't introduce a new linker dependency. Eg. any application that + * wasn't previously linking object code related to key-generation won't have to + * now just because key-generation is part of RSA_METHOD. */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) + { + if(rsa->meth->rsa_keygen) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); + return rsa_builtin_keygen(rsa, bits, e_value, cb); + } + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) + { + BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; + BIGNUM local_r0,local_d,local_p; + BIGNUM *pr0,*d,*p; + int bitsp,bitsq,ok= -1,n=0; + BN_CTX *ctx=NULL; + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (FIPS_mode() && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT); + return 0; + } + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + if (r3 == NULL) goto err; + + bitsp=(bits+1)/2; + bitsq=bits-bitsp; + + /* We need the RSA components non-NULL */ + if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err; + if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err; + if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err; + if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err; + if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err; + if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err; + if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; + if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err; + + BN_copy(rsa->e, e_value); + + /* generate p and q */ + for (;;) + { + if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2,rsa->p,BN_value_one())) goto err; + if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; + if (BN_is_one(r1)) break; + if(!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if(!BN_GENCB_call(cb, 3, 0)) + goto err; + for (;;) + { + /* When generating ridiculously small keys, we can get stuck + * continually regenerating the same prime values. Check for + * this and bail if it happens 3 times. */ + unsigned int degenerate = 0; + do + { + if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; + } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); + if(degenerate == 3) + { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; + if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err; + if (BN_is_one(r1)) + break; + if(!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if(!BN_GENCB_call(cb, 3, 1)) + goto err; + if (BN_cmp(rsa->p,rsa->q) < 0) + { + tmp=rsa->p; + rsa->p=rsa->q; + rsa->q=tmp; + } + + /* calculate n */ + if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err; + + /* calculate d */ + if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */ + if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */ + if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + pr0 = &local_r0; + BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); + } + else + pr0 = r0; + if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */ + + /* set up d for correct BN_FLG_CONSTTIME flag */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } + else + d = rsa->d; + + /* calculate d mod (p-1) */ + if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err; + + /* calculate d mod (q-1) */ + if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err; + + /* calculate inverse of q mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + } + else + p = rsa->p; + if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err; + + if (fips_rsa_pairwise_fail) + BN_add_word(rsa->n, 1); + + if(!fips_check_rsa(rsa)) + goto err; + + ok=1; +err: + if (ok == -1) + { + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN); + ok=0; + } + if (ctx != NULL) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ok; + } + +#endif diff --git a/fips/rsa/fips_rsa_lib.c b/fips/rsa/fips_rsa_lib.c new file mode 100644 index 0000000000..c135539f8b --- /dev/null +++ b/fips/rsa/fips_rsa_lib.c @@ -0,0 +1,100 @@ +/* fips_rsa_sign.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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). + * + */ + +#include +#include +#include +#include + +/* Minimal FIPS versions of FIPS_rsa_new() and FIPS_rsa_free: to + * reduce external dependencies. + */ + +RSA *FIPS_rsa_new(void) + { + 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; + } + +void FIPS_rsa_free(RSA *r) + { + if (!r) + return; + 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); + if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); + OPENSSL_free(r); + } + diff --git a/fips/rsa/fips_rsa_selftest.c b/fips/rsa/fips_rsa_selftest.c new file mode 100644 index 0000000000..eecfb60312 --- /dev/null +++ b/fips/rsa/fips_rsa_selftest.c @@ -0,0 +1,431 @@ +/* ==================================================================== + * Copyright (c) 2003-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +static unsigned char n[] = +"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71" +"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5" +"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD" +"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80" +"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25" +"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39" +"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68" +"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD" +"\xCB"; + + +static int setrsakey(RSA *key) + { + static const unsigned char e[] = "\x11"; + + static const unsigned char d[] = +"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD" +"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41" +"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69" +"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA" +"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94" +"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A" +"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94" +"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3" +"\xC1"; + + static const unsigned char p[] = +"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60" +"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6" +"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A" +"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65" +"\x99"; + + static const unsigned char q[] = +"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" +"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" +"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" +"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15" +"\x03"; + + static const unsigned char dmp1[] = +"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A" +"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E" +"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E" +"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81"; + + static const unsigned char dmq1[] = +"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9" +"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7" +"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D" +"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D"; + + static const unsigned char iqmp[] = +"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23" +"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11" +"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E" +"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39" +"\xF7"; + + key->n = BN_bin2bn(n, sizeof(n)-1, key->n); + key->e = BN_bin2bn(e, sizeof(e)-1, key->e); + key->d = BN_bin2bn(d, sizeof(d)-1, key->d); + key->p = BN_bin2bn(p, sizeof(p)-1, key->p); + key->q = BN_bin2bn(q, sizeof(q)-1, key->q); + key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); + key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); + key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); + return 1; + } + +void FIPS_corrupt_rsa() + { + n[0]++; + } + +/* Known Answer Test (KAT) data for the above RSA private key signing + * kat_tbs. + */ + +static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT"; + +static const unsigned char kat_RSA_PSS_SHA1[] = { + 0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F, + 0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB, + 0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3, + 0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C, + 0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7, + 0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5, + 0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45, + 0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31, + 0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8, + 0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84, + 0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9 +}; + +static const unsigned char kat_RSA_PSS_SHA224[] = { + 0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7, + 0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA, + 0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57, + 0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89, + 0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE, + 0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22, + 0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5, + 0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49, + 0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D, + 0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00, + 0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0 +}; + +static const unsigned char kat_RSA_PSS_SHA256[] = { + 0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89, + 0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F, + 0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28, + 0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E, + 0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05, + 0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA, + 0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6, + 0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F, + 0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D, + 0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6, + 0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C +}; + +static const unsigned char kat_RSA_PSS_SHA384[] = { + 0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2, + 0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E, + 0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD, + 0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F, + 0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C, + 0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB, + 0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F, + 0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89, + 0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F, + 0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55, + 0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1 +}; + +static const unsigned char kat_RSA_PSS_SHA512[] = { + 0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C, + 0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A, + 0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD, + 0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39, + 0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7, + 0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61, + 0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13, + 0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63, + 0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE, + 0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88, + 0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B +}; + +static const unsigned char kat_RSA_SHA1[] = { + 0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, + 0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, + 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF, + 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8, + 0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, + 0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, + 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E, + 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F, + 0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, + 0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, + 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4 +}; + +static const unsigned char kat_RSA_SHA224[] = { + 0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9, + 0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D, + 0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89, + 0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD, + 0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5, + 0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC, + 0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B, + 0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2, + 0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35, + 0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC, + 0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D +}; + +static const unsigned char kat_RSA_SHA256[] = { + 0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23, + 0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23, + 0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35, + 0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E, + 0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18, + 0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30, + 0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A, + 0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38, + 0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA, + 0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90, + 0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A +}; + +static const unsigned char kat_RSA_SHA384[] = { + 0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F, + 0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7, + 0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C, + 0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55, + 0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF, + 0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2, + 0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C, + 0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD, + 0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1, + 0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04, + 0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF +}; + +static const unsigned char kat_RSA_SHA512[] = { + 0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF, + 0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A, + 0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1, + 0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8, + 0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5, + 0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B, + 0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6, + 0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05, + 0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D, + 0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91, + 0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84 +}; + +static const unsigned char kat_RSA_X931_SHA1[] = { + 0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF, + 0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75, + 0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC, + 0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97, + 0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6, + 0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19, + 0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7, + 0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99, + 0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76, + 0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67, + 0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49 +}; + +static const unsigned char kat_RSA_X931_SHA256[] = { + 0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89, + 0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD, + 0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF, + 0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B, + 0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B, + 0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98, + 0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC, + 0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C, + 0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD, + 0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC, + 0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80 +}; + +static const unsigned char kat_RSA_X931_SHA384[] = { + 0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B, + 0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB, + 0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3, + 0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6, + 0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31, + 0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1, + 0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79, + 0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF, + 0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35, + 0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D, + 0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28 +}; + +static const unsigned char kat_RSA_X931_SHA512[] = { + 0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63, + 0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC, + 0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7, + 0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28, + 0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5, + 0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF, + 0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0, + 0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09, + 0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C, + 0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B, + 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3 +}; + + +int FIPS_selftest_rsa() + { + int ret = 0; + RSA *key = NULL; + EVP_PKEY pk; + key=FIPS_rsa_new(); + setrsakey(key); + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = key; + + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA1, sizeof(kat_RSA_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA1 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA224, sizeof(kat_RSA_SHA224), + EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA224 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA256, sizeof(kat_RSA_SHA256), + EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA256 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA384, sizeof(kat_RSA_SHA384), + EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA384 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA512, sizeof(kat_RSA_SHA512), + EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA512 PKCS#1")) + goto err; + + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA1 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224), + EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA224 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256), + EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA256 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384), + EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA384 PSS")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512), + EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA512 PSS")) + goto err; + + + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA1 X931")) + goto err; + /* NB: SHA224 not supported in X9.31 */ + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256), + EVP_sha256(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA256 X931")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384), + EVP_sha384(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA384 X931")) + goto err; + if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512), + EVP_sha512(), EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA512 X931")) + goto err; + + + ret = 1; + + err: + FIPS_rsa_free(key); + return ret; + } + +#endif /* def OPENSSL_FIPS */ diff --git a/fips/rsa/fips_rsa_sign.c b/fips/rsa/fips_rsa_sign.c new file mode 100644 index 0000000000..fd2d7309eb --- /dev/null +++ b/fips/rsa/fips_rsa_sign.c @@ -0,0 +1,554 @@ +/* fips_rsa_sign.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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). + * + */ + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +/* FIPS versions of RSA_sign() and RSA_verify(). + * These will only have to deal with SHA* signatures and by including + * pregenerated encodings all ASN1 dependencies can be avoided + */ + +/* Standard encodings including NULL parameter */ + +static const unsigned char sha1_bin[] = { + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14 +}; + +static const unsigned char sha224_bin[] = { + 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c +}; + +static const unsigned char sha256_bin[] = { + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 +}; + +static const unsigned char sha384_bin[] = { + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 +}; + +static const unsigned char sha512_bin[] = { + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 +}; + +/* Alternate encodings with absent parameters. We don't generate signature + * using this format but do tolerate received signatures of this form. + */ + +static unsigned char sha1_nn_bin[] = { + 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, + 0x14 +}; + +static unsigned char sha224_nn_bin[] = { + 0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x04, 0x1c +}; + +static unsigned char sha256_nn_bin[] = { + 0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x04, 0x20 +}; + +static unsigned char sha384_nn_bin[] = { + 0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x04, 0x30 +}; + +static unsigned char sha512_nn_bin[] = { + 0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x04, 0x40 +}; + + +static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len) + { + switch (nid) + { + + case NID_sha1: + *len = sizeof(sha1_bin); + return sha1_bin; + + case NID_sha224: + *len = sizeof(sha224_bin); + return sha224_bin; + + case NID_sha256: + *len = sizeof(sha256_bin); + return sha256_bin; + + case NID_sha384: + *len = sizeof(sha384_bin); + return sha384_bin; + + case NID_sha512: + *len = sizeof(sha512_bin); + return sha512_bin; + + default: + return NULL; + + } + } + +static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len) + { + switch (nid) + { + + case NID_sha1: + *len = sizeof(sha1_nn_bin); + return sha1_nn_bin; + + case NID_sha224: + *len = sizeof(sha224_nn_bin); + return sha224_nn_bin; + + case NID_sha256: + *len = sizeof(sha256_nn_bin); + return sha256_nn_bin; + + case NID_sha384: + *len = sizeof(sha384_nn_bin); + return sha384_nn_bin; + + case NID_sha512: + *len = sizeof(sha512_nn_bin); + return sha512_nn_bin; + + default: + return NULL; + + } + } + +static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y, + unsigned char *sigret, unsigned int *siglen, EVP_MD_SVCTX *sv) + { + int i=0,j,ret=0; + unsigned int dlen; + const unsigned char *der; + unsigned int m_len; + int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK; + int rsa_pad_mode = 0; + RSA *rsa = sv->key; + /* Largest DigestInfo: 19 (max encoding) + max MD */ + unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE]; + unsigned char md[EVP_MAX_MD_SIZE + 1]; + + EVP_DigestFinal_ex(sv->mctx, md, &m_len); + + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) + { + ret = rsa->meth->rsa_sign(type, md, m_len, + sigret, siglen, rsa); + goto done; + } + + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) + { + int hash_id; + memcpy(tmpdinfo, md, m_len); + hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx)); + if (hash_id == -1) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + tmpdinfo[m_len] = (unsigned char)hash_id; + i = m_len + 1; + rsa_pad_mode = RSA_X931_PADDING; + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + { + + der = fips_digestinfo_encoding(type, &dlen); + + if (!der) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + memcpy(tmpdinfo, der, dlen); + memcpy(tmpdinfo + dlen, md, m_len); + + i = dlen + m_len; + rsa_pad_mode = RSA_PKCS1_PADDING; + + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) + { + unsigned char *sbuf; + int saltlen; + i = RSA_size(rsa); + sbuf = OPENSSL_malloc(RSA_size(rsa)); + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (!sbuf) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE); + goto psserr; + } + if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md, + M_EVP_MD_CTX_md(sv->mctx), saltlen)) + goto psserr; + j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING); + if (j > 0) + { + ret=1; + *siglen=j; + } + psserr: + OPENSSL_cleanse(md,m_len); + OPENSSL_cleanse(sbuf, i); + OPENSSL_free(sbuf); + return ret; + } + + j=RSA_size(rsa); + if (i > (j-RSA_PKCS1_PADDING_SIZE)) + { + RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + goto done; + } + /* NB: call underlying method directly to avoid FIPS blocking */ + j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode); + if (j > 0) + { + ret=1; + *siglen=j; + } + + done: + OPENSSL_cleanse(tmpdinfo,i); + OPENSSL_cleanse(md,m_len); + return ret; + } + +static int fips_rsa_verify(int dtype, + const unsigned char *x, unsigned int y, + unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv) + { + int i,ret=0; + unsigned int dlen, diglen; + int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK; + int rsa_pad_mode = 0; + unsigned char *s; + const unsigned char *der; + unsigned char dig[EVP_MAX_MD_SIZE]; + RSA *rsa = sv->key; + + if (siglen != (unsigned int)RSA_size(sv->key)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); + return(0); + } + + EVP_DigestFinal_ex(sv->mctx, dig, &diglen); + + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + { + return rsa->meth->rsa_verify(dtype, dig, diglen, + sigbuf, siglen, rsa); + } + + + s= OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE); + goto err; + } + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) + rsa_pad_mode = RSA_X931_PADDING; + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + rsa_pad_mode = RSA_PKCS1_PADDING; + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) + rsa_pad_mode = RSA_NO_PADDING; + + /* NB: call underlying method directly to avoid FIPS blocking */ + i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_pad_mode); + + if (i <= 0) goto err; + + if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) + { + int hash_id; + if (i != (int)(diglen + 1)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx)); + if (hash_id == -1) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE); + goto err; + } + if (s[diglen] != (unsigned char)hash_id) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + if (memcmp(s, dig, diglen)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + ret = 1; + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) + { + + der = fips_digestinfo_encoding(dtype, &dlen); + + if (!der) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE); + return(0); + } + + /* Compare, DigestInfo length, DigestInfo header and finally + * digest value itself + */ + + /* If length mismatch try alternate encoding */ + if (i != (int)(dlen + diglen)) + der = fips_digestinfo_nn_encoding(dtype, &dlen); + + if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen) + || memcmp(s + dlen, dig, diglen)) + { + RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE); + goto err; + } + ret = 1; + + } + else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) + { + int saltlen; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx), + s, saltlen); + if (ret < 0) + ret = 0; + } +err: + if (s != NULL) + { + OPENSSL_cleanse(s, siglen); + OPENSSL_free(s); + } + return(ret); + } + +#define EVP_PKEY_RSA_fips_method \ + (evp_sign_method *)fips_rsa_sign, \ + (evp_verify_method *)fips_rsa_verify, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} + +static int init(EVP_MD_CTX *ctx) + { return SHA1_Init(ctx->md_data); } + +static int update(EVP_MD_CTX *ctx,const void *data,size_t count) + { return SHA1_Update(ctx->md_data,data,count); } + +static int final(EVP_MD_CTX *ctx,unsigned char *md) + { return SHA1_Final(md,ctx->md_data); } + +static const EVP_MD sha1_md= + { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA_CTX), + }; + +const EVP_MD *EVP_sha1(void) + { + return(&sha1_md); + } + +static int init224(EVP_MD_CTX *ctx) + { return SHA224_Init(ctx->md_data); } +static int init256(EVP_MD_CTX *ctx) + { return SHA256_Init(ctx->md_data); } +/* + * Even though there're separate SHA224_[Update|Final], we call + * SHA256 functions even in SHA224 context. This is what happens + * there anyway, so we can spare few CPU cycles:-) + */ +static int update256(EVP_MD_CTX *ctx,const void *data,size_t count) + { return SHA256_Update(ctx->md_data,data,count); } +static int final256(EVP_MD_CTX *ctx,unsigned char *md) + { return SHA256_Final(md,ctx->md_data); } + +static const EVP_MD sha224_md= + { + NID_sha224, + NID_sha224WithRSAEncryption, + SHA224_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init224, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA256_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA256_CTX), + }; + +const EVP_MD *EVP_sha224(void) + { return(&sha224_md); } + +static const EVP_MD sha256_md= + { + NID_sha256, + NID_sha256WithRSAEncryption, + SHA256_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init256, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA256_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA256_CTX), + }; + +const EVP_MD *EVP_sha256(void) + { return(&sha256_md); } + +static int init384(EVP_MD_CTX *ctx) + { return SHA384_Init(ctx->md_data); } +static int init512(EVP_MD_CTX *ctx) + { return SHA512_Init(ctx->md_data); } +/* See comment in SHA224/256 section */ +static int update512(EVP_MD_CTX *ctx,const void *data,size_t count) + { return SHA512_Update(ctx->md_data,data,count); } +static int final512(EVP_MD_CTX *ctx,unsigned char *md) + { return SHA512_Final(md,ctx->md_data); } + +static const EVP_MD sha384_md= + { + NID_sha384, + NID_sha384WithRSAEncryption, + SHA384_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init384, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA512_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA512_CTX), + }; + +const EVP_MD *EVP_sha384(void) + { return(&sha384_md); } + +static const EVP_MD sha512_md= + { + NID_sha512, + NID_sha512WithRSAEncryption, + SHA512_DIGEST_LENGTH, + EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX, + init512, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_fips_method, + SHA512_CBLOCK, + sizeof(EVP_MD *)+sizeof(SHA512_CTX), + }; + +const EVP_MD *EVP_sha512(void) + { return(&sha512_md); } + +#endif diff --git a/fips/rsa/fips_rsa_x931g.c b/fips/rsa/fips_rsa_x931g.c new file mode 100644 index 0000000000..d9f9a81235 --- /dev/null +++ b/fips/rsa/fips_rsa_x931g.c @@ -0,0 +1,280 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS + +extern int fips_check_rsa(RSA *rsa); + + +/* X9.31 RSA key derivation and generation */ + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2, + const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp, + const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb) + { + BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL; + BN_CTX *ctx=NULL,*ctx2=NULL; + + if (!rsa) + goto err; + + ctx = BN_CTX_new(); + BN_CTX_start(ctx); + if (!ctx) + goto err; + + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + + if (r3 == NULL) + goto err; + if (!rsa->e) + { + rsa->e = BN_dup(e); + if (!rsa->e) + goto err; + } + else + e = rsa->e; + + /* If not all parameters present only calculate what we can. + * This allows test programs to output selective parameters. + */ + + if (Xp && !rsa->p) + { + rsa->p = BN_new(); + if (!rsa->p) + goto err; + + if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, + Xp, Xp1, Xp2, e, ctx, cb)) + goto err; + } + + if (Xq && !rsa->q) + { + rsa->q = BN_new(); + if (!rsa->q) + goto err; + if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, + Xq, Xq1, Xq2, e, ctx, cb)) + goto err; + } + + if (!rsa->p || !rsa->q) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 2; + } + + /* Since both primes are set we can now calculate all remaining + * components. + */ + + /* calculate n */ + rsa->n=BN_new(); + if (rsa->n == NULL) + goto err; + if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1,rsa->p,BN_value_one())) + goto err; /* p-1 */ + if (!BN_sub(r2,rsa->q,BN_value_one())) + goto err; /* q-1 */ + if (!BN_mul(r0,r1,r2,ctx)) + goto err; /* (p-1)(q-1) */ + + if (!BN_gcd(r3, r1, r2, ctx)) + goto err; + + if (!BN_div(r0, NULL, r0, r3, ctx)) + goto err; /* LCM((p-1)(q-1)) */ + + ctx2 = BN_CTX_new(); + if (!ctx2) + goto err; + + rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */ + if (rsa->d == NULL) + goto err; + + /* calculate d mod (p-1) */ + rsa->dmp1=BN_new(); + if (rsa->dmp1 == NULL) + goto err; + if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) + goto err; + + /* calculate d mod (q-1) */ + rsa->dmq1=BN_new(); + if (rsa->dmq1 == NULL) + goto err; + if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) + goto err; + + /* calculate inverse of q mod p */ + rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2); + + err: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (ctx2) + BN_CTX_free(ctx2); + /* If this is set all calls successful */ + if (rsa->iqmp != NULL) + return 1; + + return 0; + + } + +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb) + { + int ok = 0; + BIGNUM *Xp = NULL, *Xq = NULL; + BN_CTX *ctx = NULL; + + if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT); + return 0; + } + + if (bits & 0xff) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_INVALID_KEY_LENGTH); + return 0; + } + + if(FIPS_selftest_failed()) + { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + ctx = BN_CTX_new(); + if (!ctx) + goto error; + + BN_CTX_start(ctx); + Xp = BN_CTX_get(ctx); + Xq = BN_CTX_get(ctx); + if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) + goto error; + + rsa->p = BN_new(); + rsa->q = BN_new(); + if (!rsa->p || !rsa->q) + goto error; + + /* Generate two primes from Xp, Xq */ + + if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, + e, ctx, cb)) + goto error; + + if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, + e, ctx, cb)) + goto error; + + /* Since rsa->p and rsa->q are valid this call will just derive + * remaining RSA components. + */ + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) + goto error; + + if(!fips_check_rsa(rsa)) + goto error; + + ok = 1; + + error: + if (ctx) + { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (ok) + return 1; + + return 0; + + } + +#endif diff --git a/fips/rsa/fips_rsagtest.c b/fips/rsa/fips_rsagtest.c new file mode 100644 index 0000000000..0ae2a29335 --- /dev/null +++ b/fips/rsa/fips_rsagtest.c @@ -0,0 +1,388 @@ +/* fips_rsagtest.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005,2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in); +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e); +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_test(out, in)) + { + fprintf(stderr, "FATAL RSAGTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_test(FILE *out, FILE *in) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL; + BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL; + BIGNUM *e = NULL; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [foo = bar] line) just copy */ + if (!p || *keyword=='[') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword, "xp1")) + { + if (Xp1 || !do_hex2bn(&Xp1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xp2")) + { + if (Xp2 || !do_hex2bn(&Xp2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xp")) + { + if (Xp || !do_hex2bn(&Xp,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq1")) + { + if (Xq1 || !do_hex2bn(&Xq1,value)) + goto parse_error; + } + else if (!strcmp(keyword, "xq2")) + { + if (Xq2 || !do_hex2bn(&Xq2,value)) + goto parse_error; + } + else if (!strcmp(keyword, "Xq")) + { + if (Xq || !do_hex2bn(&Xq,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (e || !do_hex2bn(&e,value)) + goto parse_error; + } + else if (!strcmp(keyword, "p1")) + continue; + else if (!strcmp(keyword, "p2")) + continue; + else if (!strcmp(keyword, "p")) + continue; + else if (!strcmp(keyword, "q1")) + continue; + else if (!strcmp(keyword, "q2")) + continue; + else if (!strcmp(keyword, "q")) + continue; + else if (!strcmp(keyword, "n")) + continue; + else if (!strcmp(keyword, "d")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (e && Xp1 && Xp2 && Xp) + { + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e)) + goto error; + BN_free(Xp1); + Xp1 = NULL; + BN_free(Xp2); + Xp2 = NULL; + BN_free(Xp); + Xp = NULL; + BN_free(e); + e = NULL; + } + + if (rsa && Xq1 && Xq2 && Xq) + { + if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq)) + goto error; + BN_free(Xq1); + Xq1 = NULL; + BN_free(Xq2); + Xq2 = NULL; + BN_free(Xq); + Xq = NULL; + FIPS_rsa_free(rsa); + rsa = NULL; + } + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + + if (Xp1) + BN_free(Xp1); + if (Xp2) + BN_free(Xp2); + if (Xp) + BN_free(Xp); + if (Xq1) + BN_free(Xq1); + if (Xq1) + BN_free(Xq1); + if (Xq2) + BN_free(Xq2); + if (Xq) + BN_free(Xq); + if (e) + BN_free(e); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printkey1(FILE *out, RSA *rsa, + BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, + BIGNUM *e) + { + int ret = 0; + BIGNUM *p1 = NULL, *p2 = NULL; + p1 = BN_new(); + p2 = BN_new(); + if (!p1 || !p2) + goto error; + + if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp, + NULL, NULL, NULL, e, NULL)) + goto error; + + do_bn_print_name(out, "p1", p1); + do_bn_print_name(out, "p2", p2); + do_bn_print_name(out, "p", rsa->p); + + ret = 1; + + error: + if (p1) + BN_free(p1); + if (p2) + BN_free(p2); + + return ret; + } + +static int rsa_printkey2(FILE *out, RSA *rsa, + BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq) + { + int ret = 0; + BIGNUM *q1 = NULL, *q2 = NULL; + q1 = BN_new(); + q2 = BN_new(); + if (!q1 || !q2) + goto error; + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL, + Xq1, Xq2, Xq, NULL, NULL)) + goto error; + + do_bn_print_name(out, "q1", q1); + do_bn_print_name(out, "q2", q2); + do_bn_print_name(out, "q", rsa->q); + do_bn_print_name(out, "n", rsa->n); + do_bn_print_name(out, "d", rsa->d); + + ret = 1; + + error: + if (q1) + BN_free(q1); + if (q2) + BN_free(q2); + + return ret; + } + +#endif diff --git a/fips/rsa/fips_rsastest.c b/fips/rsa/fips_rsastest.c new file mode 100644 index 0000000000..cca1a27cc9 --- /dev/null +++ b/fips/rsa/fips_rsastest.c @@ -0,0 +1,368 @@ +/* fips_rsastest.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +static int rsa_stest(FILE *out, FILE *in, int Saltlen); +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1, Saltlen = -1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if ((argc > 2) && !strcmp("-saltlen", argv[1])) + { + Saltlen = atoi(argv[2]); + if (Saltlen < 0) + { + fprintf(stderr, "FATAL: Invalid salt length\n"); + goto end; + } + argc -= 2; + argv += 2; + } + else if ((argc > 1) && !strcmp("-x931", argv[1])) + { + Saltlen = -2; + argc--; + argv++; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_stest(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSASTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_stest(FILE *out, FILE *in, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + RSA *rsa = NULL; + const EVP_MD *dgst = NULL; + unsigned char *Msg = NULL; + long Msglen = -1; + int keylen = -1, current_keylen = -1; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = just copy */ + if (!p) + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + /* Look for [mod = XXX] for key length */ + + if (!strcmp(keyword, "[mod")) + { + p = value + strlen(value) - 1; + if (*p != ']') + goto parse_error; + *p = 0; + keylen = atoi(value); + if (keylen < 0) + goto parse_error; + } + else if (!strcmp(keyword, "SHAAlg")) + { + if (!strcmp(value, "SHA1")) + dgst = EVP_sha1(); + else if (!strcmp(value, "SHA224")) + dgst = EVP_sha224(); + else if (!strcmp(value, "SHA256")) + dgst = EVP_sha256(); + else if (!strcmp(value, "SHA384")) + dgst = EVP_sha384(); + else if (!strcmp(value, "SHA512")) + dgst = EVP_sha512(); + else + { + fprintf(stderr, + "FATAL: unsupported algorithm \"%s\"\n", + value); + goto parse_error; + } + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + + fputs(olinebuf, out); + + /* If key length has changed, generate and output public + * key components of new RSA private key. + */ + + if (keylen != current_keylen) + { + BIGNUM *bn_e; + if (rsa) + FIPS_rsa_free(rsa); + rsa = FIPS_rsa_new(); + if (!rsa) + goto error; + bn_e = BN_new(); + if (!bn_e || !BN_set_word(bn_e, 0x1001)) + goto error; + if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL)) + goto error; + BN_free(bn_e); + fputs("n = ", out); + do_bn_print(out, rsa->n); + fputs("\ne = ", out); + do_bn_print(out, rsa->e); + fputs("\n", out); + current_keylen = keylen; + } + + if (Msg && dgst) + { + if (!rsa_printsig(out, rsa, dgst, Msg, Msglen, + Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + } + + } + + ret = 1; + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (rsa) + FIPS_rsa_free(rsa); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, + unsigned char *Msg, long Msglen, int Saltlen) + { + int ret = 0; + unsigned char *sigbuf = NULL; + int i, siglen; + /* EVP_PKEY structure */ + EVP_PKEY pk; + EVP_MD_CTX ctx; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa; + + siglen = RSA_size(rsa); + sigbuf = OPENSSL_malloc(siglen); + if (!sigbuf) + goto error; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_SignInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_SignUpdate(&ctx, Msg, Msglen)) + goto error; + if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) + goto error; + + EVP_MD_CTX_cleanup(&ctx); + + fputs("S = ", out); + + for (i = 0; i < siglen; i++) + fprintf(out, "%02X", sigbuf[i]); + + fputs("\n", out); + + ret = 1; + + error: + + return ret; + } +#endif diff --git a/fips/rsa/fips_rsavtest.c b/fips/rsa/fips_rsavtest.c new file mode 100644 index 0000000000..13dc09a03f --- /dev/null +++ b/fips/rsa/fips_rsavtest.c @@ -0,0 +1,375 @@ +/* fips_rsavtest.c */ +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL + * project 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS RSA support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +int rsa_test(FILE *out, FILE *in, int saltlen); +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + int Saltlen = -1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if ((argc > 2) && !strcmp("-saltlen", argv[1])) + { + Saltlen = atoi(argv[2]); + if (Saltlen < 0) + { + fprintf(stderr, "FATAL: Invalid salt length\n"); + goto end; + } + argc -= 2; + argv += 2; + } + else if ((argc > 1) && !strcmp("-x931", argv[1])) + { + Saltlen = -2; + argc--; + argv++; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!rsa_test(out, in, Saltlen)) + { + fprintf(stderr, "FATAL RSAVTEST file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define RSA_TEST_MAXLINELEN 10240 + +int rsa_test(FILE *out, FILE *in, int Saltlen) + { + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + const EVP_MD *dgst = NULL; + BIGNUM *n = NULL, *e = NULL; + unsigned char *Msg = NULL, *S = NULL; + long Msglen, Slen; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [foo = bar] line) just copy */ + if (!p || *keyword=='[') + { + if (fputs(olinebuf, out) < 0) + goto error; + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword, "n")) + { + if (!do_hex2bn(&n,value)) + goto parse_error; + } + else if (!strcmp(keyword, "e")) + { + if (!do_hex2bn(&e,value)) + goto parse_error; + } + else if (!strcmp(keyword, "SHAAlg")) + { + if (!strcmp(value, "SHA1")) + dgst = EVP_sha1(); + else if (!strcmp(value, "SHA224")) + dgst = EVP_sha224(); + else if (!strcmp(value, "SHA256")) + dgst = EVP_sha256(); + else if (!strcmp(value, "SHA384")) + dgst = EVP_sha384(); + else if (!strcmp(value, "SHA512")) + dgst = EVP_sha512(); + else + { + fprintf(stderr, + "FATAL: unsupported algorithm \"%s\"\n", + value); + goto parse_error; + } + } + else if (!strcmp(keyword, "Msg")) + { + if (Msg) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + Msg = hex2bin_m(value, &Msglen); + if (!Msg) + goto parse_error; + } + else if (!strcmp(keyword, "S")) + { + if (S) + goto parse_error; + if (strlen(value) & 1) + *(--value) = '0'; + S = hex2bin_m(value, &Slen); + if (!S) + goto parse_error; + } + else if (!strcmp(keyword, "Result")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (n && e && Msg && S && dgst) + { + if (!rsa_printver(out, n, e, dgst, + Msg, Msglen, S, Slen, Saltlen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + OPENSSL_free(S); + S = NULL; + } + + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (n) + BN_free(n); + if (e) + BN_free(e); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int rsa_printver(FILE *out, + BIGNUM *n, BIGNUM *e, + const EVP_MD *dgst, + unsigned char *Msg, long Msglen, + unsigned char *S, long Slen, int Saltlen) + { + int ret = 0, r; + /* Setup RSA and EVP_PKEY structures */ + RSA *rsa_pubkey = NULL; + EVP_PKEY pk; + EVP_MD_CTX ctx; + unsigned char *buf = NULL; + rsa_pubkey = FIPS_rsa_new(); + if (!rsa_pubkey) + goto error; + rsa_pubkey->n = BN_dup(n); + rsa_pubkey->e = BN_dup(e); + if (!rsa_pubkey->n || !rsa_pubkey->e) + goto error; + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = rsa_pubkey; + + EVP_MD_CTX_init(&ctx); + + if (Saltlen >= 0) + { + M_EVP_MD_CTX_set_flags(&ctx, + EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); + } + else if (Saltlen == -2) + M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); + if (!EVP_VerifyInit_ex(&ctx, dgst, NULL)) + goto error; + if (!EVP_VerifyUpdate(&ctx, Msg, Msglen)) + goto error; + + r = EVP_VerifyFinal(&ctx, S, Slen, &pk); + + + EVP_MD_CTX_cleanup(&ctx); + + if (r < 0) + goto error; + ERR_clear_error(); + + if (r == 0) + fputs("Result = F\n", out); + else + fputs("Result = P\n", out); + + ret = 1; + + error: + if (rsa_pubkey) + FIPS_rsa_free(rsa_pubkey); + if (buf) + OPENSSL_free(buf); + + return ret; + } +#endif diff --git a/fips/sha/.cvsignore b/fips/sha/.cvsignore new file mode 100644 index 0000000000..78ace06571 --- /dev/null +++ b/fips/sha/.cvsignore @@ -0,0 +1,5 @@ +fips_standalone_sha1 +lib +Makefile.save +*.flc +semantic.cache diff --git a/fips/sha/Makefile b/fips/sha/Makefile new file mode 100644 index 0000000000..ba8eb02baf --- /dev/null +++ b/fips/sha/Makefile @@ -0,0 +1,160 @@ +# +# OpenSSL/fips/sha/Makefile +# + +DIR= sha +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile +AR= ar r +EXE_EXT= + +ASFLAGS= $(INCLUDES) $(ASFLAG) +AFLAGS= $(ASFLAGS) + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST= fips_shatest.c +TESTDATA= SHAmix.req SHAmix.fax +APPS= +EXE= fips_standalone_sha1$(EXE_EXT) + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_sha1_selftest.c +LIBOBJ=fips_sha1_selftest.o + +SRC= $(LIBSRC) fips_standalone_sha1.c + +EXHEADER= +HEADER= + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all) + +all: ../fips_standalone_sha1$(EXE_EXT) lib + +lib: $(LIBOBJ) + @echo $(LIBOBJ) > lib + +../fips_standalone_sha1$(EXE_EXT): fips_standalone_sha1.o + FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha1dgst.o ; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../../crypto/sha/$$i" ; done; \ + $(CC) -o $@ $(CFLAGS) fips_standalone_sha1.o $$FIPS_SHA_ASM + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST) + cp $(TESTDATA) $(TOP)/test + @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS) + +install: + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done + +tags: + ctags $(SRC) + +tests: + +Q=../testvectors/sha/req +A=../testvectors/sha/rsp + +VECTORS = SHA1LongMsg \ + SHA1Monte \ + SHA1ShortMsg \ + SHA224LongMsg \ + SHA224Monte \ + SHA224ShortMsg \ + SHA256LongMsg \ + SHA256Monte \ + SHA256ShortMsg \ + SHA384LongMsg \ + SHA384Monte \ + SHA384ShortMsg \ + SHA512LongMsg \ + SHA512Monte \ + SHA512ShortMsg + +fips_test: + -rm -rf $(A) + mkdir $(A) + for file in $(VECTORS); do \ + if [ -f $(Q)/$$file.req ]; then \ + $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_shatest $(Q)/$$file.req $(A)/$$file.rsp; \ + fi; \ + done + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff $(EXE) + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips_sha1_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_sha1_selftest.o: ../../include/openssl/crypto.h +fips_sha1_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_sha1_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_sha1_selftest.o: ../../include/openssl/lhash.h +fips_sha1_selftest.o: ../../include/openssl/obj_mac.h +fips_sha1_selftest.o: ../../include/openssl/objects.h +fips_sha1_selftest.o: ../../include/openssl/opensslconf.h +fips_sha1_selftest.o: ../../include/openssl/opensslv.h +fips_sha1_selftest.o: ../../include/openssl/ossl_typ.h +fips_sha1_selftest.o: ../../include/openssl/safestack.h +fips_sha1_selftest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +fips_sha1_selftest.o: ../../include/openssl/symhacks.h fips_sha1_selftest.c +fips_shatest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_shatest.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +fips_shatest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_shatest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +fips_shatest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +fips_shatest.o: ../../include/openssl/evp.h ../../include/openssl/fips.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 ../../include/openssl/pkcs7.h +fips_shatest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +fips_shatest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_shatest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +fips_shatest.o: ../../include/openssl/x509v3.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 diff --git a/fips/sha/fips_sha1_selftest.c b/fips/sha/fips_sha1_selftest.c new file mode 100644 index 0000000000..ba6a29ed94 --- /dev/null +++ b/fips/sha/fips_sha1_selftest.c @@ -0,0 +1,97 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_FIPS +static char test[][60]= + { + "", + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + }; + +static const unsigned char ret[][SHA_DIGEST_LENGTH]= + { + { 0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55, + 0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09 }, + { 0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e, + 0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d }, + { 0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae, + 0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1 }, + }; + +void FIPS_corrupt_sha1() + { + test[2][0]++; + } + +int FIPS_selftest_sha1() + { + int n; + + for(n=0 ; n +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_FIPS + +int main(int argc, char *argv[]) +{ + printf("No FIPS SHAXXX support\n"); + return(0); +} + +#else + +#include "fips_utl.h" + +static int dgst_test(FILE *out, FILE *in); +static int print_dgst(const EVP_MD *md, FILE *out, + unsigned char *Msg, int Msglen); +static int print_monte(const EVP_MD *md, FILE *out, + unsigned char *Seed, int SeedLen); + +int main(int argc, char **argv) + { + FILE *in = NULL, *out = NULL; + + int ret = 1; + + if(!FIPS_mode_set(1)) + { + do_print_errors(); + goto end; + } + + if (argc == 1) + in = stdin; + else + in = fopen(argv[1], "r"); + + if (argc < 2) + out = stdout; + else + out = fopen(argv[2], "w"); + + if (!in) + { + fprintf(stderr, "FATAL input initialization error\n"); + goto end; + } + + if (!out) + { + fprintf(stderr, "FATAL output initialization error\n"); + goto end; + } + + if (!dgst_test(out, in)) + { + fprintf(stderr, "FATAL digest file processing error\n"); + goto end; + } + else + ret = 0; + + end: + + if (ret) + do_print_errors(); + + if (in && (in != stdin)) + fclose(in); + if (out && (out != stdout)) + fclose(out); + + return ret; + + } + +#define SHA_TEST_MAX_BITS 102400 +#define SHA_TEST_MAXLINELEN (((SHA_TEST_MAX_BITS >> 3) * 2) + 100) + +int dgst_test(FILE *out, FILE *in) + { + const EVP_MD *md = NULL; + char *linebuf, *olinebuf, *p, *q; + char *keyword, *value; + unsigned char *Msg = NULL, *Seed = NULL; + long MsgLen = -1, Len = -1, SeedLen = -1; + int ret = 0; + int lnum = 0; + + olinebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); + linebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); + + if (!linebuf || !olinebuf) + goto error; + + + while (fgets(olinebuf, SHA_TEST_MAXLINELEN, in)) + { + lnum++; + strcpy(linebuf, olinebuf); + keyword = linebuf; + /* Skip leading space */ + while (isspace((unsigned char)*keyword)) + keyword++; + + /* Look for = sign */ + p = strchr(linebuf, '='); + + /* If no = or starts with [ (for [L=20] line) just copy */ + if (!p) + { + fputs(olinebuf, out); + continue; + } + + q = p - 1; + + /* Remove trailing space */ + while (isspace((unsigned char)*q)) + *q-- = 0; + + *p = 0; + value = p + 1; + + /* Remove leading space from value */ + while (isspace((unsigned char)*value)) + value++; + + /* Remove trailing space from value */ + p = value + strlen(value) - 1; + while (*p == '\n' || isspace((unsigned char)*p)) + *p-- = 0; + + if (!strcmp(keyword,"[L") && *p==']') + { + switch (atoi(value)) + { + case 20: md=EVP_sha1(); break; + case 28: md=EVP_sha224(); break; + case 32: md=EVP_sha256(); break; + case 48: md=EVP_sha384(); break; + case 64: md=EVP_sha512(); break; + default: goto parse_error; + } + } + else if (!strcmp(keyword, "Len")) + { + if (Len != -1) + goto parse_error; + Len = atoi(value); + if (Len < 0) + goto parse_error; + /* Only handle multiples of 8 bits */ + if (Len & 0x7) + goto parse_error; + if (Len > SHA_TEST_MAX_BITS) + goto parse_error; + MsgLen = Len >> 3; + } + + else if (!strcmp(keyword, "Msg")) + { + long tmplen; + if (strlen(value) & 1) + *(--value) = '0'; + if (Msg) + goto parse_error; + Msg = hex2bin_m(value, &tmplen); + if (!Msg) + goto parse_error; + } + else if (!strcmp(keyword, "Seed")) + { + if (strlen(value) & 1) + *(--value) = '0'; + if (Seed) + goto parse_error; + Seed = hex2bin_m(value, &SeedLen); + if (!Seed) + goto parse_error; + } + else if (!strcmp(keyword, "MD")) + continue; + else + goto parse_error; + + fputs(olinebuf, out); + + if (md && Msg && (MsgLen >= 0)) + { + if (!print_dgst(md, out, Msg, MsgLen)) + goto error; + OPENSSL_free(Msg); + Msg = NULL; + MsgLen = -1; + Len = -1; + } + else if (md && Seed && (SeedLen > 0)) + { + if (!print_monte(md, out, Seed, SeedLen)) + goto error; + OPENSSL_free(Seed); + Seed = NULL; + SeedLen = -1; + } + + + } + + + ret = 1; + + + error: + + if (olinebuf) + OPENSSL_free(olinebuf); + if (linebuf) + OPENSSL_free(linebuf); + if (Msg) + OPENSSL_free(Msg); + if (Seed) + OPENSSL_free(Seed); + + return ret; + + parse_error: + + fprintf(stderr, "FATAL parse error processing line %d\n", lnum); + + goto error; + + } + +static int print_dgst(const EVP_MD *emd, FILE *out, + unsigned char *Msg, int Msglen) + { + int i, mdlen; + unsigned char md[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(Msg, Msglen, md, (unsigned int *)&mdlen, emd, NULL)) + { + fputs("Error calculating HASH\n", stderr); + return 0; + } + fputs("MD = ", out); + for (i = 0; i < mdlen; i++) + fprintf(out, "%02x", md[i]); + fputs("\n", out); + return 1; + } + +static int print_monte(const EVP_MD *md, FILE *out, + unsigned char *Seed, int SeedLen) + { + unsigned int i, j, k; + int ret = 0; + EVP_MD_CTX ctx; + unsigned char *m1, *m2, *m3, *p; + unsigned int mlen, m1len, m2len, m3len; + + EVP_MD_CTX_init(&ctx); + + if (SeedLen > EVP_MAX_MD_SIZE) + mlen = SeedLen; + else + mlen = EVP_MAX_MD_SIZE; + + m1 = OPENSSL_malloc(mlen); + m2 = OPENSSL_malloc(mlen); + m3 = OPENSSL_malloc(mlen); + + if (!m1 || !m2 || !m3) + goto mc_error; + + m1len = m2len = m3len = SeedLen; + memcpy(m1, Seed, SeedLen); + memcpy(m2, Seed, SeedLen); + memcpy(m3, Seed, SeedLen); + + fputs("\n", out); + + for (j = 0; j < 100; j++) + { + for (i = 0; i < 1000; i++) + { + EVP_DigestInit_ex(&ctx, md, NULL); + EVP_DigestUpdate(&ctx, m1, m1len); + EVP_DigestUpdate(&ctx, m2, m2len); + EVP_DigestUpdate(&ctx, m3, m3len); + p = m1; + m1 = m2; + m1len = m2len; + m2 = m3; + m2len = m3len; + m3 = p; + EVP_DigestFinal_ex(&ctx, m3, &m3len); + } + fprintf(out, "COUNT = %d\n", j); + fputs("MD = ", out); + for (k = 0; k < m3len; k++) + fprintf(out, "%02x", m3[k]); + fputs("\n\n", out); + memcpy(m1, m3, m3len); + memcpy(m2, m3, m3len); + m1len = m2len = m3len; + } + + ret = 1; + + mc_error: + if (m1) + OPENSSL_free(m1); + if (m2) + OPENSSL_free(m2); + if (m3) + OPENSSL_free(m3); + + EVP_MD_CTX_cleanup(&ctx); + + return ret; + } + +#endif diff --git a/fips/sha/fips_standalone_sha1.c b/fips/sha/fips_standalone_sha1.c new file mode 100644 index 0000000000..058b71a20f --- /dev/null +++ b/fips/sha/fips_standalone_sha1.c @@ -0,0 +1,173 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include + +#ifndef FIPSCANISTER_O +int FIPS_selftest_failed() { return 0; } +void FIPS_selftest_check() {} +void OPENSSL_cleanse(void *p,size_t len) {} +#endif + +#ifdef OPENSSL_FIPS + +static void hmac_init(SHA_CTX *md_ctx,SHA_CTX *o_ctx, + const char *key) + { + int len=strlen(key); + int i; + unsigned char keymd[HMAC_MAX_MD_CBLOCK]; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + + if (len > SHA_CBLOCK) + { + SHA1_Init(md_ctx); + SHA1_Update(md_ctx,key,len); + SHA1_Final(keymd,md_ctx); + len=20; + } + else + memcpy(keymd,key,len); + memset(&keymd[len],'\0',HMAC_MAX_MD_CBLOCK-len); + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x36^keymd[i]; + SHA1_Init(md_ctx); + SHA1_Update(md_ctx,pad,SHA_CBLOCK); + + for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++) + pad[i]=0x5c^keymd[i]; + SHA1_Init(o_ctx); + SHA1_Update(o_ctx,pad,SHA_CBLOCK); + } + +static void hmac_final(unsigned char *md,SHA_CTX *md_ctx,SHA_CTX *o_ctx) + { + unsigned char buf[20]; + + SHA1_Final(buf,md_ctx); + SHA1_Update(o_ctx,buf,sizeof buf); + SHA1_Final(md,o_ctx); + } + +#endif + +int main(int argc,char **argv) + { +#ifdef OPENSSL_FIPS + static char key[]="etaonrishdlcupfm"; + int n,binary=0; + + if(argc < 2) + { + fprintf(stderr,"%s []+\n",argv[0]); + exit(1); + } + + n=1; + if (!strcmp(argv[n],"-binary")) + { + n++; + binary=1; /* emit binary fingerprint... */ + } + + for(; n < argc ; ++n) + { + FILE *f=fopen(argv[n],"rb"); + SHA_CTX md_ctx,o_ctx; + unsigned char md[20]; + int i; + + if(!f) + { + perror(argv[n]); + exit(2); + } + + hmac_init(&md_ctx,&o_ctx,key); + for( ; ; ) + { + char buf[1024]; + int l=fread(buf,1,sizeof buf,f); + + if(l == 0) + { + if(ferror(f)) + { + perror(argv[n]); + exit(3); + } + else + break; + } + SHA1_Update(&md_ctx,buf,l); + } + hmac_final(md,&md_ctx,&o_ctx); + + if (binary) + { + fwrite(md,20,1,stdout); + break; /* ... for single(!) file */ + } + + printf("HMAC-SHA1(%s)= ",argv[n]); + for(i=0 ; i < 20 ; ++i) + printf("%02x",md[i]); + printf("\n"); + } +#endif + return 0; + } + +