Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:raulgs:gtk2_win
mingw32-openssl
openssl-1.0.2h-fips.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssl-1.0.2h-fips.patch of Package mingw32-openssl
diff --git a/Configure b/Configure index c98107a..9f7408a 100755 --- a/Configure +++ b/Configure @@ -1062,11 +1062,6 @@ if (defined($disabled{"md5"}) || defined($disabled{"rsa"})) $disabled{"ssl2"} = "forced"; } -if ($fips && $fipslibdir eq "") - { - $fipslibdir = $fipsdir . "/lib/"; - } - # RSAX ENGINE sets default non-FIPS RSA method. if ($fips) { @@ -1555,7 +1550,6 @@ $cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($bn_obj =~ /-gf2m/); if ($fips) { $openssl_other_defines.="#define OPENSSL_FIPS\n"; - $cflags .= " -I\$(FIPSDIR)/include"; } $cpuid_obj="mem_clr.o" unless ($cpuid_obj =~ /\.o$/); @@ -1758,9 +1752,12 @@ while (<IN>) s/^FIPSDIR=.*/FIPSDIR=$fipsdir/; s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/; - s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips; s/^BASEADDR=.*/BASEADDR=$baseaddr/; + if ($fips) + { + s/^FIPS=.*/FIPS=yes/; + } s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/; s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/; s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared); diff --git a/Makefile.org b/Makefile.org index 76fdbdf..7131f8e 100644 --- a/Makefile.org +++ b/Makefile.org @@ -136,6 +136,9 @@ FIPSCANLIB= BASEADDR= +# Non-empty if FIPS enabled +FIPS= + DIRS= crypto ssl engines apps test tools ENGDIRS= ccgost SHLIBDIRS= crypto ssl @@ -148,7 +151,7 @@ SDIRS= \ bn ec rsa dsa ecdsa dh ecdh dso engine \ buffer bio stack lhash rand err \ evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ - cms pqueue ts jpake srp store cmac + cms pqueue ts jpake srp store cmac fips # keep in mind that the above list is adjusted by ./Configure # according to no-xxx arguments... @@ -238,6 +241,7 @@ BUILDENV= LC_ALL=C PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)'\ FIPSLIBDIR='${FIPSLIBDIR}' \ FIPSDIR='${FIPSDIR}' \ FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}" \ + FIPS="$${FIPS:-$(FIPS)}" \ THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES= # MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors, # which in turn eliminates ambiguities in variable treatment with -e. diff --git a/Makefile.org.orig b/Makefile.org.orig new file mode 100644 index 0000000..76fdbdf --- /dev/null +++ b/Makefile.org.orig @@ -0,0 +1,678 @@ +## +## Makefile for OpenSSL +## + +VERSION= +MAJOR= +MINOR= +SHLIB_VERSION_NUMBER= +SHLIB_VERSION_HISTORY= +SHLIB_MAJOR= +SHLIB_MINOR= +SHLIB_EXT= +PLATFORM=dist +OPTIONS= +CONFIGURE_ARGS= +SHLIB_TARGET= + +# HERE indicates where this Makefile lives. This can be used to indicate +# where sub-Makefiles are expected to be. Currently has very limited usage, +# and should probably not be bothered with at all. +HERE=. + +# INSTALL_PREFIX is for package builders so that they can configure +# for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/. +# Normally it is left empty. +INSTALL_PREFIX= +INSTALLTOP=/usr/local/ssl + +# Do not edit this manually. Use Configure --openssldir=DIR do change this! +OPENSSLDIR=/usr/local/ssl + +# NO_IDEA - Define to build without the IDEA algorithm +# NO_RC4 - Define to build without the RC4 algorithm +# NO_RC2 - Define to build without the RC2 algorithm +# THREADS - Define when building with threads, you will probably also need any +# system defines as well, i.e. _REENTERANT for Solaris 2.[34] +# TERMIO - Define the termio terminal subsystem, needed if sgtty is missing. +# TERMIOS - Define the termios terminal subsystem, Silicon Graphics. +# LONGCRYPT - Define to use HPUX 10.x's long password modification to crypt(3). +# DEVRANDOM - Give this the value of the 'random device' if your OS supports +# one. 32 bytes will be read from this when the random +# number generator is initalised. +# SSL_FORBID_ENULL - define if you want the server to be not able to use the +# NULL encryption ciphers. +# +# LOCK_DEBUG - turns on lots of lock debug output :-) +# REF_CHECK - turn on some xyz_free() assertions. +# REF_PRINT - prints some stuff on structure free. +# CRYPTO_MDEBUG - turns on my 'memory leak' detecting stuff +# MFUNC - Make all Malloc/Free/Realloc calls call +# CRYPTO_malloc/CRYPTO_free/CRYPTO_realloc which can be setup to +# call application defined callbacks via CRYPTO_set_mem_functions() +# MD5_ASM needs to be defined to use the x86 assembler for MD5 +# SHA1_ASM needs to be defined to use the x86 assembler for SHA1 +# RMD160_ASM needs to be defined to use the x86 assembler for RIPEMD160 +# Do not define B_ENDIAN or L_ENDIAN if 'unsigned long' == 8. It must +# equal 4. +# PKCS1_CHECK - pkcs1 tests. + +CC= cc +CFLAG= -O +DEPFLAG= +PEX_LIBS= +EX_LIBS= +EXE_EXT= +ARFLAGS= +AR=ar $(ARFLAGS) r +RANLIB= ranlib +NM= nm +PERL= perl +TAR= tar +TARFLAGS= --no-recursion +MAKEDEPPROG=makedepend +LIBDIR=lib + +# We let the C compiler driver to take care of .s files. This is done in +# order to be excused from maintaining a separate set of architecture +# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC +# gcc, then the driver will automatically translate it to -xarch=v8plus +# and pass it down to assembler. +AS=$(CC) -c +ASFLAG=$(CFLAG) + +# For x86 assembler: Set PROCESSOR to 386 if you want to support +# the 80386. +PROCESSOR= + +# CPUID module collects small commonly used assembler snippets +CPUID_OBJ= +BN_ASM= bn_asm.o +EC_ASM= +DES_ENC= des_enc.o fcrypt_b.o +AES_ENC= aes_core.o aes_cbc.o +BF_ENC= bf_enc.o +CAST_ENC= c_enc.o +RC4_ENC= rc4_enc.o +RC5_ENC= rc5_enc.o +MD5_ASM_OBJ= +SHA1_ASM_OBJ= +RMD160_ASM_OBJ= +WP_ASM_OBJ= +CMLL_ENC= +MODES_ASM_OBJ= +ENGINES_ASM_OBJ= +PERLASM_SCHEME= + +# KRB5 stuff +KRB5_INCLUDES= +LIBKRB5= + +# Zlib stuff +ZLIB_INCLUDE= +LIBZLIB= + +# TOP level FIPS install directory. +FIPSDIR= + +# This is the location of fipscanister.o and friends. +# The FIPS module build will place it $(INSTALLTOP)/lib +# but since $(INSTALLTOP) can only take the default value +# when the module is built it will be in /usr/local/ssl/lib +# $(INSTALLTOP) for this build may be different so hard +# code the path. + +FIPSLIBDIR= + +# The location of the library which contains fipscanister.o +# normally it will be libcrypto unless fipsdso is set in which +# case it will be libfips. If not compiling in FIPS mode at all +# this is empty making it a useful test for a FIPS compile. + +FIPSCANLIB= + +# Shared library base address. Currently only used on Windows. +# + +BASEADDR= + +DIRS= crypto ssl engines apps test tools +ENGDIRS= ccgost +SHLIBDIRS= crypto ssl + +# dirs in crypto to build +SDIRS= \ + objects \ + md2 md4 md5 sha mdc2 hmac ripemd whrlpool \ + des aes rc2 rc4 rc5 idea bf cast camellia seed modes \ + bn ec rsa dsa ecdsa dh ecdh dso engine \ + buffer bio stack lhash rand err \ + evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ + cms pqueue ts jpake srp store cmac +# keep in mind that the above list is adjusted by ./Configure +# according to no-xxx arguments... + +# tests to perform. "alltests" is a special word indicating that all tests +# should be performed. +TESTS = alltests + +MAKEFILE= Makefile + +MANDIR=$(OPENSSLDIR)/man +MAN1=1 +MAN3=3 +MANSUFFIX= +HTMLSUFFIX=html +HTMLDIR=$(OPENSSLDIR)/html +SHELL=/bin/sh + +TOP= . +ONEDIRS=out tmp +EDIRS= times doc bugs util include certs ms shlib mt demos perl sf dep VMS +WDIRS= windows +LIBS= libcrypto.a libssl.a +SHARED_CRYPTO=libcrypto$(SHLIB_EXT) +SHARED_SSL=libssl$(SHLIB_EXT) +SHARED_LIBS= +SHARED_LIBS_LINK_EXTS= +SHARED_LDFLAGS= + +GENERAL= Makefile +BASENAME= openssl +NAME= $(BASENAME)-$(VERSION) +TARFILE= ../$(NAME).tar +EXHEADER= e_os2.h +HEADER= e_os.h + +all: Makefile build_all + +# as we stick to -e, CLEARENV ensures that local variables in lower +# Makefiles remain local and variable. $${VAR+VAR} is tribute to Korn +# shell, which [annoyingly enough] terminates unset with error if VAR +# is not present:-( TOP= && unset TOP is tribute to HP-UX /bin/sh, +# which terminates unset with error if no variable was present:-( +CLEARENV= TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS} \ + $${INCLUDE+INCLUDE} $${INCLUDES+INCLUDES} \ + $${DIR+DIR} $${DIRS+DIRS} $${SRC+SRC} \ + $${LIBSRC+LIBSRC} $${LIBOBJ+LIBOBJ} $${ALL+ALL} \ + $${EXHEADER+EXHEADER} $${HEADER+HEADER} \ + $${GENERAL+GENERAL} $${CFLAGS+CFLAGS} \ + $${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS} \ + $${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} $${SCRIPTS+SCRIPTS} \ + $${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS} \ + $${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS} + +# LC_ALL=C ensures that error [and other] messages are delivered in +# same language for uniform treatment. +BUILDENV= LC_ALL=C PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)'\ + CC='$(CC)' CFLAG='$(CFLAG)' \ + AS='$(CC)' ASFLAG='$(CFLAG) -c' \ + AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)' \ + CROSS_COMPILE='$(CROSS_COMPILE)' \ + PERL='$(PERL)' ENGDIRS='$(ENGDIRS)' \ + SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)' \ + INSTALL_PREFIX='$(INSTALL_PREFIX)' \ + INSTALLTOP='$(INSTALLTOP)' OPENSSLDIR='$(OPENSSLDIR)' \ + LIBDIR='$(LIBDIR)' \ + MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD $(MAKEDEPPROG)' \ + DEPFLAG='-DOPENSSL_NO_DEPRECATED $(DEPFLAG)' \ + MAKEDEPPROG='$(MAKEDEPPROG)' \ + SHARED_LDFLAGS='$(SHARED_LDFLAGS)' \ + KRB5_INCLUDES='$(KRB5_INCLUDES)' LIBKRB5='$(LIBKRB5)' \ + ZLIB_INCLUDE='$(ZLIB_INCLUDE)' LIBZLIB='$(LIBZLIB)' \ + EXE_EXT='$(EXE_EXT)' SHARED_LIBS='$(SHARED_LIBS)' \ + SHLIB_EXT='$(SHLIB_EXT)' SHLIB_TARGET='$(SHLIB_TARGET)' \ + PEX_LIBS='$(PEX_LIBS)' EX_LIBS='$(EX_LIBS)' \ + CPUID_OBJ='$(CPUID_OBJ)' BN_ASM='$(BN_ASM)' \ + EC_ASM='$(EC_ASM)' DES_ENC='$(DES_ENC)' \ + AES_ENC='$(AES_ENC)' CMLL_ENC='$(CMLL_ENC)' \ + BF_ENC='$(BF_ENC)' CAST_ENC='$(CAST_ENC)' \ + RC4_ENC='$(RC4_ENC)' RC5_ENC='$(RC5_ENC)' \ + SHA1_ASM_OBJ='$(SHA1_ASM_OBJ)' \ + MD5_ASM_OBJ='$(MD5_ASM_OBJ)' \ + RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)' \ + WP_ASM_OBJ='$(WP_ASM_OBJ)' \ + MODES_ASM_OBJ='$(MODES_ASM_OBJ)' \ + ENGINES_ASM_OBJ='$(ENGINES_ASM_OBJ)' \ + PERLASM_SCHEME='$(PERLASM_SCHEME)' \ + FIPSLIBDIR='${FIPSLIBDIR}' \ + FIPSDIR='${FIPSDIR}' \ + FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}" \ + THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES= +# MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors, +# which in turn eliminates ambiguities in variable treatment with -e. + +# BUILD_CMD is a generic macro to build a given target in a given +# subdirectory. The target must be given through the shell variable +# `target' and the subdirectory to build in must be given through `dir'. +# This macro shouldn't be used directly, use RECURSIVE_BUILD_CMD or +# BUILD_ONE_CMD instead. +# +# BUILD_ONE_CMD is a macro to build a given target in a given +# subdirectory if that subdirectory is part of $(DIRS). It requires +# exactly the same shell variables as BUILD_CMD. +# +# RECURSIVE_BUILD_CMD is a macro to build a given target in all +# subdirectories defined in $(DIRS). It requires that the target +# is given through the shell variable `target'. +BUILD_CMD= if [ -d "$$dir" ]; then \ + ( cd $$dir && echo "making $$target in $$dir..." && \ + $(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. DIR=$$dir $$target \ + ) || exit 1; \ + fi +RECURSIVE_BUILD_CMD=for dir in $(DIRS); do $(BUILD_CMD); done +BUILD_ONE_CMD=\ + if expr " $(DIRS) " : ".* $$dir " >/dev/null 2>&1; then \ + $(BUILD_CMD); \ + fi + +reflect: + @[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV) + +sub_all: build_all + +build_all: build_libs build_apps build_tests build_tools + +build_libs: build_libcrypto build_libssl openssl.pc + +build_libcrypto: build_crypto build_engines libcrypto.pc +build_libssl: build_ssl libssl.pc + +build_crypto: + @dir=crypto; target=all; $(BUILD_ONE_CMD) +build_ssl: build_crypto + @dir=ssl; target=all; $(BUILD_ONE_CMD) +build_engines: build_crypto + @dir=engines; target=all; $(BUILD_ONE_CMD) +build_apps: build_libs + @dir=apps; target=all; $(BUILD_ONE_CMD) +build_tests: build_libs + @dir=test; target=all; $(BUILD_ONE_CMD) +build_tools: build_libs + @dir=tools; target=all; $(BUILD_ONE_CMD) + +all_testapps: build_libs build_testapps +build_testapps: + @dir=crypto; target=testapps; $(BUILD_ONE_CMD) + +fips_premain_dso$(EXE_EXT): libcrypto.a + [ -z "$(FIPSCANLIB)" ] || $(CC) $(CFLAG) -Iinclude \ + -DFINGERPRINT_PREMAIN_DSO_LOAD -o $@ \ + $(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fipscanister.o \ + libcrypto.a $(EX_LIBS) + +libcrypto$(SHLIB_EXT): libcrypto.a fips_premain_dso$(EXE_EXT) + @if [ "$(SHLIB_TARGET)" != "" ]; then \ + if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \ + FIPSLD_LIBCRYPTO=libcrypto.a ; \ + FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; \ + export CC FIPSLD_CC FIPSLD_LIBCRYPTO; \ + fi; \ + $(MAKE) -e SHLIBDIRS=crypto CC="$${CC:-$(CC)}" build-shared && \ + (touch -c fips_premain_dso$(EXE_EXT) || :); \ + else \ + echo "There's no support for shared libraries on this platform" >&2; \ + exit 1; \ + fi + +libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a + @if [ "$(SHLIB_TARGET)" != "" ]; then \ + $(MAKE) SHLIBDIRS=ssl SHLIBDEPS='-lcrypto' build-shared; \ + else \ + echo "There's no support for shared libraries on this platform" >&2; \ + exit 1; \ + fi + +clean-shared: + @set -e; for i in $(SHLIBDIRS); do \ + if [ -n "$(SHARED_LIBS_LINK_EXTS)" ]; then \ + tmp="$(SHARED_LIBS_LINK_EXTS)"; \ + for j in $${tmp:-x}; do \ + ( set -x; rm -f lib$$i$$j ); \ + done; \ + fi; \ + ( set -x; rm -f lib$$i$(SHLIB_EXT) ); \ + if expr "$(PLATFORM)" : "Cygwin" >/dev/null; then \ + ( set -x; rm -f cyg$$i$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \ + fi; \ + done + +link-shared: + @ set -e; for i in $(SHLIBDIRS); do \ + $(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \ + LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \ + LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \ + symlink.$(SHLIB_TARGET); \ + libs="$$libs -l$$i"; \ + done + +build-shared: do_$(SHLIB_TARGET) link-shared + +do_$(SHLIB_TARGET): + @ set -e; libs='-L. $(SHLIBDEPS)'; for i in $(SHLIBDIRS); do \ + if [ "$$i" = "ssl" -a -n "$(LIBKRB5)" ]; then \ + libs="$(LIBKRB5) $$libs"; \ + fi; \ + $(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \ + LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \ + LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \ + LIBDEPS="$$libs $(EX_LIBS)" \ + link_a.$(SHLIB_TARGET); \ + libs="-l$$i $$libs"; \ + done + +libcrypto.pc: Makefile + @ ( echo 'prefix=$(INSTALLTOP)'; \ + echo 'exec_prefix=$${prefix}'; \ + echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ + echo 'includedir=$${prefix}/include'; \ + echo ''; \ + echo 'Name: OpenSSL-libcrypto'; \ + echo 'Description: OpenSSL cryptography library'; \ + echo 'Version: '$(VERSION); \ + echo 'Requires: '; \ + echo 'Libs: -L$${libdir} -lcrypto'; \ + echo 'Libs.private: $(EX_LIBS)'; \ + echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc + +libssl.pc: Makefile + @ ( echo 'prefix=$(INSTALLTOP)'; \ + echo 'exec_prefix=$${prefix}'; \ + echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ + echo 'includedir=$${prefix}/include'; \ + echo ''; \ + echo 'Name: OpenSSL-libssl'; \ + echo 'Description: Secure Sockets Layer and cryptography libraries'; \ + echo 'Version: '$(VERSION); \ + echo 'Requires.private: libcrypto'; \ + echo 'Libs: -L$${libdir} -lssl'; \ + echo 'Libs.private: $(EX_LIBS)'; \ + echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc + +openssl.pc: Makefile + @ ( echo 'prefix=$(INSTALLTOP)'; \ + echo 'exec_prefix=$${prefix}'; \ + echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ + echo 'includedir=$${prefix}/include'; \ + echo ''; \ + echo 'Name: OpenSSL'; \ + echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \ + echo 'Version: '$(VERSION); \ + echo 'Requires: libssl libcrypto' ) > openssl.pc + +Makefile: Makefile.org Configure config + @echo "Makefile is older than Makefile.org, Configure or config." + @echo "Reconfigure the source tree (via './config' or 'perl Configure'), please." + @false + +libclean: + rm -f *.map *.so *.so.* *.dylib *.dll engines/*.so engines/*.dll engines/*.dylib *.a engines/*.a */lib */*/lib + +clean: libclean + rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c + @set -e; target=clean; $(RECURSIVE_BUILD_CMD) + rm -f $(LIBS) + rm -f openssl.pc libssl.pc libcrypto.pc + rm -f speed.* .pure + rm -f $(TARFILE) + @set -e; for i in $(ONEDIRS) ;\ + do \ + rm -fr $$i/*; \ + done + +makefile.one: files + $(PERL) util/mk1mf.pl >makefile.one; \ + sh util/do_ms.sh + +files: + $(PERL) $(TOP)/util/files.pl Makefile > $(TOP)/MINFO + @set -e; target=files; $(RECURSIVE_BUILD_CMD) + +links: + @$(PERL) $(TOP)/util/mkdir-p.pl include/openssl + @$(PERL) $(TOP)/util/mklink.pl include/openssl $(EXHEADER) + @set -e; target=links; $(RECURSIVE_BUILD_CMD) + +gentests: + @(cd test && echo "generating dummy tests (if needed)..." && \ + $(CLEARENV) && $(MAKE) -e $(BUILDENV) TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on generate ); + +dclean: + rm -rf *.bak include/openssl certs/.0 + @set -e; target=dclean; $(RECURSIVE_BUILD_CMD) + +rehash: rehash.time +rehash.time: certs apps + @if [ -z "$(CROSS_COMPILE)" ]; then \ + (OPENSSL="`pwd`/util/opensslwrap.sh"; \ + [ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \ + OPENSSL_DEBUG_MEMORY=on; \ + export OPENSSL OPENSSL_DEBUG_MEMORY; \ + $(PERL) tools/c_rehash certs/demo) && \ + touch rehash.time; \ + else :; fi + +test: tests + +tests: rehash + @(cd test && echo "testing..." && \ + $(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on OPENSSL_CONF=../apps/openssl.cnf tests ); + OPENSSL_CONF=apps/openssl.cnf util/opensslwrap.sh version -a + +report: + @$(PERL) util/selftest.pl + +update: errors stacks util/libeay.num util/ssleay.num TABLE + @set -e; target=update; $(RECURSIVE_BUILD_CMD) + +depend: + @set -e; target=depend; $(RECURSIVE_BUILD_CMD) + +lint: + @set -e; target=lint; $(RECURSIVE_BUILD_CMD) + +tags: + rm -f TAGS + find . -name '[^.]*.[ch]' | xargs etags -a + +errors: + $(PERL) util/ck_errf.pl -strict */*.c */*/*.c + $(PERL) util/mkerr.pl -recurse -write + (cd engines; $(MAKE) PERL=$(PERL) errors) + +stacks: + $(PERL) util/mkstack.pl -write + +util/libeay.num:: + $(PERL) util/mkdef.pl crypto update + +util/ssleay.num:: + $(PERL) util/mkdef.pl ssl update + +TABLE: Configure + (echo 'Output of `Configure TABLE'"':"; \ + $(PERL) Configure TABLE) > TABLE + +# Build distribution tar-file. As the list of files returned by "find" is +# pretty long, on several platforms a "too many arguments" error or similar +# would occur. Therefore the list of files is temporarily stored into a file +# and read directly, requiring GNU-Tar. Call "make TAR=gtar dist" if the normal +# tar does not support the --files-from option. +TAR_COMMAND=$(TAR) $(TARFLAGS) --files-from $(TARFILE).list \ + --owner 0 --group 0 \ + --transform 's|^|$(NAME)/|' \ + -cvf - + +$(TARFILE).list: + find * \! -name STATUS \! -name TABLE \! -name '*.o' \! -name '*.a' \ + \! -name '*.so' \! -name '*.so.*' \! -name 'openssl' \ + \( \! -name '*test' -o -name bctest -o -name pod2mantest \) \ + \! -name '.#*' \! -name '*~' \! -type l \ + | sort > $(TARFILE).list + +tar: $(TARFILE).list + find . -type d -print | xargs chmod 755 + find . -type f -print | xargs chmod a+r + find . -type f -perm -0100 -print | xargs chmod a+x + $(TAR_COMMAND) | gzip --best > $(TARFILE).gz + rm -f $(TARFILE).list + ls -l $(TARFILE).gz + +tar-snap: $(TARFILE).list + $(TAR_COMMAND) > $(TARFILE) + rm -f $(TARFILE).list + ls -l $(TARFILE) + +dist: + $(PERL) Configure dist + @$(MAKE) SDIRS='$(SDIRS)' clean + @$(MAKE) TAR='$(TAR)' TARFLAGS='$(TARFLAGS)' $(DISTTARVARS) tar + +install: all install_docs install_sw + +install_sw: + @$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \ + $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \ + $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \ + $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \ + $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \ + $(INSTALL_PREFIX)$(OPENSSLDIR)/misc \ + $(INSTALL_PREFIX)$(OPENSSLDIR)/certs \ + $(INSTALL_PREFIX)$(OPENSSLDIR)/private + @set -e; headerlist="$(EXHEADER)"; for i in $$headerlist;\ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + @set -e; target=install; $(RECURSIVE_BUILD_CMD) + @set -e; liblist="$(LIBS)"; for i in $$liblist ;\ + do \ + if [ -f "$$i" ]; then \ + ( echo installing $$i; \ + cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \ + $(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \ + fi; \ + done; + @set -e; if [ -n "$(SHARED_LIBS)" ]; then \ + tmp="$(SHARED_LIBS)"; \ + for i in $${tmp:-x}; \ + do \ + if [ -f "$$i" -o -f "$$i.a" ]; then \ + ( echo installing $$i; \ + if expr "$(PLATFORM)" : "Cygwin" >/dev/null; then \ + c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \ + cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \ + chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \ + cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \ + else \ + cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \ + chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \ + fi ); \ + if expr $(PLATFORM) : 'mingw' > /dev/null; then \ + ( case $$i in \ + *crypto*) i=libeay32.dll;; \ + *ssl*) i=ssleay32.dll;; \ + esac; \ + echo installing $$i; \ + cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \ + chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \ + fi; \ + fi; \ + done; \ + ( here="`pwd`"; \ + cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \ + $(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \ + if [ "$(INSTALLTOP)" != "/usr" ]; then \ + echo 'OpenSSL shared libraries have been installed in:'; \ + echo ' $(INSTALLTOP)'; \ + echo ''; \ + sed -e '1,/^$$/d' doc/openssl-shared.txt; \ + fi; \ + fi + cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc + cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc + cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc + +install_html_docs: + here="`pwd`"; \ + filecase=; \ + case "$(PLATFORM)" in DJGPP|Cygwin*|mingw*|darwin*-*-cc) \ + filecase=-i; \ + esac; \ + for subdir in apps crypto ssl; do \ + mkdir -p $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \ + for i in doc/$$subdir/*.pod; do \ + fn=`basename $$i .pod`; \ + echo "installing html/$$fn.$(HTMLSUFFIX)"; \ + cat $$i \ + | sed -r 's/L<([^)]*)(\([0-9]\))?\|([^)]*)(\([0-9]\))?>/L<\1|\3>/g' \ + | pod2html --podroot=doc --htmlroot=.. --podpath=apps:crypto:ssl \ + | sed -r 's/<!DOCTYPE.*//g' \ + > $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir/$$fn.$(HTMLSUFFIX); \ + $(PERL) util/extract-names.pl < $$i | \ + grep -v $$filecase "^$$fn\$$" | \ + (cd $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \ + while read n; do \ + PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$(HTMLSUFFIX) "$$n".$(HTMLSUFFIX); \ + done); \ + done; \ + done + +install_docs: + @$(PERL) $(TOP)/util/mkdir-p.pl \ + $(INSTALL_PREFIX)$(MANDIR)/man1 \ + $(INSTALL_PREFIX)$(MANDIR)/man3 \ + $(INSTALL_PREFIX)$(MANDIR)/man5 \ + $(INSTALL_PREFIX)$(MANDIR)/man7 + @pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \ + here="`pwd`"; \ + filecase=; \ + case "$(PLATFORM)" in DJGPP|Cygwin*|mingw*|darwin*-*-cc) \ + filecase=-i; \ + esac; \ + set -e; for i in doc/apps/*.pod; do \ + fn=`basename $$i .pod`; \ + sec=`$(PERL) util/extract-section.pl 1 < $$i`; \ + echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \ + (cd `$(PERL) util/dirname.pl $$i`; \ + sh -c "$$pod2man \ + --section=$$sec --center=OpenSSL \ + --release=$(VERSION) `basename $$i`") \ + > $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \ + $(PERL) util/extract-names.pl < $$i | \ + (grep -v $$filecase "^$$fn\$$"; true) | \ + (grep -v "[ ]"; true) | \ + (cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \ + while read n; do \ + PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \ + done); \ + done; \ + set -e; for i in doc/crypto/*.pod doc/ssl/*.pod; do \ + fn=`basename $$i .pod`; \ + sec=`$(PERL) util/extract-section.pl 3 < $$i`; \ + echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \ + (cd `$(PERL) util/dirname.pl $$i`; \ + sh -c "$$pod2man \ + --section=$$sec --center=OpenSSL \ + --release=$(VERSION) `basename $$i`") \ + > $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \ + $(PERL) util/extract-names.pl < $$i | \ + (grep -v $$filecase "^$$fn\$$"; true) | \ + (grep -v "[ ]"; true) | \ + (cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \ + while read n; do \ + PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \ + done); \ + done + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/apps/speed.c b/apps/speed.c index 95adcc1..a9c47af 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -197,7 +197,6 @@ # ifdef OPENSSL_DOING_MAKEDEPEND # undef AES_set_encrypt_key # undef AES_set_decrypt_key -# undef DES_set_key_unchecked # endif # define BF_set_key private_BF_set_key # define CAST_set_key private_CAST_set_key @@ -205,7 +204,6 @@ # define SEED_set_key private_SEED_set_key # define RC2_set_key private_RC2_set_key # define RC4_set_key private_RC4_set_key -# define DES_set_key_unchecked private_DES_set_key_unchecked # define AES_set_encrypt_key private_AES_set_encrypt_key # define AES_set_decrypt_key private_AES_set_decrypt_key # define Camellia_set_key private_Camellia_set_key @@ -974,7 +972,12 @@ int MAIN(int argc, char **argv) # endif # ifndef OPENSSL_NO_RSA if (strcmp(*argv, "rsa") == 0) { - rsa_doit[R_RSA_512] = 1; +# ifdef OPENSSL_FIPS + if (!FIPS_mode()) +# endif + { + rsa_doit[R_RSA_512] = 1; + } rsa_doit[R_RSA_1024] = 1; rsa_doit[R_RSA_2048] = 1; rsa_doit[R_RSA_4096] = 1; @@ -982,7 +985,12 @@ int MAIN(int argc, char **argv) # endif # ifndef OPENSSL_NO_DSA if (strcmp(*argv, "dsa") == 0) { - dsa_doit[R_DSA_512] = 1; +# ifdef OPENSSL_FIPS + if (!FIPS_mode()) +# endif + { + dsa_doit[R_DSA_512] = 1; + } dsa_doit[R_DSA_1024] = 1; dsa_doit[R_DSA_2048] = 1; } else @@ -1233,13 +1241,19 @@ int MAIN(int argc, char **argv) if (j == 0) { for (i = 0; i < ALGOR_NUM; i++) { - if (i != D_EVP) + if (i != D_EVP && + (!FIPS_mode() || (i != D_WHIRLPOOL && + i != D_MD2 && i != D_MD4 && + i != D_MD5 && i != D_MDC2 && + i != D_RMD160))) doit[i] = 1; } for (i = 0; i < RSA_NUM; i++) - rsa_doit[i] = 1; + if (!FIPS_mode() || i != R_RSA_512) + rsa_doit[i] = 1; for (i = 0; i < DSA_NUM; i++) - dsa_doit[i] = 1; + if (!FIPS_mode() || i != R_DSA_512) + dsa_doit[i] = 1; # ifndef OPENSSL_NO_ECDSA for (i = 0; i < EC_NUM; i++) ecdsa_doit[i] = 1; @@ -1299,30 +1313,46 @@ int MAIN(int argc, char **argv) AES_set_encrypt_key(key32, 256, &aes_ks3); # endif # ifndef OPENSSL_NO_CAMELLIA - Camellia_set_key(key16, 128, &camellia_ks1); - Camellia_set_key(ckey24, 192, &camellia_ks2); - Camellia_set_key(ckey32, 256, &camellia_ks3); + if (doit[D_CBC_128_CML] || doit[D_CBC_192_CML] || doit[D_CBC_256_CML]) { + Camellia_set_key(key16, 128, &camellia_ks1); + Camellia_set_key(ckey24, 192, &camellia_ks2); + Camellia_set_key(ckey32, 256, &camellia_ks3); + } # endif # ifndef OPENSSL_NO_IDEA - idea_set_encrypt_key(key16, &idea_ks); + if (doit[D_CBC_IDEA]) { + idea_set_encrypt_key(key16, &idea_ks); + } # endif # ifndef OPENSSL_NO_SEED - SEED_set_key(key16, &seed_ks); + if (doit[D_CBC_SEED]) { + SEED_set_key(key16, &seed_ks); + } # endif # ifndef OPENSSL_NO_RC4 - RC4_set_key(&rc4_ks, 16, key16); + if (doit[D_RC4]) { + RC4_set_key(&rc4_ks, 16, key16); + } # endif # ifndef OPENSSL_NO_RC2 - RC2_set_key(&rc2_ks, 16, key16, 128); + if (doit[D_CBC_RC2]) { + RC2_set_key(&rc2_ks, 16, key16, 128); + } # endif # ifndef OPENSSL_NO_RC5 - RC5_32_set_key(&rc5_ks, 16, key16, 12); + if (doit[D_CBC_RC5]) { + RC5_32_set_key(&rc5_ks, 16, key16, 12); + } # endif # ifndef OPENSSL_NO_BF - BF_set_key(&bf_ks, 16, key16); + if (doit[D_CBC_BF]) { + BF_set_key(&bf_ks, 16, key16); + } # endif # ifndef OPENSSL_NO_CAST - CAST_set_key(&cast_ks, 16, key16); + if (doit[D_CBC_CAST]) { + CAST_set_key(&cast_ks, 16, key16); + } # endif # ifndef OPENSSL_NO_RSA memset(rsa_c, 0, sizeof(rsa_c)); @@ -1605,6 +1635,7 @@ int MAIN(int argc, char **argv) HMAC_CTX hctx; HMAC_CTX_init(&hctx); + HMAC_CTX_set_flags(&hctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); HMAC_Init_ex(&hctx, (unsigned char *)"This is a key...", 16, EVP_md5(), NULL); diff --git a/crypto/aes/aes_misc.c b/crypto/aes/aes_misc.c index fafad4d..4ab7312 100644 --- a/crypto/aes/aes_misc.c +++ b/crypto/aes/aes_misc.c @@ -70,17 +70,11 @@ const char *AES_options(void) int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key) { -#ifdef OPENSSL_FIPS - fips_cipher_abort(AES); -#endif return private_AES_set_encrypt_key(userKey, bits, key); } int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key) { -#ifdef OPENSSL_FIPS - fips_cipher_abort(AES); -#endif return private_AES_set_decrypt_key(userKey, bits, key); } diff --git a/crypto/cmac/cmac.c b/crypto/cmac/cmac.c index 2954b6e..784228d 100644 --- a/crypto/cmac/cmac.c +++ b/crypto/cmac/cmac.c @@ -105,12 +105,6 @@ CMAC_CTX *CMAC_CTX_new(void) void CMAC_CTX_cleanup(CMAC_CTX *ctx) { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) { - FIPS_cmac_ctx_cleanup(ctx); - return; - } -#endif EVP_CIPHER_CTX_cleanup(&ctx->cctx); OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); @@ -160,20 +154,6 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS); return 0; } - - /* Switch to FIPS cipher implementation if possible */ - if (cipher != NULL) { - const EVP_CIPHER *fcipher; - fcipher = FIPS_get_cipherbynid(EVP_CIPHER_nid(cipher)); - if (fcipher != NULL) - cipher = fcipher; - } - /* - * Other algorithm blocking will be done in FIPS_cmac_init, via - * FIPS_cipherinit(). - */ - if (!impl && !ctx->cctx.engine) - return FIPS_cmac_init(ctx, key, keylen, cipher, NULL); } #endif /* All zeros means restart */ @@ -219,10 +199,6 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) { const unsigned char *data = in; size_t bl; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) - return FIPS_cmac_update(ctx, in, dlen); -#endif if (ctx->nlast_block == -1) return 0; if (dlen == 0) @@ -262,10 +238,6 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) { int i, bl, lb; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) - return FIPS_cmac_final(ctx, out, poutlen); -#endif if (ctx->nlast_block == -1) return 0; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); diff --git a/crypto/crypto.h b/crypto/crypto.h index 6c644ce..01efbc2 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -600,24 +600,29 @@ int FIPS_mode_set(int r); void OPENSSL_init(void); # define fips_md_init(alg) fips_md_init_ctx(alg, alg) +# define nonfips_md_init(alg) nonfips_md_init_ctx(alg, alg) +# define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) # ifdef OPENSSL_FIPS -# define fips_md_init_ctx(alg, cx) \ +# define nonfips_md_init_ctx(alg, cx) \ int alg##_Init(cx##_CTX *c) \ { \ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ - "Low level API call to digest " #alg " forbidden in FIPS mode!"); \ + "Digest " #alg " forbidden in FIPS mode!"); \ return private_##alg##_Init(c); \ } \ int private_##alg##_Init(cx##_CTX *c) # define fips_cipher_abort(alg) \ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ - "Low level API call to cipher " #alg " forbidden in FIPS mode!") + "Cipher " #alg " forbidden in FIPS mode!") + +/* die if FIPS selftest failed */ +void FIPS_selftest_check(void); # else -# define fips_md_init_ctx(alg, cx) \ - int alg##_Init(cx##_CTX *c) +# define nonfips_md_init_ctx(alg, cx) fips_md_init_ctx(alg, cx) # define fips_cipher_abort(alg) while(0) # endif @@ -637,6 +642,9 @@ int CRYPTO_memcmp(const volatile void *a, const volatile void *b, size_t len); */ void ERR_load_CRYPTO_strings(void); +# define OPENSSL_HAVE_INIT 1 +void OPENSSL_init_library(void); + /* Error codes for the CRYPTO functions. */ /* Function codes. */ diff --git a/crypto/des/des.h b/crypto/des/des.h index 1b40144..fe02e34 100644 --- a/crypto/des/des.h +++ b/crypto/des/des.h @@ -231,10 +231,6 @@ int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); -# ifdef OPENSSL_FIPS -void private_DES_set_key_unchecked(const_DES_cblock *key, - DES_key_schedule *schedule); -# endif void DES_string_to_key(const char *str, DES_cblock *key); void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, diff --git a/crypto/des/set_key.c b/crypto/des/set_key.c index 8fd8fe1..5c63164 100644 --- a/crypto/des/set_key.c +++ b/crypto/des/set_key.c @@ -359,15 +359,6 @@ int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule) } void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) -#ifdef OPENSSL_FIPS -{ - fips_cipher_abort(DES); - private_DES_set_key_unchecked(key, schedule); -} - -void private_DES_set_key_unchecked(const_DES_cblock *key, - DES_key_schedule *schedule) -#endif { static const int shifts2[16] = { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 }; diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h index a5bd901..7ae5079 100644 --- a/crypto/dh/dh.h +++ b/crypto/dh/dh.h @@ -77,6 +77,8 @@ # define OPENSSL_DH_MAX_MODULUS_BITS 10000 # endif +# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + # define DH_FLAG_CACHE_MONT_P 0x01 /* diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c index 5bedb66..4fcb16b 100644 --- a/crypto/dh/dh_gen.c +++ b/crypto/dh/dh_gen.c @@ -85,10 +85,6 @@ int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, #endif if (ret->meth->generate_params) return ret->meth->generate_params(ret, prime_len, generator, cb); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dh_generate_parameters_ex(ret, prime_len, generator, cb); -#endif return dh_builtin_genparams(ret, prime_len, generator, cb); } @@ -126,6 +122,18 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, int g, ok = -1; BN_CTX *ctx = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS, FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif + ctx = BN_CTX_new(); if (ctx == NULL) goto err; diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 1d80fb2..1c24715 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -61,6 +61,9 @@ #include <openssl/bn.h> #include <openssl/rand.h> #include <openssl/dh.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif static int generate_key(DH *dh); static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); @@ -97,7 +100,7 @@ int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) { int rv, pad; - rv = dh->meth->compute_key(key, pub_key, dh); + rv = DH_compute_key(key, pub_key, dh); if (rv <= 0) return rv; pad = BN_num_bytes(dh->p) - rv; @@ -115,7 +118,7 @@ static DH_METHOD dh_ossl = { dh_bn_mod_exp, dh_init, dh_finish, - 0, + DH_FLAG_FIPS_METHOD, NULL, NULL }; @@ -134,6 +137,14 @@ static int generate_key(DH *dh) BN_MONT_CTX *mont = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_mode() + && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { + DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + return 0; + } +#endif + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -217,6 +228,13 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); goto err; } +#ifdef OPENSSL_FIPS + if (FIPS_mode() + && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { + DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } +#endif ctx = BN_CTX_new(); if (ctx == NULL) @@ -277,6 +295,9 @@ static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, static int dh_init(DH *dh) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif dh->flags |= DH_FLAG_CACHE_MONT_P; return (1); } diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index bebc160..b38b4be 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -80,14 +80,7 @@ void DH_set_default_method(const DH_METHOD *meth) const DH_METHOD *DH_get_default_method(void) { if (!default_DH_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dh_openssl(); - else - return DH_OpenSSL(); -#else default_DH_method = DH_OpenSSL(); -#endif } return default_DH_method; } diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 545358f..7c78c5a 100644 --- a/crypto/dsa/dsa.h +++ b/crypto/dsa/dsa.h @@ -88,6 +88,8 @@ # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 # endif +# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + # define DSA_FLAG_CACHE_MONT_P 0x01 /* * new with 0.9.7h; the built-in DSA implementation now uses constant time @@ -265,6 +267,20 @@ int DSA_print_fp(FILE *bp, const DSA *x, int off); DH *DSA_dup_DH(const DSA *r); # endif +# ifdef OPENSSL_FIPS +int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, + const unsigned char *seed_in, + size_t seed_len, int *counter_ret, + unsigned long *h_ret, BN_GENCB *cb); +int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits, + const EVP_MD *evpmd, unsigned char *seed, + int seed_len, BIGNUM **p_ret, BIGNUM **q_ret, + int *counter_ret, BN_GENCB *cb); +int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, BIGNUM **g_ret, + unsigned long *h_ret, BN_GENCB *cb); +# endif + # define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) @@ -287,11 +303,14 @@ void ERR_load_DSA_strings(void); # define DSA_F_DO_DSA_PRINT 104 # define DSA_F_DSAPARAMS_PRINT 100 # define DSA_F_DSAPARAMS_PRINT_FP 101 -# define DSA_F_DSA_BUILTIN_PARAMGEN2 126 +# define DSA_F_DSA_BUILTIN_KEYGEN 124 +# define DSA_F_DSA_BUILTIN_PARAMGEN 123 +# define DSA_F_DSA_BUILTIN_PARAMGEN2 226 # define DSA_F_DSA_DO_SIGN 112 # define DSA_F_DSA_DO_VERIFY 113 -# define DSA_F_DSA_GENERATE_KEY 124 -# define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 +# define DSA_F_DSA_GENERATE_KEY 126 +# define DSA_F_DSA_GENERATE_PARAMETERS_EX 127 +# define DSA_F_DSA_GENERATE_PARAMETERS /* unused */ 125 # define DSA_F_DSA_NEW_METHOD 103 # define DSA_F_DSA_PARAM_DECODE 119 # define DSA_F_DSA_PRINT_FP 105 @@ -317,12 +336,16 @@ void ERR_load_DSA_strings(void); # define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 # define DSA_R_DECODE_ERROR 104 # define DSA_R_INVALID_DIGEST_TYPE 106 -# define DSA_R_INVALID_PARAMETERS 112 +# define DSA_R_INVALID_PARAMETERS 212 +# define DSA_R_KEY_SIZE_INVALID 113 +# define DSA_R_KEY_SIZE_TOO_SMALL 110 # define DSA_R_MISSING_PARAMETERS 101 # define DSA_R_MODULUS_TOO_LARGE 103 -# define DSA_R_NEED_NEW_SETUP_VALUES 110 +# define DSA_R_NEED_NEW_SETUP_VALUES 112 # define DSA_R_NON_FIPS_DSA_METHOD 111 +# define DSA_R_NON_FIPS_METHOD 111 # define DSA_R_NO_PARAMETERS_SET 107 +# define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE /* unused */ 112 # define DSA_R_PARAMETER_ENCODING_ERROR 105 # define DSA_R_Q_NOT_PRIME 113 diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index f5ddc66..5bae45c 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -74,6 +74,8 @@ static ERR_STRING_DATA DSA_str_functs[] = { {ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, + {ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN), "dsa_builtin_keygen"}, + {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "dsa_builtin_paramgen"}, {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"}, {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, @@ -109,6 +111,8 @@ static ERR_STRING_DATA DSA_str_reasons[] = { {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"}, {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"}, {ERR_REASON(DSA_R_INVALID_PARAMETERS), "invalid parameters"}, + {ERR_REASON(DSA_R_KEY_SIZE_INVALID), "key size invalid"}, + {ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL), "key size too small"}, {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"}, {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index 15f3bb4..96c4c09 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -91,6 +91,16 @@ # include <openssl/fips.h> # endif +# ifndef OPENSSL_FIPS +static int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits, + const EVP_MD *evpmd, unsigned char *seed, + int seed_len, BIGNUM **p_ret, BIGNUM **q_ret, + int *counter_ret, BN_GENCB *cb); +static int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, + BIGNUM **g_ret, unsigned long *h_ret, + BN_GENCB *cb); +# endif + int DSA_generate_parameters_ex(DSA *ret, int bits, const unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, @@ -106,97 +116,165 @@ int DSA_generate_parameters_ex(DSA *ret, int bits, if (ret->meth->dsa_paramgen) return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, counter_ret, h_ret, cb); -# ifdef OPENSSL_FIPS - else if (FIPS_mode()) { - return FIPS_dsa_generate_parameters_ex(ret, bits, - seed_in, seed_len, - counter_ret, h_ret, cb); - } -# endif else { const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); size_t qbits = EVP_MD_size(evpmd) * 8; return dsa_builtin_paramgen(ret, bits, qbits, evpmd, - seed_in, seed_len, NULL, counter_ret, + seed_in, seed_len, counter_ret, h_ret, cb); } } +# ifdef OPENSSL_FIPS +int FIPS_dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, + const unsigned char *seed_in, size_t seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb) +{ + return dsa_builtin_paramgen(ret, bits, qbits, + evpmd, seed_in, seed_len, + counter_ret, h_ret, cb); +} +# endif + int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, unsigned char *seed_out, + size_t seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok = 0; unsigned char seed[SHA256_DIGEST_LENGTH]; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + size_t qsize = qbits >> 3; + BN_CTX *ctx = NULL; + +# ifdef OPENSSL_FIPS + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (FIPS_module_mode() && + (bits != 1024 || qbits != 160) && + (bits != 2048 || qbits != 224) && + (bits != 2048 || qbits != 256) && (bits != 3072 || qbits != 256)) { + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_INVALID); + goto err; + } +# endif + if (seed_len && (seed_len < (size_t)qsize)) + seed_in = NULL; /* seed buffer too small -- ignore */ + if (seed_len > sizeof(seed)) + seed_len = sizeof(seed); /* App. 2.2 of FIPS PUB 186 allows larger SEED, + * but our internal buffers are restricted to 256 bits*/ + if (seed_in != NULL) + memcpy(seed, seed_in, seed_len); + else + seed_len = 0; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + if (!FIPS_dsa_generate_pq(ctx, bits, qbits, evpmd, + seed, seed_len, &p, &q, counter_ret, cb)) + goto err; + + if (!FIPS_dsa_generate_g(ctx, p, q, &g, h_ret, cb)) + goto err; + + ok = 1; + err: + if (ok) { + if (ret->p) { + BN_free(ret->p); + ret->p = NULL; + } + if (ret->q) { + BN_free(ret->q); + ret->q = NULL; + } + if (ret->g) { + BN_free(ret->g); + ret->g = NULL; + } + 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; + } + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +# ifndef OPENSSL_FIPS +static +# endif +int FIPS_dsa_generate_pq(BN_CTX *ctx, size_t bits, size_t qbits, + const EVP_MD *evpmd, unsigned char *seed, + int seed_len, BIGNUM **p_ret, BIGNUM **q_ret, + int *counter_ret, BN_GENCB *cb) +{ + int ok = 0; unsigned char md[SHA256_DIGEST_LENGTH]; - unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH]; BIGNUM *r0, *W, *X, *c, *test; - BIGNUM *g = NULL, *q = NULL, *p = NULL; - BN_MONT_CTX *mont = NULL; - int i, k, n = 0, m = 0, qsize = qbits >> 3; + BIGNUM *q = NULL, *p = NULL; + int i, k, b, n = 0, m = 0, qsize = qbits >> 3; int counter = 0; int r = 0; - BN_CTX *ctx = NULL; - unsigned int h = 2; if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && qsize != SHA256_DIGEST_LENGTH) /* invalid q size */ return 0; - if (evpmd == NULL) - /* use SHA1 as default */ + if (evpmd == NULL) { + if (qbits <= 160) evpmd = EVP_sha1(); + else if (qbits <= 224) + evpmd = EVP_sha224(); + else + evpmd = EVP_sha256(); + } 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 < (size_t)qsize)) - seed_in = NULL; /* seed buffer too small -- ignore */ - if (seed_len > (size_t)qsize) - seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger - * SEED, but our internal buffers are - * restricted to 160 bits */ - if (seed_in != NULL) - memcpy(seed, seed_in, seed_len); - - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - - if ((ctx = BN_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); + *q_ret = q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); - p = BN_CTX_get(ctx); + *p_ret = p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); if (!BN_lshift(test, BN_value_one(), bits - 1)) goto err; + /* step 3 n = \lceil bits / qbits \rceil - 1 */ + n = (bits + qbits - 1) / qbits - 1; + /* step 4 b = bits - 1 - n * qbits */ + b = bits - 1 - n * qbits; + for (;;) { for (;;) { /* find q */ int seed_is_random; - /* step 1 */ + /* step 5 generate seed */ if (!BN_GENCB_call(cb, 0, m++)) goto err; - if (!seed_len || !seed_in) { + if (!seed_len) { if (RAND_pseudo_bytes(seed, qsize) < 0) goto err; seed_is_random = 1; @@ -206,29 +284,18 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, * be bad */ } memcpy(buf, seed, qsize); - memcpy(buf2, seed, qsize); - /* precompute "SEED + 1" for step 7: */ - for (i = qsize - 1; i >= 0; i--) { - buf[i]++; - if (buf[i] != 0) - break; - } - /* step 2 */ + /* step 6 U = hash(seed) */ if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) goto err; - if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) - goto err; - for (i = 0; i < qsize; i++) - md[i] ^= buf2[i]; - /* step 3 */ + /* step 7 q = 2^(qbits-1) + U + 1 - (U mod 2) */ md[0] |= 0x80; md[qsize - 1] |= 0x01; if (!BN_bin2bn(md, qsize, q)) goto err; - /* step 4 */ + /* step 8 test for prime (64 round of Rabin-Miller) */ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb); if (r > 0) @@ -236,8 +303,6 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, if (r != 0) goto err; - /* do a callback call */ - /* step 5 */ } if (!BN_GENCB_call(cb, 2, 0)) @@ -245,19 +310,16 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, if (!BN_GENCB_call(cb, 3, 0)) goto err; - /* step 6 */ + /* step 11 */ counter = 0; - /* "offset = 2" */ - - n = (bits - 1) / 160; + /* "offset = 1" */ for (;;) { if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) goto err; - /* step 7 */ + /* step 11.1, 11.2 obtain W */ BN_zero(W); - /* now 'buf' contains "SEED + offset - 1" */ for (k = 0; k <= n; k++) { /* * obtain "SEED + offset + k" by incrementing: @@ -271,36 +333,37 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) goto err; - /* step 8 */ if (!BN_bin2bn(md, qsize, r0)) goto err; - if (!BN_lshift(r0, r0, (qsize << 3) * k)) + if (k == n) + BN_mask_bits(r0, b); + if (!BN_lshift(r0, r0, qbits * k)) goto err; if (!BN_add(W, W, r0)) goto err; } - /* more of step 8 */ - if (!BN_mask_bits(W, bits - 1)) - goto err; + /* step 11.3 X = W + 2^(L-1) */ if (!BN_copy(X, W)) goto err; if (!BN_add(X, X, test)) goto err; - /* step 9 */ + /* step 11.4 c = X mod 2*q */ if (!BN_lshift1(r0, q)) goto err; if (!BN_mod(c, X, r0, ctx)) goto err; + + /* step 11.5 p = X - (c - 1) */ if (!BN_sub(r0, c, BN_value_one())) goto err; if (!BN_sub(p, X, r0)) goto err; - /* step 10 */ + /* step 11.6 */ if (BN_cmp(p, test) >= 0) { - /* step 11 */ + /* step 11.7 */ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); if (r > 0) goto end; /* found it */ @@ -308,12 +371,12 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, goto err; } - /* step 13 */ + /* step 11.9 */ counter++; /* "offset = offset + n + 1" */ - /* step 14 */ - if (counter >= 4096) + /* step 12 */ + if (counter >= 4 * bits) break; } } @@ -321,7 +384,33 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, if (!BN_GENCB_call(cb, 2, 1)) goto err; - /* We now need to generate g */ + ok = 1; + err: + if (ok) { + if (counter_ret != NULL) + *counter_ret = counter; + } + return ok; +} + +# ifndef OPENSSL_FIPS +static +# endif +int FIPS_dsa_generate_g(BN_CTX *ctx, BIGNUM *p, BIGNUM *q, + BIGNUM **g_ret, unsigned long *h_ret, BN_GENCB *cb) +{ + int ok = 0; + BIGNUM *r0, *test, *g = NULL; + BN_MONT_CTX *mont; + unsigned int h = 2; + + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + + r0 = BN_CTX_get(ctx); + *g_ret = g = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + /* Set r0=(p-1)/q */ if (!BN_sub(test, p, BN_value_one())) goto err; @@ -350,46 +439,14 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, 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 (counter_ret != NULL) - *counter_ret = counter; if (h_ret != NULL) *h_ret = h; - if (seed_out) - memcpy(seed_out, seed, qsize); - } - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; } -# ifdef OPENSSL_FIPS -# undef fips_dsa_builtin_paramgen2 -extern int fips_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, - const unsigned char *seed_in, - size_t seed_len, int idx, - unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); -# endif - /* * This is a parameter generation algorithm for the DSA2 algorithm as * described in FIPS 186-3. @@ -415,14 +472,6 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, EVP_MD_CTX mctx; unsigned int h = 2; -# ifdef OPENSSL_FIPS - - if (FIPS_mode()) - return fips_dsa_builtin_paramgen2(ret, L, N, evpmd, - seed_in, seed_len, idx, - seed_out, counter_ret, h_ret, cb); -# endif - EVP_MD_CTX_init(&mctx); if (evpmd == NULL) { diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index e8c8d2e..e1307b0 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -66,6 +66,34 @@ # ifdef OPENSSL_FIPS # include <openssl/fips.h> +# include <openssl/evp.h> + +static int fips_check_dsa(DSA *dsa) +{ + EVP_PKEY *pk; + unsigned char tbs[] = "DSA Pairwise Check Data"; + int ret = 0; + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_set1_DSA(pk, dsa); + + if (fips_pkey_signature_test(pk, tbs, -1, NULL, 0, NULL, 0, NULL)) + ret = 1; + + err: + if (ret == 0) { + FIPSerr(FIPS_F_FIPS_CHECK_DSA, FIPS_R_PAIRWISE_TEST_FAILED); + fips_set_selftest_fail(); + } + + if (pk) + EVP_PKEY_free(pk); + + return ret; +} + # endif static int dsa_builtin_keygen(DSA *dsa); @@ -81,10 +109,6 @@ int DSA_generate_key(DSA *dsa) # endif if (dsa->meth->dsa_keygen) return dsa->meth->dsa_keygen(dsa); -# ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dsa_generate_key(dsa); -# endif return dsa_builtin_keygen(dsa); } @@ -94,6 +118,14 @@ static int dsa_builtin_keygen(DSA *dsa) BN_CTX *ctx = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; +# ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { + DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } +# endif + if ((ctx = BN_CTX_new()) == NULL) goto err; @@ -131,6 +163,13 @@ static int dsa_builtin_keygen(DSA *dsa) dsa->priv_key = priv_key; dsa->pub_key = pub_key; +# ifdef OPENSSL_FIPS + if (FIPS_mode() && !fips_check_dsa(dsa)) { + dsa->pub_key = NULL; + dsa->priv_key = NULL; + goto err; + } +# endif ok = 1; err: diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index eb9d21d..13b3491 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -86,14 +86,7 @@ void DSA_set_default_method(const DSA_METHOD *meth) const DSA_METHOD *DSA_get_default_method(void) { if (!default_DSA_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dsa_openssl(); - else - return DSA_OpenSSL(); -#else default_DSA_method = DSA_OpenSSL(); -#endif } return default_DSA_method; } diff --git a/crypto/dsa/dsa_locl.h b/crypto/dsa/dsa_locl.h index 9c23c3e..f4f54fc 100644 --- a/crypto/dsa/dsa_locl.h +++ b/crypto/dsa/dsa_locl.h @@ -56,7 +56,7 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, unsigned char *seed_out, + size_t seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index efc4f1b..12c4a06 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -65,6 +65,9 @@ #include <openssl/dsa.h> #include <openssl/rand.h> #include <openssl/asn1.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, @@ -83,7 +86,7 @@ static DSA_METHOD openssl_dsa_meth = { NULL, /* dsa_bn_mod_exp, */ dsa_init, dsa_finish, - 0, + DSA_FLAG_FIPS_METHOD, NULL, NULL, NULL @@ -140,6 +143,19 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) DSA_SIG *ret = NULL; int noredo = 0; +#ifdef OPENSSL_FIPS + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_DSA_DO_SIGN, FIPS_R_FIPS_SELFTEST_FAILED); + return NULL; + } + + if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL); + return NULL; + } +#endif + BN_init(&m); BN_init(&xr); @@ -330,6 +346,18 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE); return -1; } +#ifdef OPENSSL_FIPS + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_DSA_DO_VERIFY, FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } +#endif if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE); @@ -410,6 +438,9 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, static int dsa_init(DSA *dsa) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif dsa->flags |= DSA_FLAG_CACHE_MONT_P; return (1); } diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c index 42b8bb0..5c22962 100644 --- a/crypto/dsa/dsa_pmeth.c +++ b/crypto/dsa/dsa_pmeth.c @@ -253,7 +253,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) if (!dsa) return 0; ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, - NULL, 0, NULL, NULL, NULL, pcb); + NULL, 0, NULL, NULL, pcb); if (ret) EVP_PKEY_assign_DSA(pkey, dsa); else diff --git a/crypto/dsa/dsatest.c b/crypto/dsa/dsatest.c index 8a224a8..a71973b 100644 --- a/crypto/dsa/dsatest.c +++ b/crypto/dsa/dsatest.c @@ -100,36 +100,41 @@ static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg); * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 */ static unsigned char seed[20] = { - 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b, 0x40, - 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3, + 0x02, 0x47, 0x11, 0x92, 0x11, 0x88, 0xC8, 0xFB, 0xAF, 0x48, 0x4C, 0x62, + 0xDF, 0xA5, 0xBE, 0xA0, 0xA4, 0x3C, 0x56, 0xE3, }; static unsigned char out_p[] = { - 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, - 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb, - 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7, - 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, - 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, - 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac, - 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2, - 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91, + 0xAC, 0xCB, 0x1E, 0x63, 0x60, 0x69, 0x0C, 0xFB, 0x06, 0x19, 0x68, 0x3E, + 0xA5, 0x01, 0x5A, 0xA2, 0x15, 0x5C, 0xE2, 0x99, 0x2D, 0xD5, 0x30, 0x99, + 0x7E, 0x5F, 0x8D, 0xE2, 0xF7, 0xC6, 0x2E, 0x8D, 0xA3, 0x9F, 0x58, 0xAD, + 0xD6, 0xA9, 0x7D, 0x0E, 0x0D, 0x95, 0x53, 0xA6, 0x71, 0x3A, 0xDE, 0xAB, + 0xAC, 0xE9, 0xF4, 0x36, 0x55, 0x9E, 0xB9, 0xD6, 0x93, 0xBF, 0xF3, 0x18, + 0x1C, 0x14, 0x7B, 0xA5, 0x42, 0x2E, 0xCD, 0x00, 0xEB, 0x35, 0x3B, 0x1B, + 0xA8, 0x51, 0xBB, 0xE1, 0x58, 0x42, 0x85, 0x84, 0x22, 0xA7, 0x97, 0x5E, + 0x99, 0x6F, 0x38, 0x20, 0xBD, 0x9D, 0xB6, 0xD9, 0x33, 0x37, 0x2A, 0xFD, + 0xBB, 0xD4, 0xBC, 0x0C, 0x2A, 0x67, 0xCB, 0x9F, 0xBB, 0xDF, 0xF9, 0x93, + 0xAA, 0xD6, 0xF0, 0xD6, 0x95, 0x0B, 0x5D, 0x65, 0x14, 0xD0, 0x18, 0x9D, + 0xC6, 0xAF, 0xF0, 0xC6, 0x37, 0x7C, 0xF3, 0x5F, }; static unsigned char out_q[] = { - 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, - 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e, - 0xda, 0xce, 0x91, 0x5f, + 0xE3, 0x8E, 0x5E, 0x6D, 0xBF, 0x2B, 0x79, 0xF8, 0xC5, 0x4B, 0x89, 0x8B, + 0xBA, 0x2D, 0x91, 0xC3, 0x6C, 0x80, 0xAC, 0x87, }; static unsigned char out_g[] = { - 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, - 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00, - 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb, - 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, - 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, - 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c, - 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c, - 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02, + 0x42, 0x4A, 0x04, 0x4E, 0x79, 0xB4, 0x99, 0x7F, 0xFD, 0x58, 0x36, 0x2C, + 0x1B, 0x5F, 0x18, 0x7E, 0x0D, 0xCC, 0xAB, 0x81, 0xC9, 0x5D, 0x10, 0xCE, + 0x4E, 0x80, 0x7E, 0x58, 0xB4, 0x34, 0x3F, 0xA7, 0x45, 0xC7, 0xAA, 0x36, + 0x24, 0x42, 0xA9, 0x3B, 0xE8, 0x0E, 0x04, 0x02, 0x2D, 0xFB, 0xA6, 0x13, + 0xB9, 0xB5, 0x15, 0xA5, 0x56, 0x07, 0x35, 0xE4, 0x03, 0xB6, 0x79, 0x7C, + 0x62, 0xDD, 0xDF, 0x3F, 0x71, 0x3A, 0x9D, 0x8B, 0xC4, 0xF6, 0xE7, 0x1D, + 0x52, 0xA8, 0xA9, 0x43, 0x1D, 0x33, 0x51, 0x88, 0x39, 0xBD, 0x73, 0xE9, + 0x5F, 0xBE, 0x82, 0x49, 0x27, 0xE6, 0xB5, 0x53, 0xC1, 0x38, 0xAC, 0x2F, + 0x6D, 0x97, 0x6C, 0xEB, 0x67, 0xC1, 0x5F, 0x67, 0xF8, 0x35, 0x05, 0x5E, + 0xD5, 0x68, 0x80, 0xAA, 0x96, 0xCA, 0x0B, 0x8A, 0xE6, 0xF1, 0xB1, 0x41, + 0xC6, 0x75, 0x94, 0x0A, 0x0A, 0x2A, 0xFA, 0x29, }; static const unsigned char str1[] = "12345678901234567890"; @@ -162,7 +167,7 @@ int main(int argc, char **argv) BIO_printf(bio_err, "test generation of DSA parameters\n"); BN_GENCB_set(&cb, dsa_cb, bio_err); - if (((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512, + if (((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 1024, seed, 20, &counter, &h, &cb)) @@ -176,8 +181,8 @@ int main(int argc, char **argv) BIO_printf(bio_err, "\ncounter=%d h=%ld\n", counter, h); DSA_print(bio_err, dsa, 0); - if (counter != 105) { - BIO_printf(bio_err, "counter should be 105\n"); + if (counter != 239) { + BIO_printf(bio_err, "counter should be 239\n"); goto end; } if (h != 2) { diff --git a/crypto/engine/eng_all.c b/crypto/engine/eng_all.c index 48ad0d2..7dcdd30 100644 --- a/crypto/engine/eng_all.c +++ b/crypto/engine/eng_all.c @@ -59,11 +59,25 @@ #include "cryptlib.h" #include "eng_int.h" +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif void ENGINE_load_builtin_engines(void) { /* Some ENGINEs need this */ OPENSSL_cpuid_setup(); +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if (FIPS_mode()) { + /* We allow loading dynamic engine as a third party + engine might be FIPS validated. + User is disallowed to load non-validated engines + by security policy. */ + ENGINE_load_dynamic(); + return; + } +#endif #if 0 /* * There's no longer any need for an "openssl" ENGINE unless, one day, it diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c index 280e584..9a903d8 100644 --- a/crypto/evp/c_allc.c +++ b/crypto/evp/c_allc.c @@ -65,6 +65,10 @@ void OpenSSL_add_all_ciphers(void) { +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if (!FIPS_mode()) { +#endif #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cfb()); EVP_add_cipher(EVP_des_cfb1()); @@ -238,4 +242,64 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256"); EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256"); #endif +#ifdef OPENSSL_FIPS + } else { +# ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_ede_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb()); + + EVP_add_cipher(EVP_des_ede_ofb()); + EVP_add_cipher(EVP_des_ede3_ofb()); + + EVP_add_cipher(EVP_des_ede_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); + EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3"); + EVP_add_cipher_alias(SN_des_ede3_cbc, "des3"); + + EVP_add_cipher(EVP_des_ede()); + EVP_add_cipher(EVP_des_ede3()); +# endif + +# ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_ecb()); + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_128_cfb()); + EVP_add_cipher(EVP_aes_128_cfb1()); + EVP_add_cipher(EVP_aes_128_cfb8()); + EVP_add_cipher(EVP_aes_128_ofb()); + EVP_add_cipher(EVP_aes_128_ctr()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_128_xts()); + EVP_add_cipher(EVP_aes_128_ccm()); + EVP_add_cipher(EVP_aes_128_wrap()); + EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); + EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); + EVP_add_cipher(EVP_aes_192_ecb()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_192_cfb()); + EVP_add_cipher(EVP_aes_192_cfb1()); + EVP_add_cipher(EVP_aes_192_cfb8()); + EVP_add_cipher(EVP_aes_192_ofb()); + EVP_add_cipher(EVP_aes_192_ctr()); + EVP_add_cipher(EVP_aes_192_gcm()); + EVP_add_cipher(EVP_aes_192_ccm()); + EVP_add_cipher(EVP_aes_192_wrap()); + EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); + EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); + EVP_add_cipher(EVP_aes_256_ecb()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_256_cfb()); + EVP_add_cipher(EVP_aes_256_cfb1()); + EVP_add_cipher(EVP_aes_256_cfb8()); + EVP_add_cipher(EVP_aes_256_ofb()); + EVP_add_cipher(EVP_aes_256_ctr()); + EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_256_xts()); + EVP_add_cipher(EVP_aes_256_ccm()); + EVP_add_cipher(EVP_aes_256_wrap()); + EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); + EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); +# endif + } +#endif } diff --git a/crypto/evp/c_alld.c b/crypto/evp/c_alld.c index fdbe3ee..61745a5 100644 --- a/crypto/evp/c_alld.c +++ b/crypto/evp/c_alld.c @@ -64,51 +64,81 @@ void OpenSSL_add_all_digests(void) { +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if (!FIPS_mode()) { +#endif #ifndef OPENSSL_NO_MD4 - EVP_add_digest(EVP_md4()); + EVP_add_digest(EVP_md4()); #endif #ifndef OPENSSL_NO_MD5 - EVP_add_digest(EVP_md5()); - EVP_add_digest_alias(SN_md5, "ssl2-md5"); - EVP_add_digest_alias(SN_md5, "ssl3-md5"); + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); #endif #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) - EVP_add_digest(EVP_sha()); + EVP_add_digest(EVP_sha()); # ifndef OPENSSL_NO_DSA - EVP_add_digest(EVP_dss()); + EVP_add_digest(EVP_dss()); # endif #endif #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) - EVP_add_digest(EVP_sha1()); - EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); - EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); + EVP_add_digest(EVP_sha1()); + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); # ifndef OPENSSL_NO_DSA - EVP_add_digest(EVP_dss1()); - EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); - EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); - EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); + EVP_add_digest(EVP_dss1()); + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); # endif # ifndef OPENSSL_NO_ECDSA - EVP_add_digest(EVP_ecdsa()); + EVP_add_digest(EVP_ecdsa()); # endif #endif #if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) - EVP_add_digest(EVP_mdc2()); + EVP_add_digest(EVP_mdc2()); #endif #ifndef OPENSSL_NO_RIPEMD - EVP_add_digest(EVP_ripemd160()); - EVP_add_digest_alias(SN_ripemd160, "ripemd"); - EVP_add_digest_alias(SN_ripemd160, "rmd160"); + EVP_add_digest(EVP_ripemd160()); + EVP_add_digest_alias(SN_ripemd160, "ripemd"); + EVP_add_digest_alias(SN_ripemd160, "rmd160"); #endif #ifndef OPENSSL_NO_SHA256 - EVP_add_digest(EVP_sha224()); - EVP_add_digest(EVP_sha256()); + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); #endif #ifndef OPENSSL_NO_SHA512 - EVP_add_digest(EVP_sha384()); - EVP_add_digest(EVP_sha512()); + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); #endif #ifndef OPENSSL_NO_WHIRLPOOL - EVP_add_digest(EVP_whirlpool()); + EVP_add_digest(EVP_whirlpool()); +#endif +#ifdef OPENSSL_FIPS + } else { +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_digest(EVP_sha1()); + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); +# ifndef OPENSSL_NO_DSA + EVP_add_digest(EVP_dss1()); + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); +# endif +# ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +# endif +# endif +# ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +# endif +# ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +# endif + } #endif } diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 5b642b2..1203a4c 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -143,18 +143,55 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) return EVP_DigestInit_ex(ctx, type, NULL); } +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_MD_CTX *ctx) +{ + FIPS_ERROR_IGNORED("Digest init"); + return 0; +} + +static int bad_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + FIPS_ERROR_IGNORED("Digest update"); + return 0; +} + +static int bad_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + FIPS_ERROR_IGNORED("Digest Final"); + return 0; +} + +static const EVP_MD bad_md = { + 0, + 0, + 0, + 0, + bad_init, + bad_update, + bad_final, + NULL, + NULL, + NULL, + 0, + {0, 0, 0, 0}, +}; + +#endif + int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); #ifdef OPENSSL_FIPS - /* If FIPS mode switch to approved implementation if possible */ - if (FIPS_mode()) { - const EVP_MD *fipsmd; - if (type) { - fipsmd = evp_get_fips_md(type); - if (fipsmd) - type = fipsmd; - } + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_EVP_DIGESTINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED); + ctx->digest = &bad_md; + return 0; } #endif #ifndef OPENSSL_NO_ENGINE @@ -216,6 +253,16 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) OPENSSL_free(ctx->md_data); ctx->md_data = NULL; } +#ifdef OPENSSL_FIPS + if (FIPS_mode()) { + if (!(type->flags & EVP_MD_FLAG_FIPS) + && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); + ctx->digest = &bad_md; + return 0; + } + } +#endif ctx->digest = type; if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { ctx->update = type->update; @@ -238,25 +285,15 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) } if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) return 1; -#ifdef OPENSSL_FIPS - if (FIPS_mode()) { - if (FIPS_digestinit(ctx, type)) - return 1; - OPENSSL_free(ctx->md_data); - ctx->md_data = NULL; - return 0; - } -#endif return ctx->digest->init(ctx); } int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) { #ifdef OPENSSL_FIPS - return FIPS_digestupdate(ctx, data, count); -#else - return ctx->update(ctx, data, count); + FIPS_selftest_check(); #endif + return ctx->update(ctx, data, count); } /* The caller can assume that this removes any secret data from the context */ @@ -271,11 +308,11 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) /* The caller can assume that this removes any secret data from the context */ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { -#ifdef OPENSSL_FIPS - return FIPS_digestfinal(ctx, md, size); -#else int ret; +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret = ctx->digest->final(ctx, md); if (size != NULL) @@ -286,7 +323,6 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) } memset(ctx->md_data, 0, ctx->digest->ctx_size); return ret; -#endif } int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) @@ -375,7 +411,6 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) /* This call frees resources associated with the context */ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { -#ifndef OPENSSL_FIPS /* * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because * sometimes only copies of the context are ever finalised. @@ -388,7 +423,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); OPENSSL_free(ctx->md_data); } -#endif if (ctx->pctx) EVP_PKEY_CTX_free(ctx->pctx); #ifndef OPENSSL_NO_ENGINE @@ -399,9 +433,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) */ ENGINE_finish(ctx->engine); #endif -#ifdef OPENSSL_FIPS - FIPS_md_ctx_cleanup(ctx); -#endif memset(ctx, '\0', sizeof *ctx); return 1; diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index 1734a82..b0ada06 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -60,9 +60,6 @@ # include "modes_lcl.h" # include <openssl/rand.h> -# undef EVP_CIPH_FLAG_FIPS -# define EVP_CIPH_FLAG_FIPS 0 - typedef struct { union { double align; @@ -1159,6 +1156,11 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_GCM_SET_IVLEN: if (arg <= 0) return 0; +# ifdef OPENSSL_FIPS + if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) + && arg < 12) + return 0; +# endif /* Allocate memory for IV if needed */ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { if (gctx->iv != c->iv) @@ -1727,6 +1729,14 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 0; if (!out || !in || len < AES_BLOCK_SIZE) return 0; +# ifdef OPENSSL_FIPS + /* Requirement of SP800-38E */ + if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && + (len > (1UL << 20) * 16)) { + EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); + return 0; + } +# endif if (xctx->stream) (*xctx->stream) (in, out, len, xctx->xts.key1, xctx->xts.key2, ctx->iv); diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c index 0e910d6..1636fc7 100644 --- a/crypto/evp/e_des3.c +++ b/crypto/evp/e_des3.c @@ -65,10 +65,6 @@ # include <openssl/des.h> # include <openssl/rand.h> -/* Block use of implementations in FIPS mode */ -# undef EVP_CIPH_FLAG_FIPS -# define EVP_CIPH_FLAG_FIPS 0 - typedef struct { union { double align; diff --git a/crypto/evp/e_null.c b/crypto/evp/e_null.c index 599fcb8..be9ff3d 100644 --- a/crypto/evp/e_null.c +++ b/crypto/evp/e_null.c @@ -68,7 +68,7 @@ static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static const EVP_CIPHER n_cipher = { NID_undef, 1, 0, 0, - 0, + EVP_CIPH_FLAG_FIPS, null_init_key, null_cipher, NULL, diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 3fac2df..5f38034 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -122,6 +122,10 @@ extern "C" { #endif +# ifdef OPENSSL_FIPS +# include <openssl/fips.h> +# endif + /* * Type needs to be a bit field Sub-type needs to be for variations on the * method, as in, can it do arbitrary encryption.... @@ -285,11 +289,6 @@ struct env_md_ctx_st { * cleaned */ # define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data * in EVP_MD_CTX_cleanup */ -/* - * FIPS and pad options are ignored in 1.0.0, definitions are here so we - * don't accidentally reuse the values for other purposes. - */ - # define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS * digest in FIPS mode */ @@ -302,6 +301,10 @@ struct env_md_ctx_st { # define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ # define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ # define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ +# define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \ + ((ctx->flags>>16) &0xFFFF) /* seed length */ +# define EVP_MD_CTX_FLAG_PSS_MDLEN 0xFFFF/* salt len same as digest */ +# define EVP_MD_CTX_FLAG_PSS_MREC 0xFFFE/* salt max or auto recovered */ # define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ @@ -363,15 +366,15 @@ struct evp_cipher_st { /* cipher handles random key generation */ # define EVP_CIPH_RAND_KEY 0x200 /* cipher has its own additional copying logic */ -# define EVP_CIPH_CUSTOM_COPY 0x400 +# define EVP_CIPH_CUSTOM_COPY 0x4000 /* Allow use default ASN1 get/set iv */ # define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 /* Buffer length in bits not bytes: CFB1 mode only */ # define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 /* Note if suitable for use in FIPS mode */ -# define EVP_CIPH_FLAG_FIPS 0x4000 +# define EVP_CIPH_FLAG_FIPS 0x400 /* Allow non FIPS cipher in FIPS mode */ -# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x800 /* * Cipher handles any and all padding logic as well as finalisation. */ diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 7d7be24..976c1b2 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -69,16 +69,73 @@ #endif #include "evp_locl.h" -#ifdef OPENSSL_FIPS -# define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl) -#else -# define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl) -#endif +#define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl) const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT; +#ifdef OPENSSL_FIPS + +/* The purpose of these is to trap programs that attempt to use non FIPS + * algorithms in FIPS mode and ignore the errors. + */ + +static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + FIPS_ERROR_IGNORED("Cipher init"); + return 0; +} + +static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + FIPS_ERROR_IGNORED("Cipher update"); + return 0; +} + +/* NB: no cleanup because it is allowed after failed init */ + +static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) +{ + FIPS_ERROR_IGNORED("Cipher set_asn1"); + return 0; +} + +static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ) +{ + FIPS_ERROR_IGNORED("Cipher get_asn1"); + return 0; +} + +static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + FIPS_ERROR_IGNORED("Cipher ctrl"); + return 0; +} + +static const EVP_CIPHER bad_cipher = { + 0, + 0, + 0, + 0, + 0, + bad_init, + bad_do_cipher, + NULL, + 0, + bad_set_asn1, + bad_get_asn1, + bad_ctrl, + NULL +}; + +#endif + void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); /* ctx->cipher=NULL; */ } @@ -110,6 +167,13 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, enc = 1; ctx->encrypt = enc; } +#ifdef OPENSSL_FIPS + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_EVP_CIPHERINIT_EX, FIPS_R_FIPS_SELFTEST_FAILED); + ctx->cipher = &bad_cipher; + return 0; + } +#endif #ifndef OPENSSL_NO_ENGINE /* * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so @@ -168,16 +232,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->engine = NULL; #endif -#ifdef OPENSSL_FIPS - if (FIPS_mode()) { - const EVP_CIPHER *fcipher; - if (cipher) - fcipher = evp_get_fips_cipher(cipher); - if (fcipher) - cipher = fcipher; - return FIPS_cipherinit(ctx, cipher, key, iv, enc); - } -#endif ctx->cipher = cipher; if (ctx->cipher->ctx_size) { ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); @@ -204,10 +258,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, #ifndef OPENSSL_NO_ENGINE skip_to_init: #endif -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_cipherinit(ctx, cipher, key, iv, enc); -#endif /* we assume block size is a power of 2 in *cryptUpdate */ OPENSSL_assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 @@ -253,6 +303,19 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, break; } } +#ifdef OPENSSL_FIPS + /* After 'key' is set no further parameters changes are permissible. + * So only check for non FIPS enabling at this point. + */ + if (key && FIPS_mode()) { + if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS) + & !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS); + ctx->cipher = &bad_cipher; + return 0; + } + } +#endif if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { if (!ctx->cipher->init(ctx, key, iv, enc)) @@ -554,7 +617,6 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { -#ifndef OPENSSL_FIPS if (c->cipher != NULL) { if (c->cipher->cleanup && !c->cipher->cleanup(c)) return 0; @@ -564,7 +626,6 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) } if (c->cipher_data) OPENSSL_free(c->cipher_data); -#endif #ifndef OPENSSL_NO_ENGINE if (c->engine) /* @@ -573,9 +634,6 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) */ ENGINE_finish(c->engine); #endif -#ifdef OPENSSL_FIPS - FIPS_cipher_ctx_cleanup(c); -#endif memset(c, 0, sizeof(EVP_CIPHER_CTX)); return 1; } diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 7e0bab9..da41dd3 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -60,10 +60,6 @@ #include "cryptlib.h" #include <openssl/evp.h> #include <openssl/objects.h> -#ifdef OPENSSL_FIPS -# include <openssl/fips.h> -# include "evp_locl.h" -#endif int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) { @@ -224,6 +220,9 @@ int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { +#ifdef OPENSSL_FIPS + FIPS_selftest_check(); +#endif return ctx->cipher->do_cipher(ctx, out, in, inl); } @@ -234,22 +233,12 @@ const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) { -#ifdef OPENSSL_FIPS - const EVP_CIPHER *fcipher; - fcipher = evp_get_fips_cipher(cipher); - if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS) - return cipher->flags | EVP_CIPH_FLAG_FIPS; -#endif return cipher->flags; } unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) { -#ifdef OPENSSL_FIPS - return EVP_CIPHER_flags(ctx->cipher); -#else return ctx->cipher->flags; -#endif } void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) @@ -316,40 +305,8 @@ int EVP_MD_size(const EVP_MD *md) return md->md_size; } -#ifdef OPENSSL_FIPS - -const EVP_MD *evp_get_fips_md(const EVP_MD *md) -{ - int nid = EVP_MD_type(md); - if (nid == NID_dsa) - return FIPS_evp_dss1(); - else if (nid == NID_dsaWithSHA) - return FIPS_evp_dss(); - else if (nid == NID_ecdsa_with_SHA1) - return FIPS_evp_ecdsa(); - else - return FIPS_get_digestbynid(nid); -} - -const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher) -{ - int nid = cipher->nid; - if (nid == NID_undef) - return FIPS_evp_enc_null(); - else - return FIPS_get_cipherbynid(nid); -} - -#endif - unsigned long EVP_MD_flags(const EVP_MD *md) { -#ifdef OPENSSL_FIPS - const EVP_MD *fmd; - fmd = evp_get_fips_md(md); - if (fmd && fmd->flags & EVP_MD_FLAG_FIPS) - return md->flags | EVP_MD_FLAG_FIPS; -#endif return md->flags; } diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h index 2bb709a..b6fecde 100644 --- a/crypto/evp/evp_locl.h +++ b/crypto/evp/evp_locl.h @@ -258,10 +258,8 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ - 0, cipher##_init_key, NULL, \ - EVP_CIPHER_set_asn1_iv, \ - EVP_CIPHER_get_asn1_iv, \ - NULL) + EVP_CIPH_FLAG_DEFAULT_ASN1, \ + cipher##_init_key, NULL, NULL, NULL, NULL) struct evp_pkey_ctx_st { /* Method associated with this operation */ @@ -355,11 +353,6 @@ const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher); # define MD2_Init private_MD2_Init # define MDC2_Init private_MDC2_Init # define SHA_Init private_SHA_Init -# define SHA1_Init private_SHA1_Init -# define SHA224_Init private_SHA224_Init -# define SHA256_Init private_SHA256_Init -# define SHA384_Init private_SHA384_Init -# define SHA512_Init private_SHA512_Init # define BF_set_key private_BF_set_key # define CAST_set_key private_CAST_set_key @@ -367,7 +360,6 @@ const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher); # define SEED_set_key private_SEED_set_key # define RC2_set_key private_RC2_set_key # define RC4_set_key private_RC4_set_key -# define DES_set_key_unchecked private_DES_set_key_unchecked # define Camellia_set_key private_Camellia_set_key #endif diff --git a/crypto/evp/m_dss.c b/crypto/evp/m_dss.c index 1478448..c048831 100644 --- a/crypto/evp/m_dss.c +++ b/crypto/evp/m_dss.c @@ -86,7 +86,7 @@ static const EVP_MD dsa_md = { NID_dsaWithSHA, NID_dsaWithSHA, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, + EVP_MD_FLAG_PKEY_DIGEST | EVP_MD_FLAG_FIPS, init, update, final, diff --git a/crypto/evp/m_dss1.c b/crypto/evp/m_dss1.c index e36fabf..cfc15f5 100644 --- a/crypto/evp/m_dss1.c +++ b/crypto/evp/m_dss1.c @@ -87,7 +87,7 @@ static const EVP_MD dss1_md = { NID_dsa, NID_dsaWithSHA1, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, + EVP_MD_FLAG_PKEY_DIGEST | EVP_MD_FLAG_FIPS, init, update, final, diff --git a/crypto/evp/m_md2.c b/crypto/evp/m_md2.c index 3c4cd7b..379aa2f 100644 --- a/crypto/evp/m_md2.c +++ b/crypto/evp/m_md2.c @@ -68,6 +68,7 @@ # ifndef OPENSSL_NO_RSA # include <openssl/rsa.h> # endif +# include "evp_locl.h" static int init(EVP_MD_CTX *ctx) { diff --git a/crypto/evp/m_sha1.c b/crypto/evp/m_sha1.c index a74e6b7..f1dd284 100644 --- a/crypto/evp/m_sha1.c +++ b/crypto/evp/m_sha1.c @@ -87,7 +87,8 @@ static const EVP_MD sha1_md = { NID_sha1, NID_sha1WithRSAEncryption, SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT | + EVP_MD_FLAG_FIPS, init, update, final, @@ -134,7 +135,8 @@ static const EVP_MD sha224_md = { NID_sha224, NID_sha224WithRSAEncryption, SHA224_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT | + EVP_MD_FLAG_FIPS, init224, update256, final256, @@ -154,7 +156,8 @@ static const EVP_MD sha256_md = { NID_sha256, NID_sha256WithRSAEncryption, SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT | + EVP_MD_FLAG_FIPS, init256, update256, final256, @@ -197,7 +200,8 @@ static const EVP_MD sha384_md = { NID_sha384, NID_sha384WithRSAEncryption, SHA384_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT | + EVP_MD_FLAG_FIPS, init384, update512, final512, @@ -217,7 +221,8 @@ static const EVP_MD sha512_md = { NID_sha512, NID_sha512WithRSAEncryption, SHA512_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT | + EVP_MD_FLAG_FIPS, init512, update512, final512, diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c index 1b9ba06..0a95123 100644 --- a/crypto/evp/p_sign.c +++ b/crypto/evp/p_sign.c @@ -61,6 +61,7 @@ #include <openssl/evp.h> #include <openssl/objects.h> #include <openssl/x509.h> +#include <openssl/rsa.h> #ifdef undef void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) @@ -101,6 +102,22 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, goto err; if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931) + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0) + goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) { + int saltlen; + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= + 0) + goto err; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + } if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) goto err; *siglen = sltmp; diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c index 65e1e21..477b1b0 100644 --- a/crypto/evp/p_verify.c +++ b/crypto/evp/p_verify.c @@ -61,6 +61,7 @@ #include <openssl/evp.h> #include <openssl/objects.h> #include <openssl/x509.h> +#include <openssl/rsa.h> int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey) @@ -87,6 +88,22 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, goto err; if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_X931) + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_X931_PADDING) <= 0) + goto err; + if (ctx->flags & EVP_MD_CTX_FLAG_PAD_PSS) { + int saltlen; + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= + 0) + goto err; + saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(ctx); + if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN) + saltlen = -1; + else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC) + saltlen = -2; + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + } i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); err: EVP_PKEY_CTX_free(pkctx); diff --git a/crypto/fips/Makefile b/crypto/fips/Makefile new file mode 100644 index 0000000..b997426 --- /dev/null +++ b/crypto/fips/Makefile @@ -0,0 +1,341 @@ +# +# OpenSSL/crypto/fips/Makefile +# + +DIR= fips +TOP= ../.. +CC= cc +INCLUDES= +CFLAG=-g +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=fips_test_suite.c fips_randtest.c +APPS= + +PROGRAM= fips_standalone_hmac +EXE= $(PROGRAM)$(EXE_EXT) + +LIB=$(TOP)/libcrypto.a +LIBSRC=fips_aes_selftest.c fips_des_selftest.c fips_hmac_selftest.c fips_rand_selftest.c \ + fips_rsa_selftest.c fips_sha_selftest.c fips.c fips_dsa_selftest.c fips_rand.c \ + fips_rsa_x931g.c fips_post.c fips_drbg_ctr.c fips_drbg_hash.c fips_drbg_hmac.c \ + fips_drbg_lib.c fips_drbg_rand.c fips_drbg_selftest.c fips_rand_lib.c \ + fips_cmac_selftest.c fips_enc.c fips_md.c + +LIBOBJ=fips_aes_selftest.o fips_des_selftest.o fips_hmac_selftest.o fips_rand_selftest.o \ + fips_rsa_selftest.o fips_sha_selftest.o fips.o fips_dsa_selftest.o fips_rand.o \ + fips_rsa_x931g.o fips_post.o fips_drbg_ctr.o fips_drbg_hash.o fips_drbg_hmac.o \ + fips_drbg_lib.o fips_drbg_rand.o fips_drbg_selftest.o fips_rand_lib.o \ + fips_cmac_selftest.o fips_enc.o fips_md.o + +LIBCRYPTO=-L.. -lcrypto + +SRC= $(LIBSRC) fips_standalone_hmac.c + +EXHEADER= fips.h fips_rand.h +HEADER= $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib exe + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +exe: $(EXE) + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + @headerlist="$(EXHEADER)"; for i in $$headerlist ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +$(EXE): $(PROGRAM).o + FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha256.o; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../sha/$$i" ; done; \ + for i in $(CPUID_OBJ); do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../$$i" ; done; \ + $(CC) -o $@ $(CFLAGS) $(PROGRAM).o $$FIPS_SHA_ASM + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fips.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h +fips.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +fips.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +fips.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +fips.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips.o: ../../include/openssl/symhacks.h fips.c fips_locl.h +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_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_drbg_ctr.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_ctr.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_ctr.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h +fips_drbg_ctr.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_drbg_ctr.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h +fips_drbg_ctr.o: ../../include/openssl/objects.h +fips_drbg_ctr.o: ../../include/openssl/opensslconf.h +fips_drbg_ctr.o: ../../include/openssl/opensslv.h +fips_drbg_ctr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_ctr.o: ../../include/openssl/safestack.h +fips_drbg_ctr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_drbg_ctr.o: fips_drbg_ctr.c fips_rand_lcl.h +fips_drbg_hash.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_hash.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_hash.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h +fips_drbg_hash.o: ../../include/openssl/fips.h +fips_drbg_hash.o: ../../include/openssl/fips_rand.h +fips_drbg_hash.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h +fips_drbg_hash.o: ../../include/openssl/objects.h +fips_drbg_hash.o: ../../include/openssl/opensslconf.h +fips_drbg_hash.o: ../../include/openssl/opensslv.h +fips_drbg_hash.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_hash.o: ../../include/openssl/safestack.h +fips_drbg_hash.o: ../../include/openssl/stack.h +fips_drbg_hash.o: ../../include/openssl/symhacks.h fips_drbg_hash.c +fips_drbg_hash.o: fips_rand_lcl.h +fips_drbg_hmac.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_hmac.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/evp.h +fips_drbg_hmac.o: ../../include/openssl/fips.h +fips_drbg_hmac.o: ../../include/openssl/fips_rand.h +fips_drbg_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h +fips_drbg_hmac.o: ../../include/openssl/objects.h +fips_drbg_hmac.o: ../../include/openssl/opensslconf.h +fips_drbg_hmac.o: ../../include/openssl/opensslv.h +fips_drbg_hmac.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_hmac.o: ../../include/openssl/safestack.h +fips_drbg_hmac.o: ../../include/openssl/stack.h +fips_drbg_hmac.o: ../../include/openssl/symhacks.h fips_drbg_hmac.c +fips_drbg_hmac.o: fips_rand_lcl.h +fips_drbg_lib.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_lib.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_drbg_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_drbg_lib.o: ../../include/openssl/fips_rand.h ../../include/openssl/hmac.h +fips_drbg_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +fips_drbg_lib.o: ../../include/openssl/objects.h +fips_drbg_lib.o: ../../include/openssl/opensslconf.h +fips_drbg_lib.o: ../../include/openssl/opensslv.h +fips_drbg_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_lib.o: ../../include/openssl/safestack.h +fips_drbg_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_drbg_lib.o: fips_drbg_lib.c fips_locl.h fips_rand_lcl.h +fips_drbg_rand.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_drbg_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_drbg_rand.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_drbg_rand.o: ../../include/openssl/fips_rand.h +fips_drbg_rand.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_drbg_rand.o: ../../include/openssl/obj_mac.h +fips_drbg_rand.o: ../../include/openssl/objects.h +fips_drbg_rand.o: ../../include/openssl/opensslconf.h +fips_drbg_rand.o: ../../include/openssl/opensslv.h +fips_drbg_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_drbg_rand.o: ../../include/openssl/safestack.h +fips_drbg_rand.o: ../../include/openssl/stack.h +fips_drbg_rand.o: ../../include/openssl/symhacks.h fips_drbg_rand.c +fips_drbg_rand.o: fips_rand_lcl.h +fips_drbg_selftest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_drbg_selftest.o: ../../include/openssl/bio.h +fips_drbg_selftest.o: ../../include/openssl/crypto.h +fips_drbg_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_drbg_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_drbg_selftest.o: ../../include/openssl/fips_rand.h +fips_drbg_selftest.o: ../../include/openssl/hmac.h +fips_drbg_selftest.o: ../../include/openssl/lhash.h +fips_drbg_selftest.o: ../../include/openssl/obj_mac.h +fips_drbg_selftest.o: ../../include/openssl/objects.h +fips_drbg_selftest.o: ../../include/openssl/opensslconf.h +fips_drbg_selftest.o: ../../include/openssl/opensslv.h +fips_drbg_selftest.o: ../../include/openssl/ossl_typ.h +fips_drbg_selftest.o: ../../include/openssl/rand.h +fips_drbg_selftest.o: ../../include/openssl/safestack.h +fips_drbg_selftest.o: ../../include/openssl/stack.h +fips_drbg_selftest.o: ../../include/openssl/symhacks.h fips_drbg_selftest.c +fips_drbg_selftest.o: fips_drbg_selftest.h fips_locl.h fips_rand_lcl.h +fips_dsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_dsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +fips_dsa_selftest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_dsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_dsa_selftest.o: ../../include/openssl/fips.h ../../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_selftest.o: fips_locl.h +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_post.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_post.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +fips_post.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +fips_post.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_post.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_post.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_post.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +fips_post.o: ../../include/openssl/opensslconf.h +fips_post.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +fips_post.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h +fips_post.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +fips_post.o: ../../include/openssl/symhacks.h fips_locl.h fips_post.c +fips_rand.o: ../../e_os.h ../../include/openssl/aes.h +fips_rand.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_rand.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +fips_rand.o: ../../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: fips_locl.h fips_rand.c +fips_rand_lib.o: ../../e_os.h ../../include/openssl/aes.h +fips_rand_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +fips_rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h +fips_rand_lib.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h +fips_rand_lib.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h +fips_rand_lib.o: ../../include/openssl/obj_mac.h +fips_rand_lib.o: ../../include/openssl/objects.h +fips_rand_lib.o: ../../include/openssl/opensslconf.h +fips_rand_lib.o: ../../include/openssl/opensslv.h +fips_rand_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +fips_rand_lib.o: ../../include/openssl/safestack.h +fips_rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +fips_rand_lib.o: fips_rand_lib.c +fips_rand_selftest.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h +fips_rand_selftest.o: ../../include/openssl/bio.h +fips_rand_selftest.o: ../../include/openssl/crypto.h +fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_rand_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_rand_selftest.o: ../../include/openssl/fips_rand.h +fips_rand_selftest.o: ../../include/openssl/hmac.h +fips_rand_selftest.o: ../../include/openssl/lhash.h +fips_rand_selftest.o: ../../include/openssl/obj_mac.h +fips_rand_selftest.o: ../../include/openssl/objects.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_locl.h +fips_rand_selftest.o: fips_rand_selftest.c +fips_rsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_rsa_selftest.o: ../../include/openssl/bn.h ../../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_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_sha_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +fips_sha_selftest.o: ../../include/openssl/crypto.h +fips_sha_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +fips_sha_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h +fips_sha_selftest.o: ../../include/openssl/lhash.h +fips_sha_selftest.o: ../../include/openssl/obj_mac.h +fips_sha_selftest.o: ../../include/openssl/objects.h +fips_sha_selftest.o: ../../include/openssl/opensslconf.h +fips_sha_selftest.o: ../../include/openssl/opensslv.h +fips_sha_selftest.o: ../../include/openssl/ossl_typ.h +fips_sha_selftest.o: ../../include/openssl/safestack.h +fips_sha_selftest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +fips_sha_selftest.o: ../../include/openssl/symhacks.h fips_sha_selftest.c diff --git a/crypto/fips/fips.c b/crypto/fips/fips.c new file mode 100644 index 0000000..29621c9 --- /dev/null +++ b/crypto/fips/fips.c @@ -0,0 +1,483 @@ +/* ==================================================================== + * 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. + * + */ + +#define _GNU_SOURCE + +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/bio.h> +#include <openssl/hmac.h> +#include <openssl/rsa.h> +#include <string.h> +#include <limits.h> +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +# include <openssl/fips.h> + +# ifndef PATH_MAX +# define PATH_MAX 1024 +# endif + +static int fips_selftest_fail = 0; +static int fips_mode = 0; +static int fips_started = 0; + +static int fips_is_owning_thread(void); +static int fips_set_owning_thread(void); +static int fips_clear_owning_thread(void); + +# define fips_w_lock() CRYPTO_w_lock(CRYPTO_LOCK_FIPS) +# define fips_w_unlock() CRYPTO_w_unlock(CRYPTO_LOCK_FIPS) +# define fips_r_lock() CRYPTO_r_lock(CRYPTO_LOCK_FIPS) +# define fips_r_unlock() CRYPTO_r_unlock(CRYPTO_LOCK_FIPS) + +static void fips_set_mode(int onoff) +{ + int owning_thread = fips_is_owning_thread(); + + if (fips_started) { + if (!owning_thread) + fips_w_lock(); + fips_mode = onoff; + if (!owning_thread) + fips_w_unlock(); + } +} + +int FIPS_module_mode(void) +{ + int ret = 0; + int owning_thread = fips_is_owning_thread(); + + if (fips_started) { + if (!owning_thread) + fips_r_lock(); + ret = fips_mode; + if (!owning_thread) + fips_r_unlock(); + } + return ret; +} + +int FIPS_selftest_failed(void) +{ + int ret = 0; + if (fips_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; +} + +/* we implement what libfipscheck does ourselves */ + +static int +get_library_path(const char *libname, const char *symbolname, char *path, + size_t pathlen) +{ + Dl_info info; + void *dl, *sym; + int rv = -1; + + dl = dlopen(libname, RTLD_LAZY); + if (dl == NULL) { + return -1; + } + + sym = dlsym(dl, symbolname); + + if (sym != NULL && dladdr(sym, &info)) { + strncpy(path, info.dli_fname, pathlen - 1); + path[pathlen - 1] = '\0'; + rv = 0; + } + + dlclose(dl); + + return rv; +} + +static const char conv[] = "0123456789abcdef"; + +static char *bin2hex(void *buf, size_t len) +{ + char *hex, *p; + unsigned char *src = buf; + + hex = malloc(len * 2 + 1); + if (hex == NULL) + return NULL; + + p = hex; + + while (len > 0) { + unsigned c; + + c = *src; + src++; + + *p = conv[c >> 4]; + ++p; + *p = conv[c & 0x0f]; + ++p; + --len; + } + *p = '\0'; + return hex; +} + +# define HMAC_PREFIX "." +# define HMAC_SUFFIX ".hmac" +# define READ_BUFFER_LENGTH 16384 + +static char *make_hmac_path(const char *origpath) +{ + char *path, *p; + const char *fn; + + path = + malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath)); + if (path == NULL) { + return NULL; + } + + fn = strrchr(origpath, '/'); + if (fn == NULL) { + fn = origpath; + } else { + ++fn; + } + + strncpy(path, origpath, fn - origpath); + p = path + (fn - origpath); + p = stpcpy(p, HMAC_PREFIX); + p = stpcpy(p, fn); + p = stpcpy(p, HMAC_SUFFIX); + + return path; +} + +static const char hmackey[] = "orboDeJITITejsirpADONivirpUkvarP"; + +static int compute_file_hmac(const char *path, void **buf, size_t *hmaclen) +{ + FILE *f = NULL; + int rv = -1; + unsigned char rbuf[READ_BUFFER_LENGTH]; + size_t len; + unsigned int hlen; + HMAC_CTX c; + + HMAC_CTX_init(&c); + + f = fopen(path, "r"); + + if (f == NULL) { + goto end; + } + + HMAC_Init(&c, hmackey, sizeof(hmackey) - 1, EVP_sha256()); + + while ((len = fread(rbuf, 1, sizeof(rbuf), f)) != 0) { + HMAC_Update(&c, rbuf, len); + } + + len = sizeof(rbuf); + /* reuse rbuf for hmac */ + HMAC_Final(&c, rbuf, &hlen); + + *buf = malloc(hlen); + if (*buf == NULL) { + goto end; + } + + *hmaclen = hlen; + + memcpy(*buf, rbuf, hlen); + + rv = 0; + end: + HMAC_CTX_cleanup(&c); + + if (f) + fclose(f); + + return rv; +} + +static int FIPSCHECK_verify(const char *libname, const char *symbolname) +{ + char path[PATH_MAX + 1]; + int rv; + FILE *hf; + char *hmacpath, *p; + char *hmac = NULL; + size_t n; + + rv = get_library_path(libname, symbolname, path, sizeof(path)); + + if (rv < 0) + return 0; + + hmacpath = make_hmac_path(path); + if (hmacpath == NULL) + return 0; + + hf = fopen(hmacpath, "r"); + if (hf == NULL) { + free(hmacpath); + return 0; + } + + if (getline(&hmac, &n, hf) > 0) { + void *buf; + size_t hmaclen; + char *hex; + + if ((p = strchr(hmac, '\n')) != NULL) + *p = '\0'; + + if (compute_file_hmac(path, &buf, &hmaclen) < 0) { + rv = -4; + goto end; + } + + if ((hex = bin2hex(buf, hmaclen)) == NULL) { + free(buf); + rv = -5; + goto end; + } + + if (strcmp(hex, hmac) != 0) { + rv = -1; + } + free(buf); + free(hex); + } else { + rv = -1; + } + + end: + free(hmac); + free(hmacpath); + fclose(hf); + + if (rv < 0) + return 0; + + /* check successful */ + return 1; +} + +int FIPS_module_mode_set(int onoff, const char *auth) +{ + int ret = 0; + + fips_w_lock(); + fips_started = 1; + fips_set_owning_thread(); + + if (onoff) { + + fips_selftest_fail = 0; + + /* Don't go into FIPS mode twice, just so we can do automagic + seeding */ + if (FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_FIPS_MODE_ALREADY_SET); + fips_selftest_fail = 1; + ret = 0; + goto end; + } +# ifdef OPENSSL_IA32_SSE2 + { + extern unsigned int OPENSSL_ia32cap_P[2]; + if ((OPENSSL_ia32cap_P[0] & (1 << 25 | 1 << 26)) != + (1 << 25 | 1 << 26)) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_UNSUPPORTED_PLATFORM); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + OPENSSL_ia32cap_P[0] |= (1 << 28); /* set "shared cache" */ + OPENSSL_ia32cap_P[1] &= ~(1 << (60 - 32)); /* clear AVX */ + } +# endif + + if (!FIPSCHECK_verify + ("libcrypto.so." SHLIB_VERSION_NUMBER, "FIPS_mode_set")) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + + if (!FIPSCHECK_verify + ("libssl.so." SHLIB_VERSION_NUMBER, "SSL_CTX_new")) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + + if (FIPS_selftest()) + fips_set_mode(onoff); + else { + fips_selftest_fail = 1; + ret = 0; + goto end; + } + ret = 1; + goto end; + } + fips_set_mode(0); + fips_selftest_fail = 0; + ret = 1; + end: + fips_clear_owning_thread(); + fips_w_unlock(); + return ret; +} + +static CRYPTO_THREADID fips_thread; +static int fips_thread_set = 0; + +static int fips_is_owning_thread(void) +{ + int ret = 0; + + if (fips_started) { + CRYPTO_r_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread_set) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, &fips_thread)) + ret = 1; + } + CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; +} + +int fips_set_owning_thread(void) +{ + int ret = 0; + + if (fips_started) { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (!fips_thread_set) { + CRYPTO_THREADID_current(&fips_thread); + ret = 1; + fips_thread_set = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; +} + +int fips_clear_owning_thread(void) +{ + int ret = 0; + + if (fips_started) { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread_set) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, &fips_thread)) + fips_thread_set = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; +} + +# 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/crypto/fips/fips.c.orig b/crypto/fips/fips.c.orig new file mode 100644 index 0000000..29621c9 --- /dev/null +++ b/crypto/fips/fips.c.orig @@ -0,0 +1,483 @@ +/* ==================================================================== + * 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. + * + */ + +#define _GNU_SOURCE + +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/bio.h> +#include <openssl/hmac.h> +#include <openssl/rsa.h> +#include <string.h> +#include <limits.h> +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +# include <openssl/fips.h> + +# ifndef PATH_MAX +# define PATH_MAX 1024 +# endif + +static int fips_selftest_fail = 0; +static int fips_mode = 0; +static int fips_started = 0; + +static int fips_is_owning_thread(void); +static int fips_set_owning_thread(void); +static int fips_clear_owning_thread(void); + +# define fips_w_lock() CRYPTO_w_lock(CRYPTO_LOCK_FIPS) +# define fips_w_unlock() CRYPTO_w_unlock(CRYPTO_LOCK_FIPS) +# define fips_r_lock() CRYPTO_r_lock(CRYPTO_LOCK_FIPS) +# define fips_r_unlock() CRYPTO_r_unlock(CRYPTO_LOCK_FIPS) + +static void fips_set_mode(int onoff) +{ + int owning_thread = fips_is_owning_thread(); + + if (fips_started) { + if (!owning_thread) + fips_w_lock(); + fips_mode = onoff; + if (!owning_thread) + fips_w_unlock(); + } +} + +int FIPS_module_mode(void) +{ + int ret = 0; + int owning_thread = fips_is_owning_thread(); + + if (fips_started) { + if (!owning_thread) + fips_r_lock(); + ret = fips_mode; + if (!owning_thread) + fips_r_unlock(); + } + return ret; +} + +int FIPS_selftest_failed(void) +{ + int ret = 0; + if (fips_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; +} + +/* we implement what libfipscheck does ourselves */ + +static int +get_library_path(const char *libname, const char *symbolname, char *path, + size_t pathlen) +{ + Dl_info info; + void *dl, *sym; + int rv = -1; + + dl = dlopen(libname, RTLD_LAZY); + if (dl == NULL) { + return -1; + } + + sym = dlsym(dl, symbolname); + + if (sym != NULL && dladdr(sym, &info)) { + strncpy(path, info.dli_fname, pathlen - 1); + path[pathlen - 1] = '\0'; + rv = 0; + } + + dlclose(dl); + + return rv; +} + +static const char conv[] = "0123456789abcdef"; + +static char *bin2hex(void *buf, size_t len) +{ + char *hex, *p; + unsigned char *src = buf; + + hex = malloc(len * 2 + 1); + if (hex == NULL) + return NULL; + + p = hex; + + while (len > 0) { + unsigned c; + + c = *src; + src++; + + *p = conv[c >> 4]; + ++p; + *p = conv[c & 0x0f]; + ++p; + --len; + } + *p = '\0'; + return hex; +} + +# define HMAC_PREFIX "." +# define HMAC_SUFFIX ".hmac" +# define READ_BUFFER_LENGTH 16384 + +static char *make_hmac_path(const char *origpath) +{ + char *path, *p; + const char *fn; + + path = + malloc(sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + strlen(origpath)); + if (path == NULL) { + return NULL; + } + + fn = strrchr(origpath, '/'); + if (fn == NULL) { + fn = origpath; + } else { + ++fn; + } + + strncpy(path, origpath, fn - origpath); + p = path + (fn - origpath); + p = stpcpy(p, HMAC_PREFIX); + p = stpcpy(p, fn); + p = stpcpy(p, HMAC_SUFFIX); + + return path; +} + +static const char hmackey[] = "orboDeJITITejsirpADONivirpUkvarP"; + +static int compute_file_hmac(const char *path, void **buf, size_t *hmaclen) +{ + FILE *f = NULL; + int rv = -1; + unsigned char rbuf[READ_BUFFER_LENGTH]; + size_t len; + unsigned int hlen; + HMAC_CTX c; + + HMAC_CTX_init(&c); + + f = fopen(path, "r"); + + if (f == NULL) { + goto end; + } + + HMAC_Init(&c, hmackey, sizeof(hmackey) - 1, EVP_sha256()); + + while ((len = fread(rbuf, 1, sizeof(rbuf), f)) != 0) { + HMAC_Update(&c, rbuf, len); + } + + len = sizeof(rbuf); + /* reuse rbuf for hmac */ + HMAC_Final(&c, rbuf, &hlen); + + *buf = malloc(hlen); + if (*buf == NULL) { + goto end; + } + + *hmaclen = hlen; + + memcpy(*buf, rbuf, hlen); + + rv = 0; + end: + HMAC_CTX_cleanup(&c); + + if (f) + fclose(f); + + return rv; +} + +static int FIPSCHECK_verify(const char *libname, const char *symbolname) +{ + char path[PATH_MAX + 1]; + int rv; + FILE *hf; + char *hmacpath, *p; + char *hmac = NULL; + size_t n; + + rv = get_library_path(libname, symbolname, path, sizeof(path)); + + if (rv < 0) + return 0; + + hmacpath = make_hmac_path(path); + if (hmacpath == NULL) + return 0; + + hf = fopen(hmacpath, "r"); + if (hf == NULL) { + free(hmacpath); + return 0; + } + + if (getline(&hmac, &n, hf) > 0) { + void *buf; + size_t hmaclen; + char *hex; + + if ((p = strchr(hmac, '\n')) != NULL) + *p = '\0'; + + if (compute_file_hmac(path, &buf, &hmaclen) < 0) { + rv = -4; + goto end; + } + + if ((hex = bin2hex(buf, hmaclen)) == NULL) { + free(buf); + rv = -5; + goto end; + } + + if (strcmp(hex, hmac) != 0) { + rv = -1; + } + free(buf); + free(hex); + } else { + rv = -1; + } + + end: + free(hmac); + free(hmacpath); + fclose(hf); + + if (rv < 0) + return 0; + + /* check successful */ + return 1; +} + +int FIPS_module_mode_set(int onoff, const char *auth) +{ + int ret = 0; + + fips_w_lock(); + fips_started = 1; + fips_set_owning_thread(); + + if (onoff) { + + fips_selftest_fail = 0; + + /* Don't go into FIPS mode twice, just so we can do automagic + seeding */ + if (FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_FIPS_MODE_ALREADY_SET); + fips_selftest_fail = 1; + ret = 0; + goto end; + } +# ifdef OPENSSL_IA32_SSE2 + { + extern unsigned int OPENSSL_ia32cap_P[2]; + if ((OPENSSL_ia32cap_P[0] & (1 << 25 | 1 << 26)) != + (1 << 25 | 1 << 26)) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_UNSUPPORTED_PLATFORM); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + OPENSSL_ia32cap_P[0] |= (1 << 28); /* set "shared cache" */ + OPENSSL_ia32cap_P[1] &= ~(1 << (60 - 32)); /* clear AVX */ + } +# endif + + if (!FIPSCHECK_verify + ("libcrypto.so." SHLIB_VERSION_NUMBER, "FIPS_mode_set")) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + + if (!FIPSCHECK_verify + ("libssl.so." SHLIB_VERSION_NUMBER, "SSL_CTX_new")) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } + + if (FIPS_selftest()) + fips_set_mode(onoff); + else { + fips_selftest_fail = 1; + ret = 0; + goto end; + } + ret = 1; + goto end; + } + fips_set_mode(0); + fips_selftest_fail = 0; + ret = 1; + end: + fips_clear_owning_thread(); + fips_w_unlock(); + return ret; +} + +static CRYPTO_THREADID fips_thread; +static int fips_thread_set = 0; + +static int fips_is_owning_thread(void) +{ + int ret = 0; + + if (fips_started) { + CRYPTO_r_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread_set) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, &fips_thread)) + ret = 1; + } + CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; +} + +int fips_set_owning_thread(void) +{ + int ret = 0; + + if (fips_started) { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (!fips_thread_set) { + CRYPTO_THREADID_current(&fips_thread); + ret = 1; + fips_thread_set = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; +} + +int fips_clear_owning_thread(void) +{ + int ret = 0; + + if (fips_started) { + CRYPTO_w_lock(CRYPTO_LOCK_FIPS2); + if (fips_thread_set) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, &fips_thread)) + fips_thread_set = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2); + } + return ret; +} + +# 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/crypto/fips/fips.h b/crypto/fips/fips.h new file mode 100644 index 0000000..792781e --- /dev/null +++ b/crypto/fips/fips.h @@ -0,0 +1,278 @@ +/* ==================================================================== + * 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 <openssl/opensslconf.h> +#include <openssl/crypto.h> +#include <stdarg.h> + +#ifndef OPENSSL_FIPS +# error FIPS is disabled. +#endif + +#ifdef OPENSSL_FIPS + +# ifdef __cplusplus +extern "C" { +# endif + + struct dsa_st; + struct rsa_st; + struct evp_pkey_st; + struct env_md_st; + struct env_md_ctx_st; + struct evp_cipher_st; + struct evp_cipher_ctx_st; + struct dh_method; + struct CMAC_CTX_st; + struct hmac_ctx_st; + + int FIPS_module_mode_set(int onoff, const char *auth); + int FIPS_module_mode(void); + const void *FIPS_rand_check(void); + int FIPS_selftest(void); + int FIPS_selftest_failed(void); + void FIPS_corrupt_sha1(void); + int FIPS_selftest_sha1(void); + int FIPS_selftest_sha2(void); + void FIPS_corrupt_aes(void); + int FIPS_selftest_aes_ccm(void); + int FIPS_selftest_aes_gcm(void); + int FIPS_selftest_aes_xts(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); + void FIPS_x931_stick(int onoff); + void FIPS_drbg_stick(int onoff); + int FIPS_selftest_rng(void); + int FIPS_selftest_x931(void); + int FIPS_selftest_hmac(void); + int FIPS_selftest_drbg(void); + int FIPS_selftest_drbg_all(void); + int FIPS_selftest_cmac(void); + + void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr); + +# define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \ + alg " previous FIPS forbidden algorithm error ignored"); + + 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); + + void fips_set_selftest_fail(void); + + const struct env_md_st *FIPS_get_digestbynid(int nid); + + const struct evp_cipher_st *FIPS_get_cipherbynid(int nid); + +/* 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_DH_INIT 148 +# define FIPS_F_DRBG_RESEED 162 +# define FIPS_F_DSA_BUILTIN_PARAMGEN 101 +# define FIPS_F_DSA_BUILTIN_PARAMGEN2 107 +# define FIPS_F_DSA_DO_SIGN 102 +# define FIPS_F_DSA_DO_VERIFY 103 +# define FIPS_F_ECDH_COMPUTE_KEY 163 +# define FIPS_F_ECDSA_DO_SIGN 164 +# define FIPS_F_ECDSA_DO_VERIFY 165 +# define FIPS_F_EC_KEY_GENERATE_KEY 166 +# 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_DSA_PRNG 151 +# define FIPS_F_FIPS_CHECK_EC 142 +# define FIPS_F_FIPS_CHECK_EC_PRNG 152 +# define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT 105 +# define FIPS_F_FIPS_CHECK_RSA 106 +# define FIPS_F_FIPS_CHECK_RSA_PRNG 150 +# define FIPS_F_FIPS_CIPHER 160 +# define FIPS_F_FIPS_CIPHERINIT 143 +# define FIPS_F_FIPS_CIPHER_CTX_CTRL 161 +# define FIPS_F_FIPS_DIGESTFINAL 158 +# define FIPS_F_FIPS_DIGESTINIT 128 +# define FIPS_F_FIPS_DIGESTUPDATE 159 +# define FIPS_F_FIPS_DRBG_BYTES 131 +# define FIPS_F_FIPS_DRBG_CHECK 146 +# define FIPS_F_FIPS_DRBG_CPRNG_TEST 132 +# define FIPS_F_FIPS_DRBG_ERROR_CHECK 136 +# define FIPS_F_FIPS_DRBG_GENERATE 134 +# define FIPS_F_FIPS_DRBG_INIT 135 +# define FIPS_F_FIPS_DRBG_INSTANTIATE 138 +# define FIPS_F_FIPS_DRBG_NEW 139 +# define FIPS_F_FIPS_DRBG_RESEED 140 +# define FIPS_F_FIPS_DRBG_SINGLE_KAT 141 +# define FIPS_F_FIPS_DSA_CHECK /* unused */ 107 +# define FIPS_F_FIPS_DSA_SIGN_DIGEST 154 +# define FIPS_F_FIPS_DSA_VERIFY_DIGEST 155 +# define FIPS_F_FIPS_GET_ENTROPY 147 +# define FIPS_F_FIPS_MODE_SET /* unused */ 108 +# define FIPS_F_FIPS_MODULE_MODE_SET 108 +# define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109 +# define FIPS_F_FIPS_RAND_ADD 137 +# define FIPS_F_FIPS_RAND_BYTES 122 +# define FIPS_F_FIPS_RAND_PSEUDO_BYTES 167 +# define FIPS_F_FIPS_RAND_SEED 168 +# define FIPS_F_FIPS_RAND_SET_METHOD 126 +# define FIPS_F_FIPS_RAND_STATUS 127 +# define FIPS_F_FIPS_RSA_SIGN_DIGEST 156 +# define FIPS_F_FIPS_RSA_VERIFY_DIGEST 157 +# define FIPS_F_FIPS_SELFTEST_AES 110 +# define FIPS_F_FIPS_SELFTEST_AES_CCM 145 +# define FIPS_F_FIPS_SELFTEST_AES_GCM 129 +# define FIPS_F_FIPS_SELFTEST_AES_XTS 144 +# define FIPS_F_FIPS_SELFTEST_CMAC 130 +# define FIPS_F_FIPS_SELFTEST_DES 111 +# define FIPS_F_FIPS_SELFTEST_DSA 112 +# define FIPS_F_FIPS_SELFTEST_ECDSA 133 +# define FIPS_F_FIPS_SELFTEST_HMAC 113 +# define FIPS_F_FIPS_SELFTEST_RNG /* unused */ 114 +# define FIPS_F_FIPS_SELFTEST_SHA1 115 +# define FIPS_F_FIPS_SELFTEST_X931 114 +# define FIPS_F_FIPS_SET_PRNG_KEY 153 +# define FIPS_F_HASH_FINAL 123 +# define FIPS_F_RSA_BUILTIN_KEYGEN 116 +# define FIPS_F_RSA_EAY_INIT 149 +# 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 /* unused */ 122 + +/* Reason codes. */ +# define FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED 150 +# define FIPS_R_ADDITIONAL_INPUT_TOO_LONG 125 +# define FIPS_R_ALREADY_INSTANTIATED 134 +# define FIPS_R_AUTHENTICATION_FAILURE 151 +# define FIPS_R_CANNOT_READ_EXE /* unused */ 103 +# define FIPS_R_CANNOT_READ_EXE_DIGEST /* unused */ 104 +# define FIPS_R_CONTRADICTING_EVIDENCE 114 +# define FIPS_R_DRBG_NOT_INITIALISED 152 +# define FIPS_R_DRBG_STUCK 103 +# define FIPS_R_ENTROPY_ERROR_UNDETECTED 104 +# define FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED 105 +# define FIPS_R_ENTROPY_SOURCE_STUCK 142 +# define FIPS_R_ERROR_INITIALISING_DRBG 115 +# define FIPS_R_ERROR_INSTANTIATING_DRBG 127 +# define FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT 124 +# define FIPS_R_ERROR_RETRIEVING_ENTROPY 122 +# define FIPS_R_ERROR_RETRIEVING_NONCE 140 +# define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH /* unused */ 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_FUNCTION_ERROR 116 +# define FIPS_R_GENERATE_ERROR 137 +# define FIPS_R_GENERATE_ERROR_UNDETECTED 118 +# define FIPS_R_INSTANTIATE_ERROR 119 +# define FIPS_R_INSUFFICIENT_SECURITY_STRENGTH 120 +# define FIPS_R_INTERNAL_ERROR 121 +# define FIPS_R_INVALID_KEY_LENGTH 109 +# define FIPS_R_INVALID_PARAMETERS 144 +# define FIPS_R_IN_ERROR_STATE 123 +# define FIPS_R_KEY_TOO_SHORT 108 +# define FIPS_R_NONCE_ERROR_UNDETECTED 149 +# define FIPS_R_NON_FIPS_METHOD 100 +# define FIPS_R_NOPR_TEST1_FAILURE 145 +# define FIPS_R_NOPR_TEST2_FAILURE 146 +# define FIPS_R_NOT_INSTANTIATED 126 +# define FIPS_R_PAIRWISE_TEST_FAILED 107 +# define FIPS_R_PERSONALISATION_ERROR_UNDETECTED 128 +# define FIPS_R_PERSONALISATION_STRING_TOO_LONG 129 +# define FIPS_R_PRNG_STRENGTH_TOO_LOW 143 +# define FIPS_R_PR_TEST1_FAILURE 147 +# define FIPS_R_PR_TEST2_FAILURE 148 +# define FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED 130 +# define FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG 131 +# define FIPS_R_RESEED_COUNTER_ERROR 132 +# define FIPS_R_RESEED_ERROR 133 +# define FIPS_R_RSA_DECRYPT_ERROR /* unused */ 115 +# define FIPS_R_RSA_ENCRYPT_ERROR /* unused */ 116 +# define FIPS_R_SELFTEST_FAILED 101 +# define FIPS_R_SELFTEST_FAILURE 135 +# define FIPS_R_STRENGTH_ERROR_UNDETECTED 136 +# define FIPS_R_TEST_FAILURE 117 +# define FIPS_R_UNINSTANTIATE_ERROR 141 +# define FIPS_R_UNINSTANTIATE_ZEROISE_ERROR 138 +# define FIPS_R_UNSUPPORTED_DRBG_TYPE 139 +# define FIPS_R_UNSUPPORTED_PLATFORM 113 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/crypto/fips/fips_aes_selftest.c b/crypto/fips/fips_aes_selftest.c new file mode 100644 index 0000000..612ca5e --- /dev/null +++ b/crypto/fips/fips_aes_selftest.c @@ -0,0 +1,365 @@ +/* ==================================================================== + * 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 <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif +#include <openssl/evp.h> + +#ifdef OPENSSL_FIPS +static const struct { + const unsigned char key[16]; + const unsigned char plaintext[16]; + const 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},},}; + +static int corrupt_aes; + +void FIPS_corrupt_aes() +{ + corrupt_aes = 1; +} + +int FIPS_selftest_aes() +{ + int n; + int ret = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + for (n = 0; n < 1; ++n) { + unsigned char key[16]; + + memcpy(key, tests[n].key, sizeof(key)); + if (corrupt_aes) + key[0]++; + if (fips_cipher_test(&ctx, EVP_aes_128_ecb(), + 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; +} + +/* AES-CCM test data from NIST public test vectors */ + +static const unsigned char ccm_key[] = { + 0xce, 0xb0, 0x09, 0xae, 0xa4, 0x45, 0x44, 0x51, 0xfe, 0xad, 0xf0, 0xe6, + 0xb3, 0x6f, 0x45, 0x55, 0x5d, 0xd0, 0x47, 0x23, 0xba, 0xa4, 0x48, 0xe8 +}; + +static const unsigned char ccm_nonce[] = { + 0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7 +}; + +static const unsigned char ccm_adata[] = { + 0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, 0xc9, 0xab, 0x25, 0xc7, + 0x5f, 0x10, 0xbd, 0xe7, 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5, + 0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4 +}; + +static const unsigned char ccm_pt[] = { + 0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, 0xe6, 0x9c, 0x2a, 0x1f, + 0x58, 0x93, 0x9d, 0xfe, 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10 +}; + +static const unsigned char ccm_ct[] = { + 0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, 0x87, 0xfd, 0x95, 0xa2, + 0x8a, 0xd3, 0x92, 0xc8, 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd +}; + +static const unsigned char ccm_tag[] = { + 0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, 0x23, 0xdc, 0x07, 0x44, + 0x14, 0xdb, 0x50, 0x6d +}; + +int FIPS_selftest_aes_ccm(void) +{ + int ret = 0; + unsigned char out[128], tag[16]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + memset(out, 0, sizeof(out)); + if (!EVP_CipherInit_ex(&ctx, EVP_aes_192_ccm(), NULL, NULL, NULL, 1)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, + sizeof(ccm_nonce), NULL)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, + sizeof(ccm_tag), NULL)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, ccm_key, ccm_nonce, 1)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, sizeof(ccm_pt)) != sizeof(ccm_pt)) + goto err; + if (EVP_Cipher(&ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, ccm_pt, sizeof(ccm_pt)) != sizeof(ccm_ct)) + goto err; + + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, 16, tag)) + goto err; + if (memcmp(tag, ccm_tag, sizeof(ccm_tag)) + || memcmp(out, ccm_ct, sizeof(ccm_ct))) + goto err; + + memset(out, 0, sizeof(out)); + + if (!EVP_CipherInit_ex(&ctx, EVP_aes_192_ccm(), NULL, NULL, NULL, 0)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, + sizeof(ccm_nonce), NULL)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, 16, tag)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, ccm_key, ccm_nonce, 0)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, sizeof(ccm_ct)) != sizeof(ccm_ct)) + goto err; + if (EVP_Cipher(&ctx, NULL, ccm_adata, sizeof(ccm_adata)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, ccm_ct, sizeof(ccm_ct)) != sizeof(ccm_pt)) + goto err; + + if (memcmp(out, ccm_pt, sizeof(ccm_pt))) + goto err; + + ret = 1; + + err: + EVP_CIPHER_CTX_cleanup(&ctx); + + if (ret == 0) { + FIPSerr(FIPS_F_FIPS_SELFTEST_AES_CCM, FIPS_R_SELFTEST_FAILED); + return 0; + } else + return ret; + +} + +/* AES-GCM test data from NIST public test vectors */ + +static const unsigned char gcm_key[] = { + 0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66, + 0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69, + 0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f +}; + +static const unsigned char gcm_iv[] = { + 0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84 +}; + +static const unsigned char gcm_pt[] = { + 0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea, + 0xcc, 0x2b, 0xf2, 0xa5 +}; + +static const unsigned char gcm_aad[] = { + 0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43, + 0x7f, 0xec, 0x78, 0xde +}; + +static const unsigned char gcm_ct[] = { + 0xf7, 0x26, 0x44, 0x13, 0xa8, 0x4c, 0x0e, 0x7c, 0xd5, 0x36, 0x86, 0x7e, + 0xb9, 0xf2, 0x17, 0x36 +}; + +static const unsigned char gcm_tag[] = { + 0x67, 0xba, 0x05, 0x10, 0x26, 0x2a, 0xe4, 0x87, 0xd7, 0x37, 0xee, 0x62, + 0x98, 0xf7, 0x7e, 0x0c +}; + +int FIPS_selftest_aes_gcm(void) +{ + int ret = 0; + unsigned char out[128], tag[16]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + memset(out, 0, sizeof(out)); + memset(tag, 0, sizeof(tag)); + if (!EVP_CipherInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 1)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, + sizeof(gcm_iv), NULL)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, gcm_key, gcm_iv, 1)) + goto err; + if (EVP_Cipher(&ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, gcm_pt, sizeof(gcm_pt)) != sizeof(gcm_ct)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, 0) < 0) + goto err; + + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) + goto err; + + if (memcmp(tag, gcm_tag, 16) || memcmp(out, gcm_ct, 16)) + goto err; + + memset(out, 0, sizeof(out)); + + if (!EVP_CipherInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL, 0)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, + sizeof(gcm_iv), NULL)) + goto err; + if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) + goto err; + if (!EVP_CipherInit_ex(&ctx, NULL, NULL, gcm_key, gcm_iv, 0)) + goto err; + if (EVP_Cipher(&ctx, NULL, gcm_aad, sizeof(gcm_aad)) < 0) + goto err; + if (EVP_Cipher(&ctx, out, gcm_ct, sizeof(gcm_ct)) != sizeof(gcm_pt)) + goto err; + if (EVP_Cipher(&ctx, NULL, NULL, 0) < 0) + goto err; + + if (memcmp(out, gcm_pt, 16)) + goto err; + + ret = 1; + + err: + EVP_CIPHER_CTX_cleanup(&ctx); + + if (ret == 0) { + FIPSerr(FIPS_F_FIPS_SELFTEST_AES_GCM, FIPS_R_SELFTEST_FAILED); + return 0; + } else + return ret; + +} + +static const unsigned char XTS_128_key[] = { + 0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35, 0x3b, 0x2c, 0x34, 0x38, + 0x76, 0x08, 0x17, 0x62, 0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18, + 0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f +}; + +static const unsigned char XTS_128_i[] = { + 0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6, 0x6e, 0x4b, 0x92, 0x01, + 0x3e, 0x76, 0x8a, 0xd5 +}; + +static const unsigned char XTS_128_pt[] = { + 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, 0x6f, 0xb3, 0x50, 0x39, + 0x07, 0x90, 0x31, 0x1c +}; + +static const unsigned char XTS_128_ct[] = { + 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a, 0x82, 0x50, 0x81, 0xd5, + 0xbe, 0x47, 0x1c, 0x63 +}; + +static const unsigned char XTS_256_key[] = { + 0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e, 0x48, 0x01, 0xe4, 0x2f, + 0x4b, 0x09, 0x47, 0x14, 0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7, + 0x50, 0x52, 0x10, 0xbd, 0x31, 0x1a, 0x0e, 0x7c, 0xd6, 0xe1, 0x3f, 0xfd, + 0xf2, 0x41, 0x8d, 0x8d, 0x19, 0x11, 0xc0, 0x04, 0xcd, 0xa5, 0x8d, 0xa3, + 0xd6, 0x19, 0xb7, 0xe2, 0xb9, 0x14, 0x1e, 0x58, 0x31, 0x8e, 0xea, 0x39, + 0x2c, 0xf4, 0x1b, 0x08 +}; + +static const unsigned char XTS_256_i[] = { + 0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2, 0xf0, 0x42, 0x8e, 0x84, + 0xa9, 0xf8, 0x75, 0x64 +}; + +static const unsigned char XTS_256_pt[] = { + 0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1, 0xac, 0xc6, 0x47, 0xe8, + 0x10, 0xbb, 0xc3, 0x64, 0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3, + 0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e +}; + +static const unsigned char XTS_256_ct[] = { + 0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5, 0x0b, 0x37, 0xf9, 0x34, + 0xd4, 0x6a, 0x9b, 0x13, 0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a, + 0xf7, 0x93, 0xe8, 0x6f, 0x73, 0xc6, 0xd7, 0xdb +}; + +int FIPS_selftest_aes_xts() +{ + int ret = 1; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (fips_cipher_test(&ctx, EVP_aes_128_xts(), + XTS_128_key, XTS_128_i, XTS_128_pt, XTS_128_ct, + sizeof(XTS_128_pt)) <= 0) + ret = 0; + + if (fips_cipher_test(&ctx, EVP_aes_256_xts(), + XTS_256_key, XTS_256_i, XTS_256_pt, XTS_256_ct, + sizeof(XTS_256_pt)) <= 0) + ret = 0; + + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + FIPSerr(FIPS_F_FIPS_SELFTEST_AES_XTS, FIPS_R_SELFTEST_FAILED); + return ret; +} + +#endif diff --git a/crypto/fips/fips_cmac_selftest.c b/crypto/fips/fips_cmac_selftest.c new file mode 100644 index 0000000..9e75ec9 --- /dev/null +++ b/crypto/fips/fips_cmac_selftest.c @@ -0,0 +1,156 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <string.h> +#include <openssl/err.h> +#include <openssl/fips.h> +#include <openssl/cmac.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS +typedef struct { + int nid; + const unsigned char key[EVP_MAX_KEY_LENGTH]; + size_t keysize; + const unsigned char msg[64]; + size_t msgsize; + const unsigned char mac[32]; + size_t macsize; +} CMAC_KAT; + +/* from http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf */ +static const CMAC_KAT vector[] = { + {NID_aes_128_cbc, /* Count = 32 from CMACGenAES128.txt */ + {0x77, 0xa7, 0x7f, 0xaf, 0x29, 0x0c, 0x1f, 0xa3, + 0x0c, 0x68, 0x3d, 0xf1, 0x6b, 0xa7, 0xa7, 0x7b,}, 128, + {0x02, 0x06, 0x83, 0xe1, 0xf0, 0x39, 0x2f, 0x4c, + 0xac, 0x54, 0x31, 0x8b, 0x60, 0x29, 0x25, 0x9e, + 0x9c, 0x55, 0x3d, 0xbc, 0x4b, 0x6a, 0xd9, 0x98, + 0xe6, 0x4d, 0x58, 0xe4, 0xe7, 0xdc, 0x2e, 0x13,}, 256, + {0xfb, 0xfe, 0xa4, 0x1b,}, 32}, + {NID_aes_192_cbc, /* Count = 23 from CMACGenAES192.txt */ + {0x7b, 0x32, 0x39, 0x13, 0x69, 0xaa, 0x4c, 0xa9, + 0x75, 0x58, 0x09, 0x5b, 0xe3, 0xc3, 0xec, 0x86, + 0x2b, 0xd0, 0x57, 0xce, 0xf1, 0xe3, 0x2d, 0x62,}, 192, + {0x0}, 0, + {0xe4, 0xd9, 0x34, 0x0b, 0x03, 0xe6, 0x7d, 0xef, + 0xd4, 0x96, 0x9c, 0xc1, 0xed, 0x37, 0x35, 0xe6,}, 128, + }, + {NID_aes_256_cbc, /* Count = 33 from CMACGenAES256.txt */ + {0x0b, 0x12, 0x2a, 0xc8, 0xf3, 0x4e, 0xd1, 0xfe, + 0x08, 0x2a, 0x36, 0x25, 0xd1, 0x57, 0x56, 0x14, + 0x54, 0x16, 0x7a, 0xc1, 0x45, 0xa1, 0x0b, 0xbf, + 0x77, 0xc6, 0xa7, 0x05, 0x96, 0xd5, 0x74, 0xf1,}, 256, + {0x49, 0x8b, 0x53, 0xfd, 0xec, 0x87, 0xed, 0xcb, + 0xf0, 0x70, 0x97, 0xdc, 0xcd, 0xe9, 0x3a, 0x08, + 0x4b, 0xad, 0x75, 0x01, 0xa2, 0x24, 0xe3, 0x88, + 0xdf, 0x34, 0x9c, 0xe1, 0x89, 0x59, 0xfe, 0x84, + 0x85, 0xf8, 0xad, 0x15, 0x37, 0xf0, 0xd8, 0x96, + 0xea, 0x73, 0xbe, 0xdc, 0x72, 0x14, 0x71, 0x3f,}, 384, + {0xf6, 0x2c, 0x46, 0x32, 0x9b,}, 40, + }, + {NID_des_ede3_cbc, /* Count = 41 from CMACGenTDES3.req */ + {0x89, 0xbc, 0xd9, 0x52, 0xa8, 0xc8, 0xab, 0x37, + 0x1a, 0xf4, 0x8a, 0xc7, 0xd0, 0x70, 0x85, 0xd5, + 0xef, 0xf7, 0x02, 0xe6, 0xd6, 0x2c, 0xdc, 0x23,}, 192, + {0xfa, 0x62, 0x0c, 0x1b, 0xbe, 0x97, 0x31, 0x9e, + 0x9a, 0x0c, 0xf0, 0x49, 0x21, 0x21, 0xf7, 0xa2, + 0x0e, 0xb0, 0x8a, 0x6a, 0x70, 0x9d, 0xcb, 0xd0, + 0x0a, 0xaf, 0x38, 0xe4, 0xf9, 0x9e, 0x75, 0x4e,}, 256, + {0x8f, 0x49, 0xa1, 0xb7, 0xd6, 0xaa, 0x22, 0x58,}, 64, + }, +}; + +int FIPS_selftest_cmac() +{ + size_t n, outlen; + unsigned char out[32]; + const EVP_CIPHER *cipher; + CMAC_CTX *ctx = CMAC_CTX_new(); + const CMAC_KAT *t; + int rv = 1; + + for (n = 0, t = vector; n < sizeof(vector) / sizeof(vector[0]); n++, t++) { + cipher = FIPS_get_cipherbynid(t->nid); + if (!cipher) { + rv = -1; + goto err; + } + if (!CMAC_Init(ctx, t->key, t->keysize / 8, cipher, 0)) { + rv = -1; + goto err; + } + if (!CMAC_Update(ctx, t->msg, t->msgsize / 8)) { + rv = -1; + goto err; + } + + if (!CMAC_Final(ctx, out, &outlen)) { + rv = -1; + goto err; + } + CMAC_CTX_cleanup(ctx); + + if (outlen < t->macsize / 8 || memcmp(out, t->mac, t->macsize / 8)) { + rv = 0; + } + } + + err: + CMAC_CTX_free(ctx); + + if (rv == -1) { + rv = 0; + } + if (!rv) + FIPSerr(FIPS_F_FIPS_SELFTEST_CMAC, FIPS_R_SELFTEST_FAILED); + + return rv; +} +#endif diff --git a/crypto/fips/fips_des_selftest.c b/crypto/fips/fips_des_selftest.c new file mode 100644 index 0000000..0743904 --- /dev/null +++ b/crypto/fips/fips_des_selftest.c @@ -0,0 +1,138 @@ +/* ==================================================================== + * 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 <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif +#include <openssl/evp.h> +#include <openssl/opensslconf.h> + +#ifdef OPENSSL_FIPS + +static const struct { + const unsigned char key[16]; + const unsigned char plaintext[8]; + const 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 const struct { + const unsigned char key[24]; + const unsigned char plaintext[8]; + const 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},},}; + +static int corrupt_des; + +void FIPS_corrupt_des() +{ + corrupt_des = 1; +} + +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) { + unsigned char plaintext[8]; + + memcpy(plaintext, tests2[n].plaintext, sizeof(plaintext)); + if (corrupt_des) + plaintext[0]++; + if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(), + tests2[n].key, NULL, + 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/crypto/fips/fips_drbg_ctr.c b/crypto/fips/fips_drbg_ctr.c new file mode 100644 index 0000000..a830b2c --- /dev/null +++ b/crypto/fips/fips_drbg_ctr.c @@ -0,0 +1,415 @@ +/* fips/rand/fips_drbg_ctr.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include <stdlib.h> +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +static void inc_128(DRBG_CTR_CTX * cctx) +{ + int i; + unsigned char c; + unsigned char *p = cctx->V + 15; + for (i = 0; i < 16; i++) { + c = *p; + c++; + *p = c; + if (c) + return; + p--; + } +} + +static void ctr_XOR(DRBG_CTR_CTX * cctx, const unsigned char *in, + size_t inlen) +{ + size_t i, n; + /* Any zero padding will have no effect on the result as we + * are XORing. So just process however much input we have. + */ + + if (!in || !inlen) + return; + + if (inlen < cctx->keylen) + n = inlen; + else + n = cctx->keylen; + + for (i = 0; i < n; i++) + cctx->K[i] ^= in[i]; + if (inlen <= cctx->keylen) + return; + + n = inlen - cctx->keylen; + /* Should never happen */ + if (n > 16) + n = 16; + for (i = 0; i < 16; i++) + cctx->V[i] ^= in[i + cctx->keylen]; +} + +/* Process a complete block using BCC algorithm of SPP 800-90 10.4.3 */ + +static void ctr_BCC_block(DRBG_CTR_CTX * cctx, unsigned char *out, + const unsigned char *in) +{ + int i; + for (i = 0; i < 16; i++) + out[i] ^= in[i]; + AES_encrypt(out, out, &cctx->df_ks); +#if 0 + fprintf(stderr, "BCC in+out\n"); + BIO_dump_fp(stderr, in, 16); + BIO_dump_fp(stderr, out, 16); +#endif +} + +/* Handle several BCC operations for as much data as we need for K and X */ +static void ctr_BCC_blocks(DRBG_CTR_CTX * cctx, const unsigned char *in) +{ + ctr_BCC_block(cctx, cctx->KX, in); + ctr_BCC_block(cctx, cctx->KX + 16, in); + if (cctx->keylen != 16) + ctr_BCC_block(cctx, cctx->KX + 32, in); +} + +/* Initialise BCC blocks: these have the value 0,1,2 in leftmost positions: + * see 10.4.2 stage 7. + */ +static void ctr_BCC_init(DRBG_CTR_CTX * cctx) +{ + memset(cctx->KX, 0, 48); + memset(cctx->bltmp, 0, 16); + ctr_BCC_block(cctx, cctx->KX, cctx->bltmp); + cctx->bltmp[3] = 1; + ctr_BCC_block(cctx, cctx->KX + 16, cctx->bltmp); + if (cctx->keylen != 16) { + cctx->bltmp[3] = 2; + ctr_BCC_block(cctx, cctx->KX + 32, cctx->bltmp); + } +} + +/* Process several blocks into BCC algorithm, some possibly partial */ +static void ctr_BCC_update(DRBG_CTR_CTX * cctx, + const unsigned char *in, size_t inlen) +{ + if (!in || !inlen) + return; + /* If we have partial block handle it first */ + if (cctx->bltmp_pos) { + size_t left = 16 - cctx->bltmp_pos; + /* If we now have a complete block process it */ + if (inlen >= left) { + memcpy(cctx->bltmp + cctx->bltmp_pos, in, left); + ctr_BCC_blocks(cctx, cctx->bltmp); + cctx->bltmp_pos = 0; + inlen -= left; + in += left; + } + } + /* Process zero or more complete blocks */ + while (inlen >= 16) { + ctr_BCC_blocks(cctx, in); + in += 16; + inlen -= 16; + } + /* Copy any remaining partial block to the temporary buffer */ + if (inlen > 0) { + memcpy(cctx->bltmp + cctx->bltmp_pos, in, inlen); + cctx->bltmp_pos += inlen; + } +} + +static void ctr_BCC_final(DRBG_CTR_CTX * cctx) +{ + if (cctx->bltmp_pos) { + memset(cctx->bltmp + cctx->bltmp_pos, 0, 16 - cctx->bltmp_pos); + ctr_BCC_blocks(cctx, cctx->bltmp); + } +} + +static void ctr_df(DRBG_CTR_CTX * cctx, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *in3, size_t in3len) +{ + size_t inlen; + unsigned char *p = cctx->bltmp; + static unsigned char c80 = 0x80; + + ctr_BCC_init(cctx); + if (!in1) + in1len = 0; + if (!in2) + in2len = 0; + if (!in3) + in3len = 0; + inlen = in1len + in2len + in3len; + /* Initialise L||N in temporary block */ + *p++ = (inlen >> 24) & 0xff; + *p++ = (inlen >> 16) & 0xff; + *p++ = (inlen >> 8) & 0xff; + *p++ = inlen & 0xff; + /* NB keylen is at most 32 bytes */ + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p = (unsigned char)((cctx->keylen + 16) & 0xff); + cctx->bltmp_pos = 8; + ctr_BCC_update(cctx, in1, in1len); + ctr_BCC_update(cctx, in2, in2len); + ctr_BCC_update(cctx, in3, in3len); + ctr_BCC_update(cctx, &c80, 1); + ctr_BCC_final(cctx); + /* Set up key K */ + AES_set_encrypt_key(cctx->KX, cctx->keylen * 8, &cctx->df_kxks); + /* X follows key K */ + AES_encrypt(cctx->KX + cctx->keylen, cctx->KX, &cctx->df_kxks); + AES_encrypt(cctx->KX, cctx->KX + 16, &cctx->df_kxks); + if (cctx->keylen != 16) + AES_encrypt(cctx->KX + 16, cctx->KX + 32, &cctx->df_kxks); +#if 0 + fprintf(stderr, "Output of ctr_df:\n"); + BIO_dump_fp(stderr, cctx->KX, cctx->keylen + 16); +#endif +} + +/* NB the no-df Update in SP800-90 specifies a constant input length + * of seedlen, however other uses of this algorithm pad the input with + * zeroes if necessary and have up to two parameters XORed together, + * handle both cases in this function instead. + */ + +static void ctr_Update(DRBG_CTX *dctx, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *nonce, size_t noncelen) +{ + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + /* ks is already setup for correct key */ + inc_128(cctx); + AES_encrypt(cctx->V, cctx->K, &cctx->ks); + /* If keylen longer than 128 bits need extra encrypt */ + if (cctx->keylen != 16) { + inc_128(cctx); + AES_encrypt(cctx->V, cctx->K + 16, &cctx->ks); + } + inc_128(cctx); + AES_encrypt(cctx->V, cctx->V, &cctx->ks); + /* If 192 bit key part of V is on end of K */ + if (cctx->keylen == 24) { + memcpy(cctx->V + 8, cctx->V, 8); + memcpy(cctx->V, cctx->K + 24, 8); + } + + if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { + /* If no input reuse existing derived value */ + if (in1 || nonce || in2) + ctr_df(cctx, in1, in1len, nonce, noncelen, in2, in2len); + /* If this a reuse input in1len != 0 */ + if (in1len) + ctr_XOR(cctx, cctx->KX, dctx->seedlen); + } else { + ctr_XOR(cctx, in1, in1len); + ctr_XOR(cctx, in2, in2len); + } + + AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks); +#if 0 + fprintf(stderr, "K+V after update is:\n"); + BIO_dump_fp(stderr, cctx->K, cctx->keylen); + BIO_dump_fp(stderr, cctx->V, 16); +#endif +} + +static int drbg_ctr_instantiate(DRBG_CTX *dctx, + const unsigned char *ent, size_t entlen, + const unsigned char *nonce, size_t noncelen, + const unsigned char *pers, size_t perslen) +{ + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + memset(cctx->K, 0, sizeof(cctx->K)); + memset(cctx->V, 0, sizeof(cctx->V)); + AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks); + ctr_Update(dctx, ent, entlen, pers, perslen, nonce, noncelen); + return 1; +} + +static int drbg_ctr_reseed(DRBG_CTX *dctx, + const unsigned char *ent, size_t entlen, + const unsigned char *adin, size_t adinlen) +{ + ctr_Update(dctx, ent, entlen, adin, adinlen, NULL, 0); + return 1; +} + +static int drbg_ctr_generate(DRBG_CTX *dctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adinlen) +{ + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + if (adin && adinlen) { + ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); + /* This means we reuse derived value */ + if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { + adin = NULL; + adinlen = 1; + } + } else + adinlen = 0; + + for (;;) { + inc_128(cctx); + if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { + AES_encrypt(cctx->V, dctx->lb, &cctx->ks); + dctx->lb_valid = 1; + continue; + } + if (outlen < 16) { + /* Use K as temp space as it will be updated */ + AES_encrypt(cctx->V, cctx->K, &cctx->ks); + if (!fips_drbg_cprng_test(dctx, cctx->K)) + return 0; + memcpy(out, cctx->K, outlen); + break; + } + AES_encrypt(cctx->V, out, &cctx->ks); + if (!fips_drbg_cprng_test(dctx, out)) + return 0; + out += 16; + outlen -= 16; + if (outlen == 0) + break; + } + + ctr_Update(dctx, adin, adinlen, NULL, 0, NULL, 0); + + return 1; + +} + +static int drbg_ctr_uninstantiate(DRBG_CTX *dctx) +{ + memset(&dctx->d.ctr, 0, sizeof(DRBG_CTR_CTX)); + return 1; +} + +int fips_drbg_ctr_init(DRBG_CTX *dctx) +{ + DRBG_CTR_CTX *cctx = &dctx->d.ctr; + + size_t keylen; + + switch (dctx->type) { + case NID_aes_128_ctr: + keylen = 16; + break; + + case NID_aes_192_ctr: + keylen = 24; + break; + + case NID_aes_256_ctr: + keylen = 32; + break; + + default: + return -2; + } + + dctx->instantiate = drbg_ctr_instantiate; + dctx->reseed = drbg_ctr_reseed; + dctx->generate = drbg_ctr_generate; + dctx->uninstantiate = drbg_ctr_uninstantiate; + + cctx->keylen = keylen; + dctx->strength = keylen * 8; + dctx->blocklength = 16; + dctx->seedlen = keylen + 16; + + if (dctx->xflags & DRBG_FLAG_CTR_USE_DF) { + /* df initialisation */ + static unsigned char df_key[32] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }; + /* Set key schedule for df_key */ + AES_set_encrypt_key(df_key, dctx->strength, &cctx->df_ks); + + dctx->min_entropy = cctx->keylen; + dctx->max_entropy = DRBG_MAX_LENGTH; + dctx->min_nonce = dctx->min_entropy / 2; + dctx->max_nonce = DRBG_MAX_LENGTH; + dctx->max_pers = DRBG_MAX_LENGTH; + dctx->max_adin = DRBG_MAX_LENGTH; + } else { + dctx->min_entropy = dctx->seedlen; + dctx->max_entropy = dctx->seedlen; + /* Nonce not used */ + dctx->min_nonce = 0; + dctx->max_nonce = 0; + dctx->max_pers = dctx->seedlen; + dctx->max_adin = dctx->seedlen; + } + + dctx->max_request = 1 << 16; + dctx->reseed_interval = 1 << 24; + + return 1; +} diff --git a/crypto/fips/fips_drbg_hash.c b/crypto/fips/fips_drbg_hash.c new file mode 100644 index 0000000..b19420a --- /dev/null +++ b/crypto/fips/fips_drbg_hash.c @@ -0,0 +1,358 @@ +/* fips/rand/fips_drbg_hash.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#define OPENSSL_FIPSAPI + +#include <stdlib.h> +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +/* This is Hash_df from SP 800-90 10.4.1 */ + +static int hash_df(DRBG_CTX *dctx, unsigned char *out, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *in3, size_t in3len, + const unsigned char *in4, size_t in4len) +{ + EVP_MD_CTX *mctx = &dctx->d.hash.mctx; + unsigned char *vtmp = dctx->d.hash.vtmp; + unsigned char tmp[6]; + /* Standard only ever needs seedlen bytes which is always less than + * maximum permitted so no need to check length. + */ + size_t outlen = dctx->seedlen; + tmp[0] = 1; + tmp[1] = ((outlen * 8) >> 24) & 0xff; + tmp[2] = ((outlen * 8) >> 16) & 0xff; + tmp[3] = ((outlen * 8) >> 8) & 0xff; + tmp[4] = (outlen * 8) & 0xff; + if (!in1) { + tmp[5] = (unsigned char)in1len; + in1 = tmp + 5; + in1len = 1; + } + for (;;) { + if (!FIPS_digestinit(mctx, dctx->d.hash.md)) + return 0; + if (!FIPS_digestupdate(mctx, tmp, 5)) + return 0; + if (in1 && !FIPS_digestupdate(mctx, in1, in1len)) + return 0; + if (in2 && !FIPS_digestupdate(mctx, in2, in2len)) + return 0; + if (in3 && !FIPS_digestupdate(mctx, in3, in3len)) + return 0; + if (in4 && !FIPS_digestupdate(mctx, in4, in4len)) + return 0; + if (outlen < dctx->blocklength) { + if (!FIPS_digestfinal(mctx, vtmp, NULL)) + return 0; + memcpy(out, vtmp, outlen); + OPENSSL_cleanse(vtmp, dctx->blocklength); + return 1; + } else if (!FIPS_digestfinal(mctx, out, NULL)) + return 0; + + outlen -= dctx->blocklength; + if (outlen == 0) + return 1; + tmp[0]++; + out += dctx->blocklength; + } +} + +/* Add an unsigned buffer to the buf value, storing the result in buf. For + * this algorithm the length of input never exceeds the seed length. + */ + +static void ctx_add_buf(DRBG_CTX *dctx, unsigned char *buf, + unsigned char *in, size_t inlen) +{ + size_t i = inlen; + const unsigned char *q; + unsigned char c, *p; + p = buf + dctx->seedlen; + q = in + inlen; + + OPENSSL_assert(i <= dctx->seedlen); + + /* Special case: zero length, just increment buffer */ + if (i) + c = 0; + else + c = 1; + + while (i) { + int r; + p--; + q--; + r = *p + *q + c; + /* Carry */ + if (r > 0xff) + c = 1; + else + c = 0; + *p = r & 0xff; + i--; + } + + i = dctx->seedlen - inlen; + + /* If not adding whole buffer handle final carries */ + if (c && i) { + do { + p--; + c = *p; + c++; + *p = c; + if (c) + return; + } while (i--); + } +} + +/* Finalise and add hash to V */ + +static int ctx_add_md(DRBG_CTX *dctx) +{ + if (!FIPS_digestfinal(&dctx->d.hash.mctx, dctx->d.hash.vtmp, NULL)) + return 0; + ctx_add_buf(dctx, dctx->d.hash.V, dctx->d.hash.vtmp, dctx->blocklength); + return 1; +} + +static int hash_gen(DRBG_CTX *dctx, unsigned char *out, size_t outlen) +{ + DRBG_HASH_CTX *hctx = &dctx->d.hash; + if (outlen == 0) + return 1; + memcpy(hctx->vtmp, hctx->V, dctx->seedlen); + for (;;) { + FIPS_digestinit(&hctx->mctx, hctx->md); + FIPS_digestupdate(&hctx->mctx, hctx->vtmp, dctx->seedlen); + if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { + FIPS_digestfinal(&hctx->mctx, dctx->lb, NULL); + dctx->lb_valid = 1; + } else if (outlen < dctx->blocklength) { + FIPS_digestfinal(&hctx->mctx, hctx->vtmp, NULL); + if (!fips_drbg_cprng_test(dctx, hctx->vtmp)) + return 0; + memcpy(out, hctx->vtmp, outlen); + return 1; + } else { + FIPS_digestfinal(&hctx->mctx, out, NULL); + if (!fips_drbg_cprng_test(dctx, out)) + return 0; + outlen -= dctx->blocklength; + if (outlen == 0) + return 1; + out += dctx->blocklength; + } + ctx_add_buf(dctx, hctx->vtmp, NULL, 0); + } +} + +static int drbg_hash_instantiate(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *nonce, size_t nonce_len, + const unsigned char *pstr, size_t pstr_len) +{ + DRBG_HASH_CTX *hctx = &dctx->d.hash; + if (!hash_df(dctx, hctx->V, + ent, ent_len, nonce, nonce_len, pstr, pstr_len, NULL, 0)) + return 0; + if (!hash_df(dctx, hctx->C, + NULL, 0, hctx->V, dctx->seedlen, NULL, 0, NULL, 0)) + return 0; + +#ifdef HASH_DRBG_TRACE + fprintf(stderr, "V+C after instantiate:\n"); + hexprint(stderr, hctx->V, dctx->seedlen); + hexprint(stderr, hctx->C, dctx->seedlen); +#endif + return 1; +} + +static int drbg_hash_reseed(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *adin, size_t adin_len) +{ + DRBG_HASH_CTX *hctx = &dctx->d.hash; + /* V about to be updated so use C as output instead */ + if (!hash_df(dctx, hctx->C, + NULL, 1, hctx->V, dctx->seedlen, + ent, ent_len, adin, adin_len)) + return 0; + memcpy(hctx->V, hctx->C, dctx->seedlen); + if (!hash_df(dctx, hctx->C, NULL, 0, + hctx->V, dctx->seedlen, NULL, 0, NULL, 0)) + return 0; +#ifdef HASH_DRBG_TRACE + fprintf(stderr, "V+C after reseed:\n"); + hexprint(stderr, hctx->V, dctx->seedlen); + hexprint(stderr, hctx->C, dctx->seedlen); +#endif + return 1; +} + +static int drbg_hash_generate(DRBG_CTX *dctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adin_len) +{ + DRBG_HASH_CTX *hctx = &dctx->d.hash; + EVP_MD_CTX *mctx = &hctx->mctx; + unsigned char tmp[4]; + if (adin && adin_len) { + tmp[0] = 2; + if (!FIPS_digestinit(mctx, hctx->md)) + return 0; + if (!EVP_DigestUpdate(mctx, tmp, 1)) + return 0; + if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen)) + return 0; + if (!EVP_DigestUpdate(mctx, adin, adin_len)) + return 0; + if (!ctx_add_md(dctx)) + return 0; + } + if (!hash_gen(dctx, out, outlen)) + return 0; + + tmp[0] = 3; + if (!FIPS_digestinit(mctx, hctx->md)) + return 0; + if (!EVP_DigestUpdate(mctx, tmp, 1)) + return 0; + if (!EVP_DigestUpdate(mctx, hctx->V, dctx->seedlen)) + return 0; + + if (!ctx_add_md(dctx)) + return 0; + + ctx_add_buf(dctx, hctx->V, hctx->C, dctx->seedlen); + + tmp[0] = (dctx->reseed_counter >> 24) & 0xff; + tmp[1] = (dctx->reseed_counter >> 16) & 0xff; + tmp[2] = (dctx->reseed_counter >> 8) & 0xff; + tmp[3] = dctx->reseed_counter & 0xff; + ctx_add_buf(dctx, hctx->V, tmp, 4); +#ifdef HASH_DRBG_TRACE + fprintf(stderr, "V+C after generate:\n"); + hexprint(stderr, hctx->V, dctx->seedlen); + hexprint(stderr, hctx->C, dctx->seedlen); +#endif + return 1; +} + +static int drbg_hash_uninstantiate(DRBG_CTX *dctx) +{ + EVP_MD_CTX_cleanup(&dctx->d.hash.mctx); + OPENSSL_cleanse(&dctx->d.hash, sizeof(DRBG_HASH_CTX)); + return 1; +} + +int fips_drbg_hash_init(DRBG_CTX *dctx) +{ + const EVP_MD *md; + DRBG_HASH_CTX *hctx = &dctx->d.hash; + md = FIPS_get_digestbynid(dctx->type); + if (!md) + return -2; + switch (dctx->type) { + case NID_sha1: + dctx->strength = 128; + break; + + case NID_sha224: + dctx->strength = 192; + break; + + default: + dctx->strength = 256; + break; + } + + dctx->instantiate = drbg_hash_instantiate; + dctx->reseed = drbg_hash_reseed; + dctx->generate = drbg_hash_generate; + dctx->uninstantiate = drbg_hash_uninstantiate; + + dctx->d.hash.md = md; + EVP_MD_CTX_init(&hctx->mctx); + + /* These are taken from SP 800-90 10.1 table 2 */ + + dctx->blocklength = M_EVP_MD_size(md); + if (dctx->blocklength > 32) + dctx->seedlen = 111; + else + dctx->seedlen = 55; + + dctx->min_entropy = dctx->strength / 8; + dctx->max_entropy = DRBG_MAX_LENGTH; + + dctx->min_nonce = dctx->min_entropy / 2; + dctx->max_nonce = DRBG_MAX_LENGTH; + + dctx->max_pers = DRBG_MAX_LENGTH; + dctx->max_adin = DRBG_MAX_LENGTH; + + dctx->max_request = 1 << 16; + dctx->reseed_interval = 1 << 24; + + return 1; +} diff --git a/crypto/fips/fips_drbg_hmac.c b/crypto/fips/fips_drbg_hmac.c new file mode 100644 index 0000000..105db12 --- /dev/null +++ b/crypto/fips/fips_drbg_hmac.c @@ -0,0 +1,270 @@ +/* fips/rand/fips_drbg_hmac.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include <stdlib.h> +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/aes.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +static int drbg_hmac_update(DRBG_CTX *dctx, + const unsigned char *in1, size_t in1len, + const unsigned char *in2, size_t in2len, + const unsigned char *in3, size_t in3len) +{ + static unsigned char c0 = 0, c1 = 1; + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + HMAC_CTX *hctx = &hmac->hctx; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + if (!HMAC_Update(hctx, &c0, 1)) + return 0; + if (in1len && !HMAC_Update(hctx, in1, in1len)) + return 0; + if (in2len && !HMAC_Update(hctx, in2, in2len)) + return 0; + if (in3len && !HMAC_Update(hctx, in3, in3len)) + return 0; + + if (!HMAC_Final(hctx, hmac->K, NULL)) + return 0; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + + if (!HMAC_Final(hctx, hmac->V, NULL)) + return 0; + + if (!in1len && !in2len && !in3len) + return 1; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + if (!HMAC_Update(hctx, &c1, 1)) + return 0; + if (in1len && !HMAC_Update(hctx, in1, in1len)) + return 0; + if (in2len && !HMAC_Update(hctx, in2, in2len)) + return 0; + if (in3len && !HMAC_Update(hctx, in3, in3len)) + return 0; + + if (!HMAC_Final(hctx, hmac->K, NULL)) + return 0; + + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, hmac->V, dctx->blocklength)) + return 0; + + if (!HMAC_Final(hctx, hmac->V, NULL)) + return 0; + + return 1; + +} + +static int drbg_hmac_instantiate(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *nonce, size_t nonce_len, + const unsigned char *pstr, size_t pstr_len) +{ + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + memset(hmac->K, 0, dctx->blocklength); + memset(hmac->V, 1, dctx->blocklength); + if (!drbg_hmac_update(dctx, + ent, ent_len, nonce, nonce_len, pstr, pstr_len)) + return 0; + +#ifdef HMAC_DRBG_TRACE + fprintf(stderr, "K+V after instantiate:\n"); + hexprint(stderr, hmac->K, hmac->blocklength); + hexprint(stderr, hmac->V, hmac->blocklength); +#endif + return 1; +} + +static int drbg_hmac_reseed(DRBG_CTX *dctx, + const unsigned char *ent, size_t ent_len, + const unsigned char *adin, size_t adin_len) +{ + if (!drbg_hmac_update(dctx, ent, ent_len, adin, adin_len, NULL, 0)) + return 0; + +#ifdef HMAC_DRBG_TRACE + { + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + fprintf(stderr, "K+V after reseed:\n"); + hexprint(stderr, hmac->K, hmac->blocklength); + hexprint(stderr, hmac->V, hmac->blocklength); + } +#endif + return 1; +} + +static int drbg_hmac_generate(DRBG_CTX *dctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adin_len) +{ + DRBG_HMAC_CTX *hmac = &dctx->d.hmac; + HMAC_CTX *hctx = &hmac->hctx; + const unsigned char *Vtmp = hmac->V; + if (adin_len && !drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0)) + return 0; + for (;;) { + if (!HMAC_Init_ex(hctx, hmac->K, dctx->blocklength, hmac->md, NULL)) + return 0; + if (!HMAC_Update(hctx, Vtmp, dctx->blocklength)) + return 0; + if (!(dctx->xflags & DRBG_FLAG_TEST) && !dctx->lb_valid) { + if (!HMAC_Final(hctx, dctx->lb, NULL)) + return 0; + dctx->lb_valid = 1; + Vtmp = dctx->lb; + continue; + } else if (outlen > dctx->blocklength) { + if (!HMAC_Final(hctx, out, NULL)) + return 0; + if (!fips_drbg_cprng_test(dctx, out)) + return 0; + Vtmp = out; + } else { + if (!HMAC_Final(hctx, hmac->V, NULL)) + return 0; + if (!fips_drbg_cprng_test(dctx, hmac->V)) + return 0; + memcpy(out, hmac->V, outlen); + break; + } + out += dctx->blocklength; + outlen -= dctx->blocklength; + } + if (!drbg_hmac_update(dctx, adin, adin_len, NULL, 0, NULL, 0)) + return 0; + + return 1; +} + +static int drbg_hmac_uninstantiate(DRBG_CTX *dctx) +{ + HMAC_CTX_cleanup(&dctx->d.hmac.hctx); + OPENSSL_cleanse(&dctx->d.hmac, sizeof(DRBG_HMAC_CTX)); + return 1; +} + +int fips_drbg_hmac_init(DRBG_CTX *dctx) +{ + const EVP_MD *md = NULL; + DRBG_HMAC_CTX *hctx = &dctx->d.hmac; + dctx->strength = 256; + switch (dctx->type) { + case NID_hmacWithSHA1: + md = EVP_sha1(); + dctx->strength = 128; + break; + + case NID_hmacWithSHA224: + md = EVP_sha224(); + dctx->strength = 192; + break; + + case NID_hmacWithSHA256: + md = EVP_sha256(); + break; + + case NID_hmacWithSHA384: + md = EVP_sha384(); + break; + + case NID_hmacWithSHA512: + md = EVP_sha512(); + break; + + default: + dctx->strength = 0; + return -2; + } + dctx->instantiate = drbg_hmac_instantiate; + dctx->reseed = drbg_hmac_reseed; + dctx->generate = drbg_hmac_generate; + dctx->uninstantiate = drbg_hmac_uninstantiate; + HMAC_CTX_init(&hctx->hctx); + hctx->md = md; + dctx->blocklength = M_EVP_MD_size(md); + dctx->seedlen = M_EVP_MD_size(md); + + dctx->min_entropy = dctx->strength / 8; + dctx->max_entropy = DRBG_MAX_LENGTH; + + dctx->min_nonce = dctx->min_entropy / 2; + dctx->max_nonce = DRBG_MAX_LENGTH; + + dctx->max_pers = DRBG_MAX_LENGTH; + dctx->max_adin = DRBG_MAX_LENGTH; + + dctx->max_request = 1 << 16; + dctx->reseed_interval = 1 << 24; + + return 1; +} diff --git a/crypto/fips/fips_drbg_lib.c b/crypto/fips/fips_drbg_lib.c new file mode 100644 index 0000000..1a71322 --- /dev/null +++ b/crypto/fips/fips_drbg_lib.c @@ -0,0 +1,553 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/fips_rand.h> +#include "fips_locl.h" +#include "fips_rand_lcl.h" + +/* Support framework for SP800-90 DRBGs */ + +int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags) +{ + int rv; + memset(dctx, 0, sizeof(DRBG_CTX)); + dctx->status = DRBG_STATUS_UNINITIALISED; + dctx->xflags = flags; + dctx->type = type; + + dctx->iflags = 0; + dctx->entropy_blocklen = 0; + dctx->health_check_cnt = 0; + dctx->health_check_interval = DRBG_HEALTH_INTERVAL; + + rv = fips_drbg_hash_init(dctx); + + if (rv == -2) + rv = fips_drbg_ctr_init(dctx); + if (rv == -2) + rv = fips_drbg_hmac_init(dctx); + + if (rv <= 0) { + if (rv == -2) + FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_UNSUPPORTED_DRBG_TYPE); + else + FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_ERROR_INITIALISING_DRBG); + } + + /* If not in test mode run selftests on DRBG of the same type */ + + if (!(dctx->xflags & DRBG_FLAG_TEST)) { + if (!FIPS_drbg_health_check(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_INIT, FIPS_R_SELFTEST_FAILURE); + return 0; + } + } + + return rv; +} + +DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags) +{ + DRBG_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DRBG_CTX)); + if (!dctx) { + FIPSerr(FIPS_F_FIPS_DRBG_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (type == 0) { + memset(dctx, 0, sizeof(DRBG_CTX)); + dctx->type = 0; + dctx->status = DRBG_STATUS_UNINITIALISED; + return dctx; + } + + if (FIPS_drbg_init(dctx, type, flags) <= 0) { + OPENSSL_free(dctx); + return NULL; + } + + return dctx; +} + +void FIPS_drbg_free(DRBG_CTX *dctx) +{ + if (dctx->uninstantiate) + dctx->uninstantiate(dctx); + /* Don't free up default DRBG */ + if (dctx == FIPS_get_default_drbg()) { + memset(dctx, 0, sizeof(DRBG_CTX)); + dctx->type = 0; + dctx->status = DRBG_STATUS_UNINITIALISED; + } else { + OPENSSL_cleanse(&dctx->d, sizeof(dctx->d)); + OPENSSL_free(dctx); + } +} + +static size_t fips_get_entropy(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) +{ + unsigned char *tout, *p; + size_t bl = dctx->entropy_blocklen, rv; + if (!dctx->get_entropy) + return 0; + if (dctx->xflags & DRBG_FLAG_TEST || !bl) + return dctx->get_entropy(dctx, pout, entropy, min_len, max_len); + rv = dctx->get_entropy(dctx, &tout, entropy + bl, + min_len + bl, max_len + bl); + if (tout == NULL) + return 0; + *pout = tout + bl; + if (rv < (min_len + bl) || (rv % bl)) + return 0; + /* Compare consecutive blocks for continuous PRNG test */ + for (p = tout; p < tout + rv - bl; p += bl) { + if (!memcmp(p, p + bl, bl)) { + FIPSerr(FIPS_F_FIPS_GET_ENTROPY, FIPS_R_ENTROPY_SOURCE_STUCK); + return 0; + } + } + rv -= bl; + if (rv > max_len) + return max_len; + return rv; +} + +static void fips_cleanup_entropy(DRBG_CTX *dctx, + unsigned char *out, size_t olen) +{ + size_t bl; + if (dctx->xflags & DRBG_FLAG_TEST) + bl = 0; + else + bl = dctx->entropy_blocklen; + /* Call cleanup with original arguments */ + dctx->cleanup_entropy(dctx, out - bl, olen + bl); +} + +int FIPS_drbg_instantiate(DRBG_CTX *dctx, + const unsigned char *pers, size_t perslen) +{ + size_t entlen = 0, noncelen = 0; + unsigned char *nonce = NULL, *entropy = NULL; + +#if 0 + /* Put here so error script picks them up */ + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, + FIPS_R_PERSONALISATION_STRING_TOO_LONG); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_IN_ERROR_STATE); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ALREADY_INSTANTIATED); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_ENTROPY); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_ERROR_RETRIEVING_NONCE); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_INSTANTIATE_ERROR); + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, FIPS_R_DRBG_NOT_INITIALISED); +#endif + + int r = 0; + + if (perslen > dctx->max_pers) { + r = FIPS_R_PERSONALISATION_STRING_TOO_LONG; + goto end; + } + + if (!dctx->instantiate) { + r = FIPS_R_DRBG_NOT_INITIALISED; + goto end; + } + + if (dctx->status != DRBG_STATUS_UNINITIALISED) { + if (dctx->status == DRBG_STATUS_ERROR) + r = FIPS_R_IN_ERROR_STATE; + else + r = FIPS_R_ALREADY_INSTANTIATED; + goto end; + } + + dctx->status = DRBG_STATUS_ERROR; + + entlen = fips_get_entropy(dctx, &entropy, dctx->strength, + dctx->min_entropy, dctx->max_entropy); + + if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) { + r = FIPS_R_ERROR_RETRIEVING_ENTROPY; + goto end; + } + + if (dctx->max_nonce > 0 && dctx->get_nonce) { + noncelen = dctx->get_nonce(dctx, &nonce, + dctx->strength / 2, + dctx->min_nonce, dctx->max_nonce); + + if (noncelen < dctx->min_nonce || noncelen > dctx->max_nonce) { + r = FIPS_R_ERROR_RETRIEVING_NONCE; + goto end; + } + + } + + if (!dctx->instantiate(dctx, + entropy, entlen, nonce, noncelen, pers, perslen)) { + r = FIPS_R_ERROR_INSTANTIATING_DRBG; + goto end; + } + + dctx->status = DRBG_STATUS_READY; + if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) + dctx->reseed_counter = 1; + + end: + + if (entropy && dctx->cleanup_entropy) + fips_cleanup_entropy(dctx, entropy, entlen); + + if (nonce && dctx->cleanup_nonce) + dctx->cleanup_nonce(dctx, nonce, noncelen); + + if (dctx->status == DRBG_STATUS_READY) + return 1; + + if (r && !(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_FIPS_DRBG_INSTANTIATE, r); + + return 0; + +} + +static int drbg_reseed(DRBG_CTX *dctx, + const unsigned char *adin, size_t adinlen, int hcheck) +{ + unsigned char *entropy = NULL; + size_t entlen = 0; + int r = 0; + +#if 0 + FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_NOT_INSTANTIATED); + FIPSerr(FIPS_F_DRBG_RESEED, FIPS_R_ADDITIONAL_INPUT_TOO_LONG); +#endif + if (dctx->status != DRBG_STATUS_READY + && dctx->status != DRBG_STATUS_RESEED) { + if (dctx->status == DRBG_STATUS_ERROR) + r = FIPS_R_IN_ERROR_STATE; + else if (dctx->status == DRBG_STATUS_UNINITIALISED) + r = FIPS_R_NOT_INSTANTIATED; + goto end; + } + + if (!adin) + adinlen = 0; + else if (adinlen > dctx->max_adin) { + r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG; + goto end; + } + + dctx->status = DRBG_STATUS_ERROR; + /* Peform health check on all reseed operations if not a prediction + * resistance request and not in test mode. + */ + if (hcheck && !(dctx->xflags & DRBG_FLAG_TEST)) { + if (!FIPS_drbg_health_check(dctx)) { + r = FIPS_R_SELFTEST_FAILURE; + goto end; + } + } + + entlen = fips_get_entropy(dctx, &entropy, dctx->strength, + dctx->min_entropy, dctx->max_entropy); + + if (entlen < dctx->min_entropy || entlen > dctx->max_entropy) { + r = FIPS_R_ERROR_RETRIEVING_ENTROPY; + goto end; + } + + if (!dctx->reseed(dctx, entropy, entlen, adin, adinlen)) + goto end; + + dctx->status = DRBG_STATUS_READY; + if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) + dctx->reseed_counter = 1; + end: + + if (entropy && dctx->cleanup_entropy) + fips_cleanup_entropy(dctx, entropy, entlen); + + if (dctx->status == DRBG_STATUS_READY) + return 1; + + if (r && !(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_DRBG_RESEED, r); + + return 0; +} + +int FIPS_drbg_reseed(DRBG_CTX *dctx, + const unsigned char *adin, size_t adinlen) +{ + return drbg_reseed(dctx, adin, adinlen, 1); +} + +static int fips_drbg_check(DRBG_CTX *dctx) +{ + if (dctx->xflags & DRBG_FLAG_TEST) + return 1; + dctx->health_check_cnt++; + if (dctx->health_check_cnt >= dctx->health_check_interval) { + if (!FIPS_drbg_health_check(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_CHECK, FIPS_R_SELFTEST_FAILURE); + return 0; + } + } + return 1; +} + +int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen) +{ + int r = 0; + + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, FIPS_R_SELFTEST_FAILED); + return 0; + } + + if (!fips_drbg_check(dctx)) + return 0; + + if (dctx->status != DRBG_STATUS_READY + && dctx->status != DRBG_STATUS_RESEED) { + if (dctx->status == DRBG_STATUS_ERROR) + r = FIPS_R_IN_ERROR_STATE; + else if (dctx->status == DRBG_STATUS_UNINITIALISED) + r = FIPS_R_NOT_INSTANTIATED; + goto end; + } + + if (outlen > dctx->max_request) { + r = FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG; + return 0; + } + + if (adinlen > dctx->max_adin) { + r = FIPS_R_ADDITIONAL_INPUT_TOO_LONG; + goto end; + } + + if (dctx->iflags & DRBG_CUSTOM_RESEED) + dctx->generate(dctx, NULL, outlen, NULL, 0); + else if (dctx->reseed_counter >= dctx->reseed_interval) + dctx->status = DRBG_STATUS_RESEED; + + if (dctx->status == DRBG_STATUS_RESEED || prediction_resistance) { + /* If prediction resistance request don't do health check */ + int hcheck = prediction_resistance ? 0 : 1; + + if (!drbg_reseed(dctx, adin, adinlen, hcheck)) { + r = FIPS_R_RESEED_ERROR; + goto end; + } + adin = NULL; + adinlen = 0; + } + + if (!dctx->generate(dctx, out, outlen, adin, adinlen)) { + r = FIPS_R_GENERATE_ERROR; + dctx->status = DRBG_STATUS_ERROR; + goto end; + } + if (!(dctx->iflags & DRBG_CUSTOM_RESEED)) { + if (dctx->reseed_counter >= dctx->reseed_interval) + dctx->status = DRBG_STATUS_RESEED; + else + dctx->reseed_counter++; + } + + end: + if (r) { + if (!(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r); + return 0; + } + + return 1; +} + +int FIPS_drbg_uninstantiate(DRBG_CTX *dctx) +{ + int rv; + if (!dctx->uninstantiate) + rv = 1; + else + rv = dctx->uninstantiate(dctx); + /* Although we'd like to cleanse here we can't because we have to + * test the uninstantiate really zeroes the data. + */ + memset(&dctx->d, 0, sizeof(dctx->d)); + dctx->status = DRBG_STATUS_UNINITIALISED; + /* If method has problems uninstantiating, return error */ + return rv; +} + +int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, + size_t (*get_entropy) (DRBG_CTX *ctx, + unsigned char **pout, + int entropy, + size_t min_len, + size_t max_len), + void (*cleanup_entropy) (DRBG_CTX *ctx, + unsigned char *out, + size_t olen), + size_t entropy_blocklen, + size_t (*get_nonce) (DRBG_CTX *ctx, + unsigned char **pout, + int entropy, size_t min_len, + size_t max_len), + void (*cleanup_nonce) (DRBG_CTX *ctx, + unsigned char *out, + size_t olen)) +{ + if (dctx->status != DRBG_STATUS_UNINITIALISED) + return 0; + dctx->entropy_blocklen = entropy_blocklen; + dctx->get_entropy = get_entropy; + dctx->cleanup_entropy = cleanup_entropy; + dctx->get_nonce = get_nonce; + dctx->cleanup_nonce = cleanup_nonce; + return 1; +} + +int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx, + size_t (*get_adin) (DRBG_CTX *ctx, + unsigned char **pout), + void (*cleanup_adin) (DRBG_CTX *ctx, + unsigned char *out, + size_t olen), + int (*rand_seed_cb) (DRBG_CTX *ctx, + const void *buf, + int num), + int (*rand_add_cb) (DRBG_CTX *ctx, + const void *buf, int num, + double entropy)) +{ + if (dctx->status != DRBG_STATUS_UNINITIALISED) + return 0; + dctx->get_adin = get_adin; + dctx->cleanup_adin = cleanup_adin; + dctx->rand_seed_cb = rand_seed_cb; + dctx->rand_add_cb = rand_add_cb; + return 1; +} + +void *FIPS_drbg_get_app_data(DRBG_CTX *dctx) +{ + return dctx->app_data; +} + +void FIPS_drbg_set_app_data(DRBG_CTX *dctx, void *app_data) +{ + dctx->app_data = app_data; +} + +size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx) +{ + return dctx->blocklength; +} + +int FIPS_drbg_get_strength(DRBG_CTX *dctx) +{ + return dctx->strength; +} + +void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval) +{ + dctx->health_check_interval = interval; +} + +void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval) +{ + dctx->reseed_interval = interval; +} + +static int drbg_stick = 0; + +void FIPS_drbg_stick(int onoff) +{ + drbg_stick = onoff; +} + +/* Continuous DRBG utility function */ +int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out) +{ + /* No CPRNG in test mode */ + if (dctx->xflags & DRBG_FLAG_TEST) + return 1; + /* Check block is valid: should never happen */ + if (dctx->lb_valid == 0) { + FIPSerr(FIPS_F_FIPS_DRBG_CPRNG_TEST, FIPS_R_INTERNAL_ERROR); + fips_set_selftest_fail(); + return 0; + } + if (drbg_stick) + memcpy(dctx->lb, out, dctx->blocklength); + /* Check against last block: fail if match */ + if (!memcmp(dctx->lb, out, dctx->blocklength)) { + FIPSerr(FIPS_F_FIPS_DRBG_CPRNG_TEST, FIPS_R_DRBG_STUCK); + fips_set_selftest_fail(); + return 0; + } + /* Save last block for next comparison */ + memcpy(dctx->lb, out, dctx->blocklength); + return 1; +} diff --git a/crypto/fips/fips_drbg_rand.c b/crypto/fips/fips_drbg_rand.c new file mode 100644 index 0000000..43600dd --- /dev/null +++ b/crypto/fips/fips_drbg_rand.c @@ -0,0 +1,166 @@ +/* fips/rand/fips_drbg_rand.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" + +/* Mapping of SP800-90 DRBGs to OpenSSL RAND_METHOD */ + +/* Since we only have one global PRNG used at any time in OpenSSL use a global + * variable to store context. + */ + +static DRBG_CTX ossl_dctx; + +DRBG_CTX *FIPS_get_default_drbg(void) +{ + return &ossl_dctx; +} + +static int fips_drbg_bytes(unsigned char *out, int count) +{ + DRBG_CTX *dctx = &ossl_dctx; + int rv = 0; + unsigned char *adin = NULL; + size_t adinlen = 0; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + do { + size_t rcnt; + if (count > (int)dctx->max_request) + rcnt = dctx->max_request; + else + rcnt = count; + if (dctx->get_adin) { + adinlen = dctx->get_adin(dctx, &adin); + if (adinlen && !adin) { + FIPSerr(FIPS_F_FIPS_DRBG_BYTES, + FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT); + goto err; + } + } + rv = FIPS_drbg_generate(dctx, out, rcnt, 0, adin, adinlen); + if (adin) { + if (dctx->cleanup_adin) + dctx->cleanup_adin(dctx, adin, adinlen); + adin = NULL; + } + if (!rv) + goto err; + out += rcnt; + count -= rcnt; + } + while (count); + rv = 1; + err: + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + return rv; +} + +static int fips_drbg_pseudo(unsigned char *out, int count) +{ + if (fips_drbg_bytes(out, count) <= 0) + return -1; + return 1; +} + +static int fips_drbg_status(void) +{ + DRBG_CTX *dctx = &ossl_dctx; + int rv; + CRYPTO_r_lock(CRYPTO_LOCK_RAND); + rv = dctx->status == DRBG_STATUS_READY ? 1 : 0; + CRYPTO_r_unlock(CRYPTO_LOCK_RAND); + return rv; +} + +static void fips_drbg_cleanup(void) +{ + DRBG_CTX *dctx = &ossl_dctx; + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + FIPS_drbg_uninstantiate(dctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); +} + +static int fips_drbg_seed(const void *seed, int seedlen) +{ + DRBG_CTX *dctx = &ossl_dctx; + if (dctx->rand_seed_cb) + return dctx->rand_seed_cb(dctx, seed, seedlen); + return 1; +} + +static int fips_drbg_add(const void *seed, int seedlen, double add_entropy) +{ + DRBG_CTX *dctx = &ossl_dctx; + if (dctx->rand_add_cb) + return dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); + return 1; +} + +static const RAND_METHOD rand_drbg_meth = { + fips_drbg_seed, + fips_drbg_bytes, + fips_drbg_cleanup, + fips_drbg_add, + fips_drbg_pseudo, + fips_drbg_status +}; + +const RAND_METHOD *FIPS_drbg_method(void) +{ + return &rand_drbg_meth; +} diff --git a/crypto/fips/fips_drbg_selftest.c b/crypto/fips/fips_drbg_selftest.c new file mode 100644 index 0000000..1397202 --- /dev/null +++ b/crypto/fips/fips_drbg_selftest.c @@ -0,0 +1,827 @@ +/* fips/rand/fips_drbg_selftest.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/fips_rand.h> +#include "fips_rand_lcl.h" +#include "fips_locl.h" + +#include "fips_drbg_selftest.h" + +typedef struct { + int post; + int nid; + unsigned int flags; + + /* KAT data for no PR */ + const unsigned char *ent; + size_t entlen; + const unsigned char *nonce; + size_t noncelen; + const unsigned char *pers; + size_t perslen; + const unsigned char *adin; + size_t adinlen; + const unsigned char *entreseed; + size_t entreseedlen; + const unsigned char *adinreseed; + size_t adinreseedlen; + const unsigned char *adin2; + size_t adin2len; + const unsigned char *kat; + size_t katlen; + const unsigned char *kat2; + size_t kat2len; + + /* KAT data for PR */ + const unsigned char *ent_pr; + size_t entlen_pr; + const unsigned char *nonce_pr; + size_t noncelen_pr; + const unsigned char *pers_pr; + size_t perslen_pr; + const unsigned char *adin_pr; + size_t adinlen_pr; + const unsigned char *entpr_pr; + size_t entprlen_pr; + const unsigned char *ading_pr; + size_t adinglen_pr; + const unsigned char *entg_pr; + size_t entglen_pr; + const unsigned char *kat_pr; + size_t katlen_pr; + const unsigned char *kat2_pr; + size_t kat2len_pr; + +} DRBG_SELFTEST_DATA; + +#define make_drbg_test_data(nid, flag, pr, p) {p, nid, flag | DRBG_FLAG_TEST, \ + pr##_entropyinput, sizeof(pr##_entropyinput), \ + pr##_nonce, sizeof(pr##_nonce), \ + pr##_personalizationstring, sizeof(pr##_personalizationstring), \ + pr##_additionalinput, sizeof(pr##_additionalinput), \ + pr##_entropyinputreseed, sizeof(pr##_entropyinputreseed), \ + pr##_additionalinputreseed, sizeof(pr##_additionalinputreseed), \ + pr##_additionalinput2, sizeof(pr##_additionalinput2), \ + pr##_int_returnedbits, sizeof(pr##_int_returnedbits), \ + pr##_returnedbits, sizeof(pr##_returnedbits), \ + pr##_pr_entropyinput, sizeof(pr##_pr_entropyinput), \ + pr##_pr_nonce, sizeof(pr##_pr_nonce), \ + pr##_pr_personalizationstring, sizeof(pr##_pr_personalizationstring), \ + pr##_pr_additionalinput, sizeof(pr##_pr_additionalinput), \ + pr##_pr_entropyinputpr, sizeof(pr##_pr_entropyinputpr), \ + pr##_pr_additionalinput2, sizeof(pr##_pr_additionalinput2), \ + pr##_pr_entropyinputpr2, sizeof(pr##_pr_entropyinputpr2), \ + pr##_pr_int_returnedbits, sizeof(pr##_pr_int_returnedbits), \ + pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits), \ + } + +#define make_drbg_test_data_df(nid, pr, p) \ + make_drbg_test_data(nid, DRBG_FLAG_CTR_USE_DF, pr, p) + +#define make_drbg_test_data_ec(curve, md, pr, p) \ + make_drbg_test_data((curve << 16) | md , 0, pr, p) + +static DRBG_SELFTEST_DATA drbg_test[] = { + make_drbg_test_data_df(NID_aes_128_ctr, aes_128_use_df, 0), + make_drbg_test_data_df(NID_aes_192_ctr, aes_192_use_df, 0), + make_drbg_test_data_df(NID_aes_256_ctr, aes_256_use_df, 1), + make_drbg_test_data(NID_aes_128_ctr, 0, aes_128_no_df, 0), + make_drbg_test_data(NID_aes_192_ctr, 0, aes_192_no_df, 0), + make_drbg_test_data(NID_aes_256_ctr, 0, aes_256_no_df, 1), + make_drbg_test_data(NID_sha1, 0, sha1, 0), + make_drbg_test_data(NID_sha224, 0, sha224, 0), + make_drbg_test_data(NID_sha256, 0, sha256, 1), + make_drbg_test_data(NID_sha384, 0, sha384, 0), + make_drbg_test_data(NID_sha512, 0, sha512, 0), + make_drbg_test_data(NID_hmacWithSHA1, 0, hmac_sha1, 0), + make_drbg_test_data(NID_hmacWithSHA224, 0, hmac_sha224, 0), + make_drbg_test_data(NID_hmacWithSHA256, 0, hmac_sha256, 1), + make_drbg_test_data(NID_hmacWithSHA384, 0, hmac_sha384, 0), + make_drbg_test_data(NID_hmacWithSHA512, 0, hmac_sha512, 0), + {0, 0, 0} +}; + +typedef struct { + const unsigned char *ent; + size_t entlen; + int entcnt; + const unsigned char *nonce; + size_t noncelen; + int noncecnt; +} TEST_ENT; + +static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) +{ + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + *pout = (unsigned char *)t->ent; + t->entcnt++; + return t->entlen; +} + +static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) +{ + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + *pout = (unsigned char *)t->nonce; + t->noncecnt++; + return t->noncelen; +} + +static int fips_drbg_single_kat(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td, + int quick) +{ + TEST_ENT t; + int rv = 0; + size_t adinlen; + unsigned char randout[1024]; + + /* Initial test without PR */ + + /* Instantiate DRBG with test entropy, nonce and personalisation + * string. + */ + + if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + return 0; + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + return 0; + + FIPS_drbg_set_app_data(dctx, &t); + + t.ent = td->ent; + t.entlen = td->entlen; + t.nonce = td->nonce; + t.noncelen = td->noncelen; + t.entcnt = 0; + t.noncecnt = 0; + + if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) + goto err; + + /* Note for CTR without DF some additional input values + * ignore bytes after the keylength: so reduce adinlen + * to half to ensure invalid data is fed in. + */ + if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) + adinlen = td->adinlen / 2; + else + adinlen = td->adinlen; + + /* Generate with no PR and verify output matches expected data */ + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, td->adin, adinlen)) + goto err; + + if (memcmp(randout, td->kat, td->katlen)) { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST1_FAILURE); + goto err2; + } + /* If abbreviated POST end of test */ + if (quick) { + rv = 1; + goto err; + } + /* Reseed DRBG with test entropy and additional input */ + t.ent = td->entreseed; + t.entlen = td->entreseedlen; + + if (!FIPS_drbg_reseed(dctx, td->adinreseed, td->adinreseedlen)) + goto err; + + /* Generate with no PR and verify output matches expected data */ + if (!FIPS_drbg_generate(dctx, randout, td->kat2len, 0, + td->adin2, td->adin2len)) + goto err; + + if (memcmp(randout, td->kat2, td->kat2len)) { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_NOPR_TEST2_FAILURE); + goto err2; + } + + FIPS_drbg_uninstantiate(dctx); + + /* Now test with PR */ + + /* Instantiate DRBG with test entropy, nonce and personalisation + * string. + */ + if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + return 0; + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + return 0; + + FIPS_drbg_set_app_data(dctx, &t); + + t.ent = td->ent_pr; + t.entlen = td->entlen_pr; + t.nonce = td->nonce_pr; + t.noncelen = td->noncelen_pr; + t.entcnt = 0; + t.noncecnt = 0; + + if (!FIPS_drbg_instantiate(dctx, td->pers_pr, td->perslen_pr)) + goto err; + + /* Now generate with PR: we need to supply entropy as this will + * perform a reseed operation. Check output matches expected value. + */ + + t.ent = td->entpr_pr; + t.entlen = td->entprlen_pr; + + /* Note for CTR without DF some additional input values + * ignore bytes after the keylength: so reduce adinlen + * to half to ensure invalid data is fed in. + */ + if (!fips_post_corrupt(FIPS_TEST_DRBG, dctx->type, &dctx->iflags)) + adinlen = td->adinlen_pr / 2; + else + adinlen = td->adinlen_pr; + if (!FIPS_drbg_generate(dctx, randout, td->katlen_pr, 1, + td->adin_pr, adinlen)) + goto err; + + if (memcmp(randout, td->kat_pr, td->katlen_pr)) { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST1_FAILURE); + goto err2; + } + + /* Now generate again with PR: supply new entropy again. + * Check output matches expected value. + */ + + t.ent = td->entg_pr; + t.entlen = td->entglen_pr; + + if (!FIPS_drbg_generate(dctx, randout, td->kat2len_pr, 1, + td->ading_pr, td->adinglen_pr)) + goto err; + + if (memcmp(randout, td->kat2_pr, td->kat2len_pr)) { + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_PR_TEST2_FAILURE); + goto err2; + } + /* All OK, test complete */ + rv = 1; + + err: + if (rv == 0) + FIPSerr(FIPS_F_FIPS_DRBG_SINGLE_KAT, FIPS_R_SELFTEST_FAILED); + err2: + FIPS_drbg_uninstantiate(dctx); + + return rv; + +} + +/* Initialise a DRBG based on selftest data */ + +static int do_drbg_init(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td, TEST_ENT * t) +{ + + if (!FIPS_drbg_init(dctx, td->nid, td->flags)) + return 0; + + if (!FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, test_nonce, 0)) + return 0; + + FIPS_drbg_set_app_data(dctx, t); + + t->ent = td->ent; + t->entlen = td->entlen; + t->nonce = td->nonce; + t->noncelen = td->noncelen; + t->entcnt = 0; + t->noncecnt = 0; + return 1; +} + +/* Initialise and instantiate DRBG based on selftest data */ +static int do_drbg_instantiate(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td, + TEST_ENT * t) +{ + if (!do_drbg_init(dctx, td, t)) + return 0; + if (!FIPS_drbg_instantiate(dctx, td->pers, td->perslen)) + return 0; + + return 1; +} + +/* This function performs extensive error checking as required by SP800-90. + * Induce several failure modes and check an error condition is set. + * This function along with fips_drbg_single_kat peforms the health checking + * operation. + */ + +static int fips_drbg_error_check(DRBG_CTX *dctx, DRBG_SELFTEST_DATA * td) +{ + unsigned char randout[1024]; + TEST_ENT t; + size_t i; + unsigned int reseed_counter_tmp; + unsigned char *p = (unsigned char *)dctx; + + /* Initialise DRBG */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + /* Don't report induced errors */ + dctx->iflags |= DRBG_FLAG_NOERR; + + /* Personalisation string tests */ + + /* Test detection of too large personlisation string */ + + if (FIPS_drbg_instantiate(dctx, td->pers, dctx->max_pers + 1) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_PERSONALISATION_ERROR_UNDETECTED); + goto err; + } + + /* Entropy source tests */ + + /* Test entropy source failure detecion: i.e. returns no data */ + + t.entlen = 0; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + /* Try to generate output from uninstantiated DRBG */ + if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_GENERATE_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + /* Test insufficient entropy */ + + t.entlen = dctx->min_entropy - 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test too much entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->max_entropy + 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Nonce tests */ + + /* Test too small nonce */ + + if (dctx->min_nonce) { + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.noncelen = dctx->min_nonce - 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_NONCE_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + } + + /* Test too large nonce */ + + if (dctx->max_nonce) { + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.noncelen = dctx->max_nonce + 1; + + if (FIPS_drbg_instantiate(dctx, td->pers, td->perslen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_NONCE_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + } + + /* Instantiate with valid data. */ + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + + /* Check generation is now OK */ + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + /* Request too much data for one request */ + if (FIPS_drbg_generate(dctx, randout, dctx->max_request + 1, 0, + td->adin, td->adinlen)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED); + goto err; + } + + /* Try too large additional input */ + if (FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, dctx->max_adin + 1)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); + goto err; + } + + /* Check prediction resistance request fails if entropy source + * failure. + */ + + t.entlen = 0; + + if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, + td->adin, td->adinlen)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Instantiate again with valid data */ + + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + /* Test reseed counter works */ + /* Save initial reseed counter */ + reseed_counter_tmp = dctx->reseed_counter; + /* Set reseed counter to beyond interval */ + dctx->reseed_counter = dctx->reseed_interval; + + /* Generate output and check entropy has been requested for reseed */ + t.entcnt = 0; + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + goto err; + if (t.entcnt != 1) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED); + goto err; + } + /* Check reseed counter has been reset */ + if (dctx->reseed_counter != reseed_counter_tmp + 1) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Check prediction resistance request fails if entropy source + * failure. + */ + + t.entlen = 0; + + dctx->iflags |= DRBG_FLAG_NOERR; + if (FIPS_drbg_generate(dctx, randout, td->katlen, 1, + td->adin, td->adinlen)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + if (!do_drbg_instantiate(dctx, td, &t)) + goto err; + /* Test reseed counter works */ + /* Save initial reseed counter */ + reseed_counter_tmp = dctx->reseed_counter; + /* Set reseed counter to beyond interval */ + dctx->reseed_counter = dctx->reseed_interval; + + /* Generate output and check entropy has been requested for reseed */ + t.entcnt = 0; + if (!FIPS_drbg_generate(dctx, randout, td->katlen, 0, + td->adin, td->adinlen)) + goto err; + if (t.entcnt != 1) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED); + goto err; + } + /* Check reseed counter has been reset */ + if (dctx->reseed_counter != reseed_counter_tmp + 1) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_RESEED_COUNTER_ERROR); + goto err; + } + + dctx->iflags &= ~DRBG_FLAG_NOERR; + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Explicit reseed tests */ + + /* Test explicit reseed with too large additional input */ + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + if (FIPS_drbg_reseed(dctx, td->adin, dctx->max_adin + 1) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED); + goto err; + } + + /* Test explicit reseed with entropy source failure */ + + t.entlen = 0; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test explicit reseed with too much entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->max_entropy + 1; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + /* Test explicit reseed with too little entropy */ + + if (!do_drbg_init(dctx, td, &t)) + goto err; + + dctx->iflags |= DRBG_FLAG_NOERR; + + t.entlen = dctx->min_entropy - 1; + + if (FIPS_drbg_reseed(dctx, td->adin, td->adinlen) > 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_ENTROPY_ERROR_UNDETECTED); + goto err; + } + + if (!FIPS_drbg_uninstantiate(dctx)) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_UNINSTANTIATE_ERROR); + goto err; + } + + p = (unsigned char *)&dctx->d; + /* Standard says we have to check uninstantiate really zeroes + * the data... + */ + for (i = 0; i < sizeof(dctx->d); i++) { + if (*p != 0) { + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, + FIPS_R_UNINSTANTIATE_ZEROISE_ERROR); + goto err; + } + p++; + } + + return 1; + + err: + /* A real error as opposed to an induced one: underlying function will + * indicate the error. + */ + if (!(dctx->iflags & DRBG_FLAG_NOERR)) + FIPSerr(FIPS_F_FIPS_DRBG_ERROR_CHECK, FIPS_R_FUNCTION_ERROR); + FIPS_drbg_uninstantiate(dctx); + return 0; + +} + +int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags) +{ + DRBG_SELFTEST_DATA *td; + flags |= DRBG_FLAG_TEST; + for (td = drbg_test; td->nid != 0; td++) { + if (td->nid == nid && td->flags == flags) { + if (!fips_drbg_single_kat(dctx, td, 0)) + return 0; + return fips_drbg_error_check(dctx, td); + } + } + return 0; +} + +int FIPS_drbg_health_check(DRBG_CTX *dctx) +{ + int rv; + DRBG_CTX *tctx = NULL; + tctx = FIPS_drbg_new(0, 0); + fips_post_started(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + if (!tctx) + return 0; + rv = fips_drbg_kat(tctx, dctx->type, dctx->xflags); + if (tctx) + FIPS_drbg_free(tctx); + if (rv) + fips_post_success(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + else + fips_post_failed(FIPS_TEST_DRBG, dctx->type, &dctx->xflags); + if (!rv) + dctx->status = DRBG_STATUS_ERROR; + else + dctx->health_check_cnt = 0; + return rv; +} + +int FIPS_selftest_drbg(void) +{ + DRBG_CTX *dctx; + DRBG_SELFTEST_DATA *td; + int rv = 1; + dctx = FIPS_drbg_new(0, 0); + if (!dctx) + return 0; + for (td = drbg_test; td->nid != 0; td++) { + if (td->post != 1) + continue; + if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 1; + if (!fips_drbg_single_kat(dctx, td, 1)) { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 0; + } + FIPS_drbg_free(dctx); + return rv; +} + +int FIPS_selftest_drbg_all(void) +{ + DRBG_CTX *dctx; + DRBG_SELFTEST_DATA *td; + int rv = 1; + dctx = FIPS_drbg_new(0, 0); + if (!dctx) + return 0; + for (td = drbg_test; td->nid != 0; td++) { + if (!fips_post_started(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 1; + if (!fips_drbg_single_kat(dctx, td, 0)) { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_drbg_error_check(dctx, td)) { + fips_post_failed(FIPS_TEST_DRBG, td->nid, &td->flags); + rv = 0; + continue; + } + if (!fips_post_success(FIPS_TEST_DRBG, td->nid, &td->flags)) + return 0; + } + FIPS_drbg_free(dctx); + return rv; +} diff --git a/crypto/fips/fips_drbg_selftest.h b/crypto/fips/fips_drbg_selftest.h new file mode 100644 index 0000000..ccc1898 --- /dev/null +++ b/crypto/fips/fips_drbg_selftest.h @@ -0,0 +1,1791 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core.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. + * + */ + +/* Selftest and health check data for the SP800-90 DRBG */ + +#define __fips_constseg + +/* AES-128 use df PR */ +__fips_constseg static const unsigned char aes_128_use_df_pr_entropyinput[] = { + 0x61, 0x52, 0x7c, 0xe3, 0x23, 0x7d, 0x0a, 0x07, 0x10, 0x0c, 0x50, 0x33, + 0xc8, 0xdb, 0xff, 0x12 +}; + +__fips_constseg static const unsigned char aes_128_use_df_pr_nonce[] = { + 0x51, 0x0d, 0x85, 0x77, 0xed, 0x22, 0x97, 0x28 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_pr_personalizationstring[] = { + 0x59, 0x9f, 0xbb, 0xcd, 0xd5, 0x25, 0x69, 0xb5, 0xcb, 0xb5, 0x03, 0xfe, + 0xd7, 0xd7, 0x01, 0x67 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_pr_additionalinput[] = { + 0xef, 0x88, 0x76, 0x01, 0xaf, 0x3c, 0xfe, 0x8b, 0xaf, 0x26, 0x06, 0x9e, + 0x9a, 0x47, 0x08, 0x76 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_pr_entropyinputpr[] = { + 0xe2, 0x76, 0xf9, 0xf6, 0x3a, 0xba, 0x10, 0x9f, 0xbf, 0x47, 0x0e, 0x51, + 0x09, 0xfb, 0xa3, 0xb6 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_pr_int_returnedbits[] = { + 0xd4, 0x98, 0x8a, 0x46, 0x80, 0x4c, 0xdb, 0xa3, 0x59, 0x02, 0x57, 0x52, + 0x66, 0x1c, 0xea, 0x5b +}; + +__fips_constseg + static const unsigned char aes_128_use_df_pr_additionalinput2[] = { + 0x88, 0x8c, 0x91, 0xd6, 0xbe, 0x56, 0x6e, 0x08, 0x9a, 0x62, 0x2b, 0x11, + 0x3f, 0x5e, 0x31, 0x06 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_pr_entropyinputpr2[] = { + 0xc0, 0x5c, 0x6b, 0x98, 0x01, 0x0d, 0x58, 0x18, 0x51, 0x18, 0x96, 0xae, + 0xa7, 0xe3, 0xa8, 0x67 +}; + +__fips_constseg static const unsigned char aes_128_use_df_pr_returnedbits[] = { + 0xcf, 0x01, 0xac, 0x22, 0x31, 0x06, 0x8e, 0xfc, 0xce, 0x56, 0xea, 0x24, + 0x0f, 0x38, 0x43, 0xc6 +}; + +/* AES-128 use df No PR */ +__fips_constseg static const unsigned char aes_128_use_df_entropyinput[] = { + 0x1f, 0x8e, 0x34, 0x82, 0x0c, 0xb7, 0xbe, 0xc5, 0x01, 0x3e, 0xd0, 0xa3, + 0x9d, 0x7d, 0x1c, 0x9b +}; + +__fips_constseg static const unsigned char aes_128_use_df_nonce[] = { + 0xd5, 0x4d, 0xbd, 0x4a, 0x93, 0x7f, 0xb8, 0x96 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_personalizationstring[] = { + 0xab, 0xd6, 0x3f, 0x04, 0xfe, 0x27, 0x6b, 0x2d, 0xd7, 0xc3, 0x1c, 0xf3, + 0x38, 0x66, 0xba, 0x1b +}; + +__fips_constseg static const unsigned char aes_128_use_df_additionalinput[] = { + 0xfe, 0xf4, 0x09, 0xa8, 0xb7, 0x73, 0x27, 0x9c, 0x5f, 0xa7, 0xea, 0x46, + 0xb5, 0xe2, 0xb2, 0x41 +}; + +__fips_constseg static const unsigned char aes_128_use_df_int_returnedbits[] = { + 0x42, 0xe4, 0x4e, 0x7b, 0x27, 0xdd, 0xcb, 0xbc, 0x0a, 0xcf, 0xa6, 0x67, + 0xe7, 0x57, 0x11, 0xb4 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_entropyinputreseed[] = { + 0x14, 0x26, 0x69, 0xd9, 0xf3, 0x65, 0x03, 0xd6, 0x6b, 0xb9, 0x44, 0x0b, + 0xc7, 0xc4, 0x9e, 0x39 +}; + +__fips_constseg + static const unsigned char aes_128_use_df_additionalinputreseed[] = { + 0x55, 0x2e, 0x60, 0x9a, 0x05, 0x72, 0x8a, 0xa8, 0xef, 0x22, 0x81, 0x5a, + 0xc8, 0x93, 0xfa, 0x84 +}; + +__fips_constseg static const unsigned char aes_128_use_df_additionalinput2[] = { + 0x3c, 0x40, 0xc8, 0xc4, 0x16, 0x0c, 0x21, 0xa4, 0x37, 0x2c, 0x8f, 0xa5, + 0x06, 0x0c, 0x15, 0x2c +}; + +__fips_constseg static const unsigned char aes_128_use_df_returnedbits[] = { + 0xe1, 0x3e, 0x99, 0x98, 0x86, 0x67, 0x0b, 0x63, 0x7b, 0xbe, 0x3f, 0x88, + 0x46, 0x81, 0xc7, 0x19 +}; + +/* AES-192 use df PR */ +__fips_constseg static const unsigned char aes_192_use_df_pr_entropyinput[] = { + 0x2b, 0x4e, 0x8b, 0xe1, 0xf1, 0x34, 0x80, 0x56, 0x81, 0xf9, 0x74, 0xec, + 0x17, 0x44, 0x2a, 0xf1, 0x14, 0xb0, 0xbf, 0x97, 0x39, 0xb7, 0x04, 0x7d +}; + +__fips_constseg static const unsigned char aes_192_use_df_pr_nonce[] = { + 0xd6, 0x9d, 0xeb, 0x14, 0x4e, 0x6c, 0x30, 0x1e, 0x39, 0x55, 0x73, 0xd0, + 0xd1, 0x80, 0x78, 0xfa +}; + +__fips_constseg + static const unsigned char aes_192_use_df_pr_personalizationstring[] = { + 0xfc, 0x43, 0x4a, 0xf8, 0x9a, 0x55, 0xb3, 0x53, 0x83, 0xe2, 0x18, 0x16, + 0x0c, 0xdc, 0xcd, 0x5e, 0x4f, 0xa0, 0x03, 0x01, 0x2b, 0x9f, 0xe4, 0xd5, + 0x7d, 0x49, 0xf0, 0x41, 0x9e, 0x3d, 0x99, 0x04 +}; + +__fips_constseg + static const unsigned char aes_192_use_df_pr_additionalinput[] = { + 0x5e, 0x9f, 0x49, 0x6f, 0x21, 0x8b, 0x1d, 0x32, 0xd5, 0x84, 0x5c, 0xac, + 0xaf, 0xdf, 0xe4, 0x79, 0x9e, 0xaf, 0xa9, 0x82, 0xd0, 0xf8, 0x4f, 0xcb, + 0x69, 0x10, 0x0a, 0x7e, 0x81, 0x57, 0xb5, 0x36 +}; + +__fips_constseg + static const unsigned char aes_192_use_df_pr_entropyinputpr[] = { + 0xd4, 0x81, 0x0c, 0xd7, 0x66, 0x39, 0xec, 0x42, 0x53, 0x87, 0x41, 0xa5, + 0x1e, 0x7d, 0x80, 0x91, 0x8e, 0xbb, 0xed, 0xac, 0x14, 0x02, 0x1a, 0xd5 +}; + +__fips_constseg + static const unsigned char aes_192_use_df_pr_int_returnedbits[] = { + 0xdf, 0x1d, 0x39, 0x45, 0x7c, 0x9b, 0xc6, 0x2b, 0x7d, 0x8c, 0x93, 0xe9, + 0x19, 0x30, 0x6b, 0x67 +}; + +__fips_constseg + static const unsigned char aes_192_use_df_pr_additionalinput2[] = { + 0x00, 0x71, 0x27, 0x4e, 0xd3, 0x14, 0xf1, 0x20, 0x7f, 0x4a, 0x41, 0x32, + 0x2a, 0x97, 0x11, 0x43, 0x8f, 0x4a, 0x15, 0x7b, 0x9b, 0x51, 0x79, 0xda, + 0x49, 0x3d, 0xde, 0xe8, 0xbc, 0x93, 0x91, 0x99 +}; + +__fips_constseg + static const unsigned char aes_192_use_df_pr_entropyinputpr2[] = { + 0x90, 0xee, 0x76, 0xa1, 0x45, 0x8d, 0xb7, 0x40, 0xb0, 0x11, 0xbf, 0xd0, + 0x65, 0xd7, 0x3c, 0x7c, 0x4f, 0x20, 0x3f, 0x4e, 0x11, 0x9d, 0xb3, 0x5e +}; + +__fips_constseg static const unsigned char aes_192_use_df_pr_returnedbits[] = { + 0x24, 0x3b, 0x20, 0xa4, 0x37, 0x66, 0xba, 0x72, 0x39, 0x3f, 0xcf, 0x3c, + 0x7e, 0x1a, 0x2b, 0x83 +}; + +/* AES-192 use df No PR */ +__fips_constseg static const unsigned char aes_192_use_df_entropyinput[] = { + 0x8d, 0x74, 0xa4, 0x50, 0x1a, 0x02, 0x68, 0x0c, 0x2a, 0x69, 0xc4, 0x82, + 0x3b, 0xbb, 0xda, 0x0e, 0x7f, 0x77, 0xa3, 0x17, 0x78, 0x57, 0xb2, 0x7b +}; + +__fips_constseg static const unsigned char aes_192_use_df_nonce[] = { + 0x75, 0xd5, 0x1f, 0xac, 0xa4, 0x8d, 0x42, 0x78, 0xd7, 0x69, 0x86, 0x9d, + 0x77, 0xd7, 0x41, 0x0e +}; + +__fips_constseg + static const unsigned char aes_192_use_df_personalizationstring[] = { + 0x4e, 0x33, 0x41, 0x3c, 0x9c, 0xc2, 0xd2, 0x53, 0xaf, 0x90, 0xea, 0xcf, + 0x19, 0x50, 0x1e, 0xe6, 0x6f, 0x63, 0xc8, 0x32, 0x22, 0xdc, 0x07, 0x65, + 0x9c, 0xd3, 0xf8, 0x30, 0x9e, 0xed, 0x35, 0x70 +}; + +__fips_constseg static const unsigned char aes_192_use_df_additionalinput[] = { + 0x5d, 0x8b, 0x8c, 0xc1, 0xdf, 0x0e, 0x02, 0x78, 0xfb, 0x19, 0xb8, 0x69, + 0x78, 0x4e, 0x9c, 0x52, 0xbc, 0xc7, 0x20, 0xc9, 0xe6, 0x5e, 0x77, 0x22, + 0x28, 0x3d, 0x0c, 0x9e, 0x68, 0xa8, 0x45, 0xd7 +}; + +__fips_constseg static const unsigned char aes_192_use_df_int_returnedbits[] = { + 0xd5, 0xe7, 0x08, 0xc5, 0x19, 0x99, 0xd5, 0x31, 0x03, 0x0a, 0x74, 0xb6, + 0xb7, 0xed, 0xe9, 0xea +}; + +__fips_constseg + static const unsigned char aes_192_use_df_entropyinputreseed[] = { + 0x9c, 0x26, 0xda, 0xf1, 0xac, 0xd9, 0x5a, 0xd6, 0xa8, 0x65, 0xf5, 0x02, + 0x8f, 0xdc, 0xa2, 0x09, 0x54, 0xa6, 0xe2, 0xa4, 0xde, 0x32, 0xe0, 0x01 +}; + +__fips_constseg + static const unsigned char aes_192_use_df_additionalinputreseed[] = { + 0x9b, 0x90, 0xb0, 0x3a, 0x0e, 0x3a, 0x80, 0x07, 0x4a, 0xf4, 0xda, 0x76, + 0x28, 0x30, 0x3c, 0xee, 0x54, 0x1b, 0x94, 0x59, 0x51, 0x43, 0x56, 0x77, + 0xaf, 0x88, 0xdd, 0x63, 0x89, 0x47, 0x06, 0x65 +}; + +__fips_constseg static const unsigned char aes_192_use_df_additionalinput2[] = { + 0x3c, 0x11, 0x64, 0x7a, 0x96, 0xf5, 0xd8, 0xb8, 0xae, 0xd6, 0x70, 0x4e, + 0x16, 0x96, 0xde, 0xe9, 0x62, 0xbc, 0xee, 0x28, 0x2f, 0x26, 0xa6, 0xf0, + 0x56, 0xef, 0xa3, 0xf1, 0x6b, 0xa1, 0xb1, 0x77 +}; + +__fips_constseg static const unsigned char aes_192_use_df_returnedbits[] = { + 0x0b, 0xe2, 0x56, 0x03, 0x1e, 0xdb, 0x2c, 0x6d, 0x7f, 0x1b, 0x15, 0x58, + 0x1a, 0xf9, 0x13, 0x28 +}; + +/* AES-256 use df PR */ +__fips_constseg static const unsigned char aes_256_use_df_pr_entropyinput[] = { + 0x61, 0x68, 0xfc, 0x1a, 0xf0, 0xb5, 0x95, 0x6b, 0x85, 0x09, 0x9b, 0x74, + 0x3f, 0x13, 0x78, 0x49, 0x3b, 0x85, 0xec, 0x93, 0x13, 0x3b, 0xa9, 0x4f, + 0x96, 0xab, 0x2c, 0xe4, 0xc8, 0x8f, 0xdd, 0x6a +}; + +__fips_constseg static const unsigned char aes_256_use_df_pr_nonce[] = { + 0xad, 0xd2, 0xbb, 0xba, 0xb7, 0x65, 0x89, 0xc3, 0x21, 0x6c, 0x55, 0x33, + 0x2b, 0x36, 0xff, 0xa4 +}; + +__fips_constseg + static const unsigned char aes_256_use_df_pr_personalizationstring[] = { + 0x6e, 0xca, 0xe7, 0x20, 0x72, 0xd3, 0x84, 0x5a, 0x32, 0xd3, 0x4b, 0x24, + 0x72, 0xc4, 0x63, 0x2b, 0x9d, 0x12, 0x24, 0x0c, 0x23, 0x26, 0x8e, 0x83, + 0x16, 0x37, 0x0b, 0xd1, 0x06, 0x4f, 0x68, 0x6d +}; + +__fips_constseg + static const unsigned char aes_256_use_df_pr_additionalinput[] = { + 0x7e, 0x08, 0x4a, 0xbb, 0xe3, 0x21, 0x7c, 0xc9, 0x23, 0xd2, 0xf8, 0xb0, + 0x73, 0x98, 0xba, 0x84, 0x74, 0x23, 0xab, 0x06, 0x8a, 0xe2, 0x22, 0xd3, + 0x7b, 0xce, 0x9b, 0xd2, 0x4a, 0x76, 0xb8, 0xde +}; + +__fips_constseg + static const unsigned char aes_256_use_df_pr_entropyinputpr[] = { + 0x0b, 0x23, 0xaf, 0xdf, 0xf1, 0x62, 0xd7, 0xd3, 0x43, 0x97, 0xf8, 0x77, + 0x04, 0xa8, 0x42, 0x20, 0xbd, 0xf6, 0x0f, 0xc1, 0x17, 0x2f, 0x9f, 0x54, + 0xbb, 0x56, 0x17, 0x86, 0x68, 0x0e, 0xba, 0xa9 +}; + +__fips_constseg + static const unsigned char aes_256_use_df_pr_int_returnedbits[] = { + 0x31, 0x8e, 0xad, 0xaf, 0x40, 0xeb, 0x6b, 0x74, 0x31, 0x46, 0x80, 0xc7, + 0x17, 0xab, 0x3c, 0x7a +}; + +__fips_constseg + static const unsigned char aes_256_use_df_pr_additionalinput2[] = { + 0x94, 0x6b, 0xc9, 0x9f, 0xab, 0x8d, 0xc5, 0xec, 0x71, 0x88, 0x1d, 0x00, + 0x8c, 0x89, 0x68, 0xe4, 0xc8, 0x07, 0x77, 0x36, 0x17, 0x6d, 0x79, 0x78, + 0xc7, 0x06, 0x4e, 0x99, 0x04, 0x28, 0x29, 0xc3 +}; + +__fips_constseg + static const unsigned char aes_256_use_df_pr_entropyinputpr2[] = { + 0xbf, 0x6c, 0x59, 0x2a, 0x0d, 0x44, 0x0f, 0xae, 0x9a, 0x5e, 0x03, 0x73, + 0xd8, 0xa6, 0xe1, 0xcf, 0x25, 0x61, 0x38, 0x24, 0x86, 0x9e, 0x53, 0xe8, + 0xa4, 0xdf, 0x56, 0xf4, 0x06, 0x07, 0x9c, 0x0f +}; + +__fips_constseg static const unsigned char aes_256_use_df_pr_returnedbits[] = { + 0x22, 0x4a, 0xb4, 0xb8, 0xb6, 0xee, 0x7d, 0xb1, 0x9e, 0xc9, 0xf9, 0xa0, + 0xd9, 0xe2, 0x97, 0x00 +}; + +/* AES-256 use df No PR */ +__fips_constseg static const unsigned char aes_256_use_df_entropyinput[] = { + 0xa5, 0x3e, 0x37, 0x10, 0x17, 0x43, 0x91, 0x93, 0x59, 0x1e, 0x47, 0x50, + 0x87, 0xaa, 0xdd, 0xd5, 0xc1, 0xc3, 0x86, 0xcd, 0xca, 0x0d, 0xdb, 0x68, + 0xe0, 0x02, 0xd8, 0x0f, 0xdc, 0x40, 0x1a, 0x47 +}; + +__fips_constseg static const unsigned char aes_256_use_df_nonce[] = { + 0xa9, 0x4d, 0xa5, 0x5a, 0xfd, 0xc5, 0x0c, 0xe5, 0x1c, 0x9a, 0x3b, 0x8a, + 0x4c, 0x44, 0x84, 0x40 +}; + +__fips_constseg + static const unsigned char aes_256_use_df_personalizationstring[] = { + 0x8b, 0x52, 0xa2, 0x4a, 0x93, 0xc3, 0x4e, 0xa7, 0x1e, 0x1c, 0xa7, 0x05, + 0xeb, 0x82, 0x9b, 0xa6, 0x5d, 0xe4, 0xd4, 0xe0, 0x7f, 0xa3, 0xd8, 0x6b, + 0x37, 0x84, 0x5f, 0xf1, 0xc7, 0xd5, 0xf6, 0xd2 +}; + +__fips_constseg static const unsigned char aes_256_use_df_additionalinput[] = { + 0x20, 0xf4, 0x22, 0xed, 0xf8, 0x5c, 0xa1, 0x6a, 0x01, 0xcf, 0xbe, 0x5f, + 0x8d, 0x6c, 0x94, 0x7f, 0xae, 0x12, 0xa8, 0x57, 0xdb, 0x2a, 0xa9, 0xbf, + 0xc7, 0xb3, 0x65, 0x81, 0x80, 0x8d, 0x0d, 0x46 +}; + +__fips_constseg static const unsigned char aes_256_use_df_int_returnedbits[] = { + 0x4e, 0x44, 0xfd, 0xf3, 0x9e, 0x29, 0xa2, 0xb8, 0x0f, 0x5d, 0x6c, 0xe1, + 0x28, 0x0c, 0x3b, 0xc1 +}; + +__fips_constseg + static const unsigned char aes_256_use_df_entropyinputreseed[] = { + 0xdd, 0x40, 0xe5, 0x98, 0x7b, 0x27, 0x16, 0x73, 0x15, 0x68, 0xd2, 0x76, + 0xbf, 0x0c, 0x67, 0x15, 0x75, 0x79, 0x03, 0xd3, 0xde, 0xde, 0x91, 0x46, + 0x42, 0xdd, 0xd4, 0x67, 0xc8, 0x79, 0xc8, 0x1e +}; + +__fips_constseg + static const unsigned char aes_256_use_df_additionalinputreseed[] = { + 0x7f, 0xd8, 0x1f, 0xbd, 0x2a, 0xb5, 0x1c, 0x11, 0x5d, 0x83, 0x4e, 0x99, + 0xf6, 0x5c, 0xa5, 0x40, 0x20, 0xed, 0x38, 0x8e, 0xd5, 0x9e, 0xe0, 0x75, + 0x93, 0xfe, 0x12, 0x5e, 0x5d, 0x73, 0xfb, 0x75 +}; + +__fips_constseg static const unsigned char aes_256_use_df_additionalinput2[] = { + 0xcd, 0x2c, 0xff, 0x14, 0x69, 0x3e, 0x4c, 0x9e, 0xfd, 0xfe, 0x26, 0x0d, + 0xe9, 0x86, 0x00, 0x49, 0x30, 0xba, 0xb1, 0xc6, 0x50, 0x57, 0x77, 0x2a, + 0x62, 0x39, 0x2c, 0x3b, 0x74, 0xeb, 0xc9, 0x0d +}; + +__fips_constseg static const unsigned char aes_256_use_df_returnedbits[] = { + 0x4f, 0x78, 0xbe, 0xb9, 0x4d, 0x97, 0x8c, 0xe9, 0xd0, 0x97, 0xfe, 0xad, + 0xfa, 0xfd, 0x35, 0x5e +}; + +/* AES-128 no df PR */ +__fips_constseg static const unsigned char aes_128_no_df_pr_entropyinput[] = { + 0x9a, 0x25, 0x65, 0x10, 0x67, 0xd5, 0xb6, 0x6b, 0x70, 0xa1, 0xb3, 0xa4, + 0x43, 0x95, 0x80, 0xc0, 0x84, 0x0a, 0x79, 0xb0, 0x88, 0x74, 0xf2, 0xbf, + 0x31, 0x6c, 0x33, 0x38, 0x0b, 0x00, 0xb2, 0x5a +}; + +__fips_constseg static const unsigned char aes_128_no_df_pr_nonce[] = { + 0x78, 0x47, 0x6b, 0xf7, 0x90, 0x8e, 0x87, 0xf1 +}; + +__fips_constseg + static const unsigned char aes_128_no_df_pr_personalizationstring[] = { + 0xf7, 0x22, 0x1d, 0x3a, 0xbe, 0x1d, 0xca, 0x32, 0x1b, 0xbd, 0x87, 0x0c, + 0x51, 0x24, 0x19, 0xee, 0xa3, 0x23, 0x09, 0x63, 0x33, 0x3d, 0xa8, 0x0c, + 0x1c, 0xfa, 0x42, 0x89, 0xcc, 0x6f, 0xa0, 0xa8 +}; + +__fips_constseg + static const unsigned char aes_128_no_df_pr_additionalinput[] = { + 0xc9, 0xe0, 0x80, 0xbf, 0x8c, 0x45, 0x58, 0x39, 0xff, 0x00, 0xab, 0x02, + 0x4c, 0x3e, 0x3a, 0x95, 0x9b, 0x80, 0xa8, 0x21, 0x2a, 0xee, 0xba, 0x73, + 0xb1, 0xd9, 0xcf, 0x28, 0xf6, 0x8f, 0x9b, 0x12 +}; + +__fips_constseg static const unsigned char aes_128_no_df_pr_entropyinputpr[] = { + 0x4c, 0xa8, 0xc5, 0xf0, 0x59, 0x9e, 0xa6, 0x8d, 0x26, 0x53, 0xd7, 0x8a, + 0xa9, 0xd8, 0xf7, 0xed, 0xb2, 0xf9, 0x12, 0x42, 0xe1, 0xe5, 0xbd, 0xe7, + 0xe7, 0x1d, 0x74, 0x99, 0x00, 0x9d, 0x31, 0x3e +}; + +__fips_constseg + static const unsigned char aes_128_no_df_pr_int_returnedbits[] = { + 0xe2, 0xac, 0x20, 0xf0, 0x80, 0xe7, 0xbc, 0x7e, 0x9c, 0x7b, 0x65, 0x71, + 0xaf, 0x19, 0x32, 0x16 +}; + +__fips_constseg + static const unsigned char aes_128_no_df_pr_additionalinput2[] = { + 0x32, 0x7f, 0x38, 0x8b, 0x73, 0x0a, 0x78, 0x83, 0xdc, 0x30, 0xbe, 0x9f, + 0x10, 0x1f, 0xf5, 0x1f, 0xca, 0x00, 0xb5, 0x0d, 0xd6, 0x9d, 0x60, 0x83, + 0x51, 0x54, 0x7d, 0x38, 0x23, 0x3a, 0x52, 0x50 +}; + +__fips_constseg + static const unsigned char aes_128_no_df_pr_entropyinputpr2[] = { + 0x18, 0x61, 0x53, 0x56, 0xed, 0xed, 0xd7, 0x20, 0xfb, 0x71, 0x04, 0x7a, + 0xb2, 0xac, 0xc1, 0x28, 0xcd, 0xf2, 0xc2, 0xfc, 0xaa, 0xb1, 0x06, 0x07, + 0xe9, 0x46, 0x95, 0x02, 0x48, 0x01, 0x78, 0xf9 +}; + +__fips_constseg static const unsigned char aes_128_no_df_pr_returnedbits[] = { + 0x29, 0xc8, 0x1b, 0x15, 0xb1, 0xd1, 0xc2, 0xf6, 0x71, 0x86, 0x68, 0x33, + 0x57, 0x82, 0x33, 0xaf +}; + +/* AES-128 no df No PR */ +__fips_constseg static const unsigned char aes_128_no_df_entropyinput[] = { + 0xc9, 0xc5, 0x79, 0xbc, 0xe8, 0xc5, 0x19, 0xd8, 0xbc, 0x66, 0x73, 0x67, + 0xf6, 0xd3, 0x72, 0xaa, 0xa6, 0x16, 0xb8, 0x50, 0xb7, 0x47, 0x3a, 0x42, + 0xab, 0xf4, 0x16, 0xb2, 0x96, 0xd2, 0xb6, 0x60 +}; + +__fips_constseg static const unsigned char aes_128_no_df_nonce[] = { + 0x5f, 0xbf, 0x97, 0x0c, 0x4b, 0xa4, 0x87, 0x13 +}; + +__fips_constseg + static const unsigned char aes_128_no_df_personalizationstring[] = { + 0xce, 0xfb, 0x7b, 0x3f, 0xd4, 0x6b, 0x29, 0x0d, 0x69, 0x06, 0xff, 0xbb, + 0xf2, 0xe5, 0xc6, 0x6c, 0x0a, 0x10, 0xa0, 0xcf, 0x1a, 0x48, 0xc7, 0x8b, + 0x3c, 0x16, 0x88, 0xed, 0x50, 0x13, 0x81, 0xce +}; + +__fips_constseg static const unsigned char aes_128_no_df_additionalinput[] = { + 0x4b, 0x22, 0x46, 0x18, 0x02, 0x7b, 0xd2, 0x1b, 0x22, 0x42, 0x7c, 0x37, + 0xd9, 0xf6, 0xe8, 0x9b, 0x12, 0x30, 0x5f, 0xe9, 0x90, 0xe8, 0x08, 0x24, + 0x4f, 0x06, 0x66, 0xdb, 0x19, 0x2b, 0x13, 0x95 +}; + +__fips_constseg static const unsigned char aes_128_no_df_int_returnedbits[] = { + 0x2e, 0x96, 0x70, 0x64, 0xfa, 0xdf, 0xdf, 0x57, 0xb5, 0x82, 0xee, 0xd6, + 0xed, 0x3e, 0x65, 0xc2 +}; + +__fips_constseg + static const unsigned char aes_128_no_df_entropyinputreseed[] = { + 0x26, 0xc0, 0x72, 0x16, 0x3a, 0x4b, 0xb7, 0x99, 0xd4, 0x07, 0xaf, 0x66, + 0x62, 0x36, 0x96, 0xa4, 0x51, 0x17, 0xfa, 0x07, 0x8b, 0x17, 0x5e, 0xa1, + 0x2f, 0x3c, 0x10, 0xe7, 0x90, 0xd0, 0x46, 0x00 +}; + +__fips_constseg + static const unsigned char aes_128_no_df_additionalinputreseed[] = { + 0x83, 0x39, 0x37, 0x7b, 0x02, 0x06, 0xd2, 0x12, 0x13, 0x8d, 0x8b, 0xf2, + 0xf0, 0xf6, 0x26, 0xeb, 0xa4, 0x22, 0x7b, 0xc2, 0xe7, 0xba, 0x79, 0xe4, + 0x3b, 0x77, 0x5d, 0x4d, 0x47, 0xb2, 0x2d, 0xb4 +}; + +__fips_constseg static const unsigned char aes_128_no_df_additionalinput2[] = { + 0x0b, 0xb9, 0x67, 0x37, 0xdb, 0x83, 0xdf, 0xca, 0x81, 0x8b, 0xf9, 0x3f, + 0xf1, 0x11, 0x1b, 0x2f, 0xf0, 0x61, 0xa6, 0xdf, 0xba, 0xa3, 0xb1, 0xac, + 0xd3, 0xe6, 0x09, 0xb8, 0x2c, 0x6a, 0x67, 0xd6 +}; + +__fips_constseg static const unsigned char aes_128_no_df_returnedbits[] = { + 0x1e, 0xa7, 0xa4, 0xe4, 0xe1, 0xa6, 0x7c, 0x69, 0x9a, 0x44, 0x6c, 0x36, + 0x81, 0x37, 0x19, 0xd4 +}; + +/* AES-192 no df PR */ +__fips_constseg static const unsigned char aes_192_no_df_pr_entropyinput[] = { + 0x9d, 0x2c, 0xd2, 0x55, 0x66, 0xea, 0xe0, 0xbe, 0x18, 0xb7, 0x76, 0xe7, + 0x73, 0x35, 0xd8, 0x1f, 0xad, 0x3a, 0xe3, 0x81, 0x0e, 0x92, 0xd0, 0x61, + 0xc9, 0x12, 0x26, 0xf6, 0x1c, 0xdf, 0xfe, 0x47, 0xaa, 0xfe, 0x7d, 0x5a, + 0x17, 0x1f, 0x8d, 0x9a +}; + +__fips_constseg static const unsigned char aes_192_no_df_pr_nonce[] = { + 0x44, 0x82, 0xed, 0xe8, 0x4c, 0x28, 0x5a, 0x14, 0xff, 0x88, 0x8d, 0x19, + 0x61, 0x5c, 0xee, 0x0f +}; + +__fips_constseg + static const unsigned char aes_192_no_df_pr_personalizationstring[] = { + 0x47, 0xd7, 0x9b, 0x99, 0xaa, 0xcb, 0xe7, 0xd2, 0x57, 0x66, 0x2c, 0xe1, + 0x78, 0xd6, 0x2c, 0xea, 0xa3, 0x23, 0x5f, 0x2a, 0xc1, 0x3a, 0xf0, 0xa4, + 0x20, 0x3b, 0xfa, 0x07, 0xd5, 0x05, 0x02, 0xe4, 0x57, 0x01, 0xb6, 0x10, + 0x57, 0x2e, 0xe7, 0x55 +}; + +__fips_constseg + static const unsigned char aes_192_no_df_pr_additionalinput[] = { + 0x4b, 0x74, 0x0b, 0x40, 0xce, 0x6b, 0xc2, 0x6a, 0x24, 0xb4, 0xf3, 0xad, + 0x7a, 0xa5, 0x7a, 0xa2, 0x15, 0xe2, 0xc8, 0x61, 0x15, 0xc6, 0xb7, 0x85, + 0x69, 0x11, 0xad, 0x7b, 0x14, 0xd2, 0xf6, 0x12, 0xa1, 0x95, 0x5d, 0x3f, + 0xe2, 0xd0, 0x0c, 0x2f +}; + +__fips_constseg static const unsigned char aes_192_no_df_pr_entropyinputpr[] = { + 0x0c, 0x9c, 0xad, 0x05, 0xee, 0xae, 0x48, 0x23, 0x89, 0x59, 0xa1, 0x94, + 0xd7, 0xd8, 0x75, 0xd5, 0x54, 0x93, 0xc7, 0x4a, 0xd9, 0x26, 0xde, 0xeb, + 0xba, 0xb0, 0x7e, 0x30, 0x1d, 0x5f, 0x69, 0x40, 0x9c, 0x3b, 0x17, 0x58, + 0x1d, 0x30, 0xb3, 0x78 +}; + +__fips_constseg + static const unsigned char aes_192_no_df_pr_int_returnedbits[] = { + 0xf7, 0x93, 0xb0, 0x6d, 0x77, 0x83, 0xd5, 0x38, 0x01, 0xe1, 0x52, 0x40, + 0x7e, 0x3e, 0x0c, 0x26 +}; + +__fips_constseg + static const unsigned char aes_192_no_df_pr_additionalinput2[] = { + 0xbc, 0x4b, 0x37, 0x44, 0x1c, 0xc5, 0x45, 0x5f, 0x8f, 0x51, 0x62, 0x8a, + 0x85, 0x30, 0x1d, 0x7c, 0xe4, 0xcf, 0xf7, 0x44, 0xce, 0x32, 0x3e, 0x57, + 0x95, 0xa4, 0x2a, 0xdf, 0xfd, 0x9e, 0x38, 0x41, 0xb3, 0xf6, 0xc5, 0xee, + 0x0c, 0x4b, 0xee, 0x6e +}; + +__fips_constseg + static const unsigned char aes_192_no_df_pr_entropyinputpr2[] = { + 0xec, 0xaf, 0xf6, 0x4f, 0xb1, 0xa0, 0x54, 0xb5, 0x5b, 0xe3, 0x46, 0xb0, + 0x76, 0x5a, 0x7c, 0x3f, 0x7b, 0x94, 0x69, 0x21, 0x51, 0x02, 0xe5, 0x9f, + 0x04, 0x59, 0x02, 0x98, 0xc6, 0x43, 0x2c, 0xcc, 0x26, 0x4c, 0x87, 0x6b, + 0x8e, 0x0a, 0x83, 0xdf +}; + +__fips_constseg static const unsigned char aes_192_no_df_pr_returnedbits[] = { + 0x74, 0x45, 0xfb, 0x53, 0x84, 0x96, 0xbe, 0xff, 0x15, 0xcc, 0x41, 0x91, + 0xb9, 0xa1, 0x21, 0x68 +}; + +/* AES-192 no df No PR */ +__fips_constseg static const unsigned char aes_192_no_df_entropyinput[] = { + 0x3c, 0x7d, 0xb5, 0xe0, 0x54, 0xd9, 0x6e, 0x8c, 0xa9, 0x86, 0xce, 0x4e, + 0x6b, 0xaf, 0xeb, 0x2f, 0xe7, 0x75, 0xe0, 0x8b, 0xa4, 0x3b, 0x07, 0xfe, + 0xbe, 0x33, 0x75, 0x93, 0x80, 0x27, 0xb5, 0x29, 0x47, 0x8b, 0xc7, 0x28, + 0x94, 0xc3, 0x59, 0x63 +}; + +__fips_constseg static const unsigned char aes_192_no_df_nonce[] = { + 0x43, 0xf1, 0x7d, 0xb8, 0xc3, 0xfe, 0xd0, 0x23, 0x6b, 0xb4, 0x92, 0xdb, + 0x29, 0xfd, 0x45, 0x71 +}; + +__fips_constseg + static const unsigned char aes_192_no_df_personalizationstring[] = { + 0x9f, 0x24, 0x29, 0x99, 0x9e, 0x01, 0xab, 0xe9, 0x19, 0xd8, 0x23, 0x08, + 0xb7, 0xd6, 0x7e, 0x8c, 0xc0, 0x9e, 0x7f, 0x6e, 0x5b, 0x33, 0x20, 0x96, + 0x0b, 0x23, 0x2c, 0xa5, 0x6a, 0xf8, 0x1b, 0x04, 0x26, 0xdb, 0x2e, 0x2b, + 0x3b, 0x88, 0xce, 0x35 +}; + +__fips_constseg static const unsigned char aes_192_no_df_additionalinput[] = { + 0x94, 0xe9, 0x7c, 0x3d, 0xa7, 0xdb, 0x60, 0x83, 0x1f, 0x98, 0x3f, 0x0b, + 0x88, 0x59, 0x57, 0x51, 0x88, 0x9f, 0x76, 0x49, 0x9f, 0xa6, 0xda, 0x71, + 0x1d, 0x0d, 0x47, 0x16, 0x63, 0xc5, 0x68, 0xe4, 0x5d, 0x39, 0x69, 0xb3, + 0x3e, 0xbe, 0xd4, 0x8e +}; + +__fips_constseg static const unsigned char aes_192_no_df_int_returnedbits[] = { + 0xf9, 0xd7, 0xad, 0x69, 0xab, 0x8f, 0x23, 0x56, 0x70, 0x17, 0x4f, 0x2a, + 0x45, 0xe7, 0x4a, 0xc5 +}; + +__fips_constseg + static const unsigned char aes_192_no_df_entropyinputreseed[] = { + 0xa6, 0x71, 0x6a, 0x3d, 0xba, 0xd1, 0xe8, 0x66, 0xa6, 0xef, 0xb2, 0x0e, + 0xa8, 0x9c, 0xaa, 0x4e, 0xaf, 0x17, 0x89, 0x50, 0x00, 0xda, 0xa1, 0xb1, + 0x0b, 0xa4, 0xd9, 0x35, 0x89, 0xc8, 0xe5, 0xb0, 0xd9, 0xb7, 0xc4, 0x33, + 0x9b, 0xcb, 0x7e, 0x75 +}; + +__fips_constseg + static const unsigned char aes_192_no_df_additionalinputreseed[] = { + 0x27, 0x21, 0xfc, 0xc2, 0xbd, 0xf3, 0x3c, 0xce, 0xc3, 0xca, 0xc1, 0x01, + 0xe0, 0xff, 0x93, 0x12, 0x7d, 0x54, 0x42, 0xe3, 0x9f, 0x03, 0xdf, 0x27, + 0x04, 0x07, 0x3c, 0x53, 0x7f, 0xa8, 0x66, 0xc8, 0x97, 0x4b, 0x61, 0x40, + 0x5d, 0x7a, 0x25, 0x79 +}; + +__fips_constseg static const unsigned char aes_192_no_df_additionalinput2[] = { + 0x2d, 0x8e, 0x16, 0x5d, 0x0b, 0x9f, 0xeb, 0xaa, 0xd6, 0xec, 0x28, 0x71, + 0x7c, 0x0b, 0xc1, 0x1d, 0xd4, 0x44, 0x19, 0x47, 0xfd, 0x1d, 0x7c, 0xe5, + 0xf3, 0x27, 0xe1, 0xb6, 0x72, 0x0a, 0xe0, 0xec, 0x0e, 0xcd, 0xef, 0x1a, + 0x91, 0x6a, 0xe3, 0x5f +}; + +__fips_constseg static const unsigned char aes_192_no_df_returnedbits[] = { + 0xe5, 0xda, 0xb8, 0xe0, 0x63, 0x59, 0x5a, 0xcc, 0x3d, 0xdc, 0x9f, 0xe8, + 0x66, 0x67, 0x2c, 0x92 +}; + +/* AES-256 no df PR */ +__fips_constseg static const unsigned char aes_256_no_df_pr_entropyinput[] = { + 0x15, 0xc7, 0x5d, 0xcb, 0x41, 0x4b, 0x16, 0x01, 0x3a, 0xd1, 0x44, 0xe8, + 0x22, 0x32, 0xc6, 0x9c, 0x3f, 0xe7, 0x43, 0xf5, 0x9a, 0xd3, 0xea, 0xf2, + 0xd7, 0x4e, 0x6e, 0x6a, 0x55, 0x73, 0x40, 0xef, 0x89, 0xad, 0x0d, 0x03, + 0x96, 0x7e, 0x78, 0x81, 0x2f, 0x91, 0x1b, 0x44, 0xb0, 0x02, 0xba, 0x1c +}; + +__fips_constseg static const unsigned char aes_256_no_df_pr_nonce[] = { + 0xdc, 0xe4, 0xd4, 0x27, 0x7a, 0x90, 0xd7, 0x99, 0x43, 0xa1, 0x3c, 0x30, + 0xcc, 0x4b, 0xee, 0x2e +}; + +__fips_constseg + static const unsigned char aes_256_no_df_pr_personalizationstring[] = { + 0xe3, 0xe6, 0xb9, 0x11, 0xe4, 0x7a, 0xa4, 0x40, 0x6b, 0xf8, 0x73, 0xf7, + 0x7e, 0xec, 0xc7, 0xb9, 0x97, 0xbf, 0xf8, 0x25, 0x7b, 0xbe, 0x11, 0x9b, + 0x5b, 0x6a, 0x0c, 0x2e, 0x2b, 0x01, 0x51, 0xcd, 0x41, 0x4b, 0x6b, 0xac, + 0x31, 0xa8, 0x0b, 0xf7, 0xe6, 0x59, 0x42, 0xb8, 0x03, 0x0c, 0xf8, 0x06 +}; + +__fips_constseg + static const unsigned char aes_256_no_df_pr_additionalinput[] = { + 0x6a, 0x9f, 0x00, 0x91, 0xae, 0xfe, 0xcf, 0x84, 0x99, 0xce, 0xb1, 0x40, + 0x6d, 0x5d, 0x33, 0x28, 0x84, 0xf4, 0x8c, 0x63, 0x4c, 0x7e, 0xbd, 0x2c, + 0x80, 0x76, 0xee, 0x5a, 0xaa, 0x15, 0x07, 0x31, 0xd8, 0xbb, 0x8c, 0x69, + 0x9d, 0x9d, 0xbc, 0x7e, 0x49, 0xae, 0xec, 0x39, 0x6b, 0xd1, 0x1f, 0x7e +}; + +__fips_constseg static const unsigned char aes_256_no_df_pr_entropyinputpr[] = { + 0xf3, 0xb9, 0x75, 0x9c, 0xbd, 0x88, 0xea, 0xa2, 0x50, 0xad, 0xd6, 0x16, + 0x1a, 0x12, 0x3c, 0x86, 0x68, 0xaf, 0x6f, 0xbe, 0x19, 0xf2, 0xee, 0xcc, + 0xa5, 0x70, 0x84, 0x53, 0x50, 0xcb, 0x9f, 0x14, 0xa9, 0xe5, 0xee, 0xb9, + 0x48, 0x45, 0x40, 0xe2, 0xc7, 0xc9, 0x9a, 0x74, 0xff, 0x8c, 0x99, 0x1f +}; + +__fips_constseg + static const unsigned char aes_256_no_df_pr_int_returnedbits[] = { + 0x2e, 0xf2, 0x45, 0x4c, 0x62, 0x2e, 0x0a, 0xb9, 0x6b, 0xa2, 0xfd, 0x56, + 0x79, 0x60, 0x93, 0xcf +}; + +__fips_constseg + static const unsigned char aes_256_no_df_pr_additionalinput2[] = { + 0xaf, 0x69, 0x20, 0xe9, 0x3b, 0x37, 0x9d, 0x3f, 0xb4, 0x80, 0x02, 0x7a, + 0x25, 0x7d, 0xb8, 0xde, 0x71, 0xc5, 0x06, 0x0c, 0xb4, 0xe2, 0x8f, 0x35, + 0xd8, 0x14, 0x0d, 0x7f, 0x76, 0x63, 0x4e, 0xb5, 0xee, 0xe9, 0x6f, 0x34, + 0xc7, 0x5f, 0x56, 0x14, 0x4a, 0xe8, 0x73, 0x95, 0x5b, 0x1c, 0xb9, 0xcb +}; + +__fips_constseg + static const unsigned char aes_256_no_df_pr_entropyinputpr2[] = { + 0xe5, 0xb0, 0x2e, 0x7e, 0x52, 0x30, 0xe3, 0x63, 0x82, 0xb6, 0x44, 0xd3, + 0x25, 0x19, 0x05, 0x24, 0x9a, 0x9f, 0x5f, 0x27, 0x6a, 0x29, 0xab, 0xfa, + 0x07, 0xa2, 0x42, 0x0f, 0xc5, 0xa8, 0x94, 0x7c, 0x17, 0x7b, 0x85, 0x83, + 0x0c, 0x25, 0x0e, 0x63, 0x0b, 0xe9, 0x12, 0x60, 0xcd, 0xef, 0x80, 0x0f +}; + +__fips_constseg static const unsigned char aes_256_no_df_pr_returnedbits[] = { + 0x5e, 0xf2, 0x26, 0xef, 0x9f, 0x58, 0x5d, 0xd5, 0x4a, 0x10, 0xfe, 0xa7, + 0x2d, 0x5f, 0x4a, 0x46 +}; + +/* AES-256 no df No PR */ +__fips_constseg static const unsigned char aes_256_no_df_entropyinput[] = { + 0xfb, 0xcf, 0x1b, 0x61, 0x16, 0x89, 0x78, 0x23, 0xf5, 0xd8, 0x96, 0xe3, + 0x4e, 0x64, 0x0b, 0x29, 0x9a, 0x3f, 0xf8, 0xa5, 0xed, 0xf2, 0xfe, 0xdb, + 0x16, 0xca, 0x7f, 0x10, 0xfa, 0x5e, 0x18, 0x76, 0x2c, 0x63, 0x5e, 0x96, + 0xcf, 0xb3, 0xd6, 0xfc, 0xaf, 0x99, 0x39, 0x28, 0x9c, 0x61, 0xe8, 0xb3 +}; + +__fips_constseg static const unsigned char aes_256_no_df_nonce[] = { + 0x12, 0x96, 0xf0, 0x52, 0xf3, 0x8d, 0x81, 0xcf, 0xde, 0x86, 0xf2, 0x99, + 0x43, 0x96, 0xb9, 0xf0 +}; + +__fips_constseg + static const unsigned char aes_256_no_df_personalizationstring[] = { + 0x63, 0x0d, 0x78, 0xf5, 0x90, 0x8e, 0x32, 0x47, 0xb0, 0x4d, 0x37, 0x60, + 0x09, 0x96, 0xbc, 0xbf, 0x97, 0x7a, 0x62, 0x14, 0x45, 0xbd, 0x8d, 0xcc, + 0x69, 0xfb, 0x03, 0xe1, 0x80, 0x1c, 0xc7, 0xe2, 0x2a, 0xf9, 0x37, 0x3f, + 0x66, 0x4d, 0x62, 0xd9, 0x10, 0xe0, 0xad, 0xc8, 0x9a, 0xf0, 0xa8, 0x6d +}; + +__fips_constseg static const unsigned char aes_256_no_df_additionalinput[] = { + 0x36, 0xc6, 0x13, 0x60, 0xbb, 0x14, 0xad, 0x22, 0xb0, 0x38, 0xac, 0xa6, + 0x18, 0x16, 0x93, 0x25, 0x86, 0xb7, 0xdc, 0xdc, 0x36, 0x98, 0x2b, 0xf9, + 0x68, 0x33, 0xd3, 0xc6, 0xff, 0xce, 0x8d, 0x15, 0x59, 0x82, 0x76, 0xed, + 0x6f, 0x8d, 0x49, 0x74, 0x2f, 0xda, 0xdc, 0x1f, 0x17, 0xd0, 0xde, 0x17 +}; + +__fips_constseg static const unsigned char aes_256_no_df_int_returnedbits[] = { + 0x16, 0x2f, 0x8e, 0x3f, 0x21, 0x7a, 0x1c, 0x20, 0x56, 0xd1, 0x92, 0xf6, + 0xd2, 0x25, 0x75, 0x0e +}; + +__fips_constseg + static const unsigned char aes_256_no_df_entropyinputreseed[] = { + 0x91, 0x79, 0x76, 0xee, 0xe0, 0xcf, 0x9e, 0xc2, 0xd5, 0xd4, 0x23, 0x9b, + 0x12, 0x8c, 0x7e, 0x0a, 0xb7, 0xd2, 0x8b, 0xd6, 0x7c, 0xa3, 0xc6, 0xe5, + 0x0e, 0xaa, 0xc7, 0x6b, 0xae, 0x0d, 0xfa, 0x53, 0x06, 0x79, 0xa1, 0xed, + 0x4d, 0x6a, 0x0e, 0xd8, 0x9d, 0xbe, 0x1b, 0x31, 0x93, 0x7b, 0xec, 0xfb +}; + +__fips_constseg + static const unsigned char aes_256_no_df_additionalinputreseed[] = { + 0xd2, 0x46, 0x50, 0x22, 0x10, 0x14, 0x63, 0xf7, 0xea, 0x0f, 0xb9, 0x7e, + 0x0d, 0xe1, 0x94, 0x07, 0xaf, 0x09, 0x44, 0x31, 0xea, 0x64, 0xa4, 0x18, + 0x5b, 0xf9, 0xd8, 0xc2, 0xfa, 0x03, 0x47, 0xc5, 0x39, 0x43, 0xd5, 0x3b, + 0x62, 0x86, 0x64, 0xea, 0x2c, 0x73, 0x8c, 0xae, 0x9d, 0x98, 0x98, 0x29 +}; + +__fips_constseg static const unsigned char aes_256_no_df_additionalinput2[] = { + 0x8c, 0xab, 0x18, 0xf8, 0xc3, 0xec, 0x18, 0x5c, 0xb3, 0x1e, 0x9d, 0xbe, + 0x3f, 0x03, 0xb4, 0x00, 0x98, 0x9d, 0xae, 0xeb, 0xf4, 0x94, 0xf8, 0x42, + 0x8f, 0xe3, 0x39, 0x07, 0xe1, 0xc9, 0xad, 0x0b, 0x1f, 0xed, 0xc0, 0xba, + 0xf6, 0xd1, 0xec, 0x27, 0x86, 0x7b, 0xd6, 0x55, 0x9b, 0x60, 0xa5, 0xc6 +}; + +__fips_constseg static const unsigned char aes_256_no_df_returnedbits[] = { + 0xef, 0xd2, 0xd8, 0x5c, 0xdc, 0x62, 0x25, 0x9f, 0xaa, 0x1e, 0x2c, 0x67, + 0xf6, 0x02, 0x32, 0xe2 +}; + +/* SHA-1 PR */ +__fips_constseg static const unsigned char sha1_pr_entropyinput[] = { + 0xd2, 0x36, 0xa5, 0x27, 0x31, 0x73, 0xdd, 0x11, 0x4f, 0x93, 0xbd, 0xe2, + 0x31, 0xa5, 0x91, 0x13 +}; + +__fips_constseg static const unsigned char sha1_pr_nonce[] = { + 0xb5, 0xb3, 0x60, 0xef, 0xf7, 0x63, 0x31, 0xf3 +}; + +__fips_constseg static const unsigned char sha1_pr_personalizationstring[] = { + 0xd4, 0xbb, 0x02, 0x10, 0xb2, 0x71, 0xdb, 0x81, 0xd6, 0xf0, 0x42, 0x60, + 0xda, 0xea, 0x77, 0x52 +}; + +__fips_constseg static const unsigned char sha1_pr_additionalinput[] = { + 0x4d, 0xd2, 0x6c, 0x87, 0xfb, 0x2c, 0x4f, 0xa6, 0x8d, 0x16, 0x63, 0x22, + 0x6a, 0x51, 0xe3, 0xf8 +}; + +__fips_constseg static const unsigned char sha1_pr_entropyinputpr[] = { + 0xc9, 0x83, 0x9e, 0x16, 0xf6, 0x1c, 0x0f, 0xb2, 0xec, 0x60, 0x31, 0xa9, + 0xcb, 0xa9, 0x36, 0x7a +}; + +__fips_constseg static const unsigned char sha1_pr_int_returnedbits[] = { + 0xa8, 0x13, 0x4f, 0xf4, 0x31, 0x02, 0x44, 0xe3, 0xd3, 0x3d, 0x61, 0x9e, + 0xe5, 0xc6, 0x3e, 0x89, 0xb5, 0x9b, 0x0f, 0x35 +}; + +__fips_constseg static const unsigned char sha1_pr_additionalinput2[] = { + 0xf9, 0xe8, 0xd2, 0x72, 0x13, 0x34, 0x95, 0x6f, 0x15, 0x49, 0x47, 0x99, + 0x16, 0x03, 0x19, 0x47 +}; + +__fips_constseg static const unsigned char sha1_pr_entropyinputpr2[] = { + 0x4e, 0x8c, 0x49, 0x9b, 0x4a, 0x5c, 0x9b, 0x9c, 0x3a, 0xee, 0xfb, 0xd2, + 0xae, 0xcd, 0x8c, 0xc4 +}; + +__fips_constseg static const unsigned char sha1_pr_returnedbits[] = { + 0x50, 0xb4, 0xb4, 0xcd, 0x68, 0x57, 0xfc, 0x2e, 0xc1, 0x52, 0xcc, 0xf6, + 0x68, 0xa4, 0x81, 0xed, 0x7e, 0xe4, 0x1d, 0x87 +}; + +/* SHA-1 No PR */ +__fips_constseg static const unsigned char sha1_entropyinput[] = { + 0xa9, 0x47, 0x1b, 0x29, 0x2d, 0x1c, 0x05, 0xdf, 0x76, 0xd0, 0x62, 0xf9, + 0xe2, 0x7f, 0x4c, 0x7b +}; + +__fips_constseg static const unsigned char sha1_nonce[] = { + 0x53, 0x23, 0x24, 0xe3, 0xec, 0x0c, 0x54, 0x14 +}; + +__fips_constseg static const unsigned char sha1_personalizationstring[] = { + 0x7a, 0x87, 0xa1, 0xac, 0x1c, 0xfd, 0xab, 0xae, 0xf7, 0xd6, 0xfb, 0x76, + 0x28, 0xec, 0x6d, 0xca +}; + +__fips_constseg static const unsigned char sha1_additionalinput[] = { + 0xfc, 0x92, 0x35, 0xd6, 0x7e, 0xb7, 0x24, 0x65, 0xfd, 0x12, 0x27, 0x35, + 0xc0, 0x72, 0xca, 0x28 +}; + +__fips_constseg static const unsigned char sha1_int_returnedbits[] = { + 0x57, 0x88, 0x82, 0xe5, 0x25, 0xa5, 0x2c, 0x4a, 0x06, 0x20, 0x6c, 0x72, + 0x55, 0x61, 0xdd, 0x90, 0x71, 0x9f, 0x95, 0xea +}; + +__fips_constseg static const unsigned char sha1_entropyinputreseed[] = { + 0x69, 0xa5, 0x40, 0x62, 0x98, 0x47, 0x56, 0x73, 0x4a, 0x8f, 0x60, 0x96, + 0xd6, 0x99, 0x27, 0xed +}; + +__fips_constseg static const unsigned char sha1_additionalinputreseed[] = { + 0xe5, 0x40, 0x4e, 0xbd, 0x50, 0x00, 0xf5, 0x15, 0xa6, 0xee, 0x45, 0xda, + 0x84, 0x3d, 0xd4, 0xc0 +}; + +__fips_constseg static const unsigned char sha1_additionalinput2[] = { + 0x11, 0x51, 0x14, 0xf0, 0x09, 0x1b, 0x4e, 0x56, 0x0d, 0xe9, 0xf6, 0x1e, + 0x52, 0x65, 0xcd, 0x96 +}; + +__fips_constseg static const unsigned char sha1_returnedbits[] = { + 0xa1, 0x9c, 0x94, 0x6e, 0x29, 0xe1, 0x33, 0x0d, 0x32, 0xd6, 0xaa, 0xce, + 0x71, 0x3f, 0x52, 0x72, 0x8b, 0x42, 0xa8, 0xd7 +}; + +/* SHA-224 PR */ +__fips_constseg static const unsigned char sha224_pr_entropyinput[] = { + 0x12, 0x69, 0x32, 0x4f, 0x83, 0xa6, 0xf5, 0x14, 0xe3, 0x49, 0x3e, 0x75, + 0x3e, 0xde, 0xad, 0xa1, 0x29, 0xc3, 0xf3, 0x19, 0x20, 0xb5, 0x4c, 0xd9 +}; + +__fips_constseg static const unsigned char sha224_pr_nonce[] = { + 0x6a, 0x78, 0xd0, 0xeb, 0xbb, 0x5a, 0xf0, 0xee, 0xe8, 0xc3, 0xba, 0x71 +}; + +__fips_constseg static const unsigned char sha224_pr_personalizationstring[] = { + 0xd5, 0xb8, 0xb6, 0xbc, 0xc1, 0x5b, 0x60, 0x31, 0x3c, 0xf5, 0xe5, 0xc0, + 0x8e, 0x52, 0x7a, 0xbd, 0xea, 0x47, 0xa9, 0x5f, 0x8f, 0xf9, 0x8b, 0xae +}; + +__fips_constseg static const unsigned char sha224_pr_additionalinput[] = { + 0x1f, 0x55, 0xec, 0xae, 0x16, 0x12, 0x84, 0xba, 0x84, 0x16, 0x19, 0x88, + 0x8e, 0xb8, 0x33, 0x25, 0x54, 0xff, 0xca, 0x79, 0xaf, 0x07, 0x25, 0x50 +}; + +__fips_constseg static const unsigned char sha224_pr_entropyinputpr[] = { + 0x92, 0xa3, 0x32, 0xa8, 0x9a, 0x0a, 0x58, 0x7c, 0x1d, 0x5a, 0x7e, 0xe1, + 0xb2, 0x73, 0xab, 0x0e, 0x16, 0x79, 0x23, 0xd3, 0x29, 0x89, 0x81, 0xe1 +}; + +__fips_constseg static const unsigned char sha224_pr_int_returnedbits[] = { + 0xf3, 0x38, 0x91, 0x40, 0x37, 0x7a, 0x51, 0x72, 0x42, 0x74, 0x78, 0x0a, + 0x69, 0xfd, 0xa6, 0x44, 0x43, 0x45, 0x6c, 0x0c, 0x5a, 0x19, 0xff, 0xf1, + 0x54, 0x60, 0xee, 0x6a +}; + +__fips_constseg static const unsigned char sha224_pr_additionalinput2[] = { + 0x75, 0xf3, 0x04, 0x25, 0xdd, 0x36, 0xa8, 0x37, 0x46, 0xae, 0x0c, 0x52, + 0x05, 0x79, 0x4c, 0x26, 0xdb, 0xe9, 0x71, 0x16, 0x4c, 0x0a, 0xf2, 0x60 +}; + +__fips_constseg static const unsigned char sha224_pr_entropyinputpr2[] = { + 0xea, 0xc5, 0x03, 0x0a, 0x4f, 0xb0, 0x38, 0x8d, 0x23, 0xd4, 0xc8, 0x77, + 0xe2, 0x6d, 0x9c, 0x0b, 0x44, 0xf7, 0x2d, 0x5b, 0xbf, 0x5d, 0x2a, 0x11 +}; + +__fips_constseg static const unsigned char sha224_pr_returnedbits[] = { + 0x60, 0x50, 0x2b, 0xe7, 0x86, 0xd8, 0x26, 0x73, 0xe3, 0x1d, 0x95, 0x20, + 0xb3, 0x2c, 0x32, 0x1c, 0xf5, 0xce, 0x57, 0xa6, 0x67, 0x2b, 0xdc, 0x4e, + 0xdd, 0x11, 0x4c, 0xc4 +}; + +/* SHA-224 No PR */ +__fips_constseg static const unsigned char sha224_entropyinput[] = { + 0xb2, 0x1c, 0x77, 0x4d, 0xf6, 0xd3, 0xb6, 0x40, 0xb7, 0x30, 0x3e, 0x29, + 0xb0, 0x85, 0x1c, 0xbe, 0x4a, 0xea, 0x6b, 0x5a, 0xb5, 0x8a, 0x97, 0xeb +}; + +__fips_constseg static const unsigned char sha224_nonce[] = { + 0x42, 0x02, 0x0a, 0x1c, 0x98, 0x9a, 0x77, 0x9e, 0x9f, 0x80, 0xba, 0xe0 +}; + +__fips_constseg static const unsigned char sha224_personalizationstring[] = { + 0x98, 0xb8, 0x04, 0x41, 0xfc, 0xc1, 0x5d, 0xc5, 0xe9, 0xb9, 0x08, 0xda, + 0xf9, 0xfa, 0x0d, 0x90, 0xce, 0xdf, 0x1d, 0x10, 0xa9, 0x8d, 0x50, 0x0c +}; + +__fips_constseg static const unsigned char sha224_additionalinput[] = { + 0x9a, 0x8d, 0x39, 0x49, 0x42, 0xd5, 0x0b, 0xae, 0xe1, 0xaf, 0xb7, 0x00, + 0x02, 0xfa, 0x96, 0xb1, 0xa5, 0x1d, 0x2d, 0x25, 0x78, 0xee, 0x83, 0x3f +}; + +__fips_constseg static const unsigned char sha224_int_returnedbits[] = { + 0xe4, 0xf5, 0x53, 0x79, 0x5a, 0x97, 0x58, 0x06, 0x08, 0xba, 0x7b, 0xfa, + 0xf0, 0x83, 0x05, 0x8c, 0x22, 0xc0, 0xc9, 0xdb, 0x15, 0xe7, 0xde, 0x20, + 0x55, 0x22, 0x9a, 0xad +}; + +__fips_constseg static const unsigned char sha224_entropyinputreseed[] = { + 0x67, 0x09, 0x48, 0xaa, 0x07, 0x16, 0x99, 0x89, 0x7f, 0x6d, 0xa0, 0xe5, + 0x8f, 0xdf, 0xbc, 0xdb, 0xfe, 0xe5, 0x6c, 0x7a, 0x95, 0x4a, 0x66, 0x17 +}; + +__fips_constseg static const unsigned char sha224_additionalinputreseed[] = { + 0x0f, 0x4b, 0x1c, 0x6f, 0xb7, 0xe3, 0x47, 0xe5, 0x5d, 0x7d, 0x38, 0xd6, + 0x28, 0x9b, 0xeb, 0x55, 0x63, 0x09, 0x3e, 0x7c, 0x56, 0xea, 0xf8, 0x19 +}; + +__fips_constseg static const unsigned char sha224_additionalinput2[] = { + 0x2d, 0x26, 0x7c, 0x37, 0xe4, 0x7a, 0x28, 0x5e, 0x5a, 0x3c, 0xaf, 0x3d, + 0x5a, 0x8e, 0x55, 0xa2, 0x1a, 0x6e, 0xc0, 0xe5, 0xf6, 0x21, 0xd3, 0xf6 +}; + +__fips_constseg static const unsigned char sha224_returnedbits[] = { + 0x4d, 0x83, 0x35, 0xdf, 0x67, 0xa9, 0xfc, 0x17, 0xda, 0x70, 0xcc, 0x8b, + 0x7f, 0x77, 0xae, 0xa2, 0x5f, 0xb9, 0x7e, 0x74, 0x4c, 0x26, 0xc1, 0x7a, + 0x3b, 0xa7, 0x5c, 0x93 +}; + +/* SHA-256 PR */ +__fips_constseg static const unsigned char sha256_pr_entropyinput[] = { + 0xce, 0x49, 0x00, 0x7a, 0x56, 0xe3, 0x67, 0x8f, 0xe1, 0xb6, 0xa7, 0xd4, + 0x4f, 0x08, 0x7a, 0x1b, 0x01, 0xf4, 0xfa, 0x6b, 0xef, 0xb7, 0xe5, 0xeb, + 0x07, 0x3d, 0x11, 0x0d, 0xc8, 0xea, 0x2b, 0xfe +}; + +__fips_constseg static const unsigned char sha256_pr_nonce[] = { + 0x73, 0x41, 0xc8, 0x92, 0x94, 0xe2, 0xc5, 0x5f, 0x93, 0xfd, 0x39, 0x5d, + 0x2b, 0x91, 0x4d, 0x38 +}; + +__fips_constseg static const unsigned char sha256_pr_personalizationstring[] = { + 0x50, 0x6d, 0x01, 0x01, 0x07, 0x5a, 0x80, 0x35, 0x7a, 0x56, 0x1a, 0x56, + 0x2f, 0x9a, 0x0b, 0x35, 0xb2, 0xb1, 0xc9, 0xe5, 0xca, 0x69, 0x61, 0x48, + 0xff, 0xfb, 0x0f, 0xd9, 0x4b, 0x79, 0x1d, 0xba +}; + +__fips_constseg static const unsigned char sha256_pr_additionalinput[] = { + 0x20, 0xb8, 0xdf, 0x44, 0x77, 0x5a, 0xb8, 0xd3, 0xbf, 0xf6, 0xcf, 0xac, + 0x5e, 0xa6, 0x96, 0x62, 0x73, 0x44, 0x40, 0x4a, 0x30, 0xfb, 0x38, 0xa5, + 0x7b, 0x0d, 0xe4, 0x0d, 0xc6, 0xe4, 0x9a, 0x1f +}; + +__fips_constseg static const unsigned char sha256_pr_entropyinputpr[] = { + 0x04, 0xc4, 0x65, 0xf4, 0xd3, 0xbf, 0x83, 0x4b, 0xab, 0xc8, 0x41, 0xa8, + 0xc2, 0xe0, 0x44, 0x63, 0x77, 0x4c, 0x6f, 0x6c, 0x49, 0x46, 0xff, 0x94, + 0x17, 0xea, 0xe6, 0x1a, 0x9d, 0x5e, 0x66, 0x78 +}; + +__fips_constseg static const unsigned char sha256_pr_int_returnedbits[] = { + 0x07, 0x4d, 0xac, 0x9b, 0x86, 0xca, 0x4a, 0xaa, 0x6e, 0x7a, 0x03, 0xa2, + 0x5d, 0x10, 0xea, 0x0b, 0xf9, 0x83, 0xcc, 0xd1, 0xfc, 0xe2, 0x07, 0xc7, + 0x06, 0x34, 0x60, 0x6f, 0x83, 0x94, 0x99, 0x76 +}; + +__fips_constseg static const unsigned char sha256_pr_additionalinput2[] = { + 0x89, 0x4e, 0x45, 0x8c, 0x11, 0xf9, 0xbc, 0x5b, 0xac, 0x74, 0x8b, 0x4b, + 0x5f, 0xf7, 0x19, 0xf3, 0xf5, 0x24, 0x54, 0x14, 0xd1, 0x15, 0xb1, 0x43, + 0x12, 0xa4, 0x5f, 0xd4, 0xec, 0xfc, 0xcd, 0x09 +}; + +__fips_constseg static const unsigned char sha256_pr_entropyinputpr2[] = { + 0x0e, 0xeb, 0x1f, 0xd7, 0xfc, 0xd1, 0x9d, 0xd4, 0x05, 0x36, 0x8b, 0xb2, + 0xfb, 0xe4, 0xf4, 0x51, 0x0c, 0x87, 0x9b, 0x02, 0x44, 0xd5, 0x92, 0x4d, + 0x44, 0xfe, 0x1a, 0x03, 0x43, 0x56, 0xbd, 0x86 +}; + +__fips_constseg static const unsigned char sha256_pr_returnedbits[] = { + 0x02, 0xaa, 0xb6, 0x1d, 0x7e, 0x2a, 0x40, 0x03, 0x69, 0x2d, 0x49, 0xa3, + 0x41, 0xe7, 0x44, 0x0b, 0xaf, 0x7b, 0x85, 0xe4, 0x5f, 0x53, 0x3b, 0x64, + 0xbc, 0x89, 0xc8, 0x82, 0xd4, 0x78, 0x37, 0xa2 +}; + +/* SHA-256 No PR */ +__fips_constseg static const unsigned char sha256_entropyinput[] = { + 0x5b, 0x1b, 0xec, 0x4d, 0xa9, 0x38, 0x74, 0x5a, 0x34, 0x0b, 0x7b, 0xc5, + 0xe5, 0xd7, 0x66, 0x7c, 0xbc, 0x82, 0xb9, 0x0e, 0x2d, 0x1f, 0x92, 0xd7, + 0xc1, 0xbc, 0x67, 0x69, 0xec, 0x6b, 0x03, 0x3c +}; + +__fips_constseg static const unsigned char sha256_nonce[] = { + 0xa4, 0x0c, 0xd8, 0x9c, 0x61, 0xd8, 0xc3, 0x54, 0xfe, 0x53, 0xc9, 0xe5, + 0x5d, 0x6f, 0x6d, 0x35 +}; + +__fips_constseg static const unsigned char sha256_personalizationstring[] = { + 0x22, 0x5e, 0x62, 0x93, 0x42, 0x83, 0x78, 0x24, 0xd8, 0x40, 0x8c, 0xde, + 0x6f, 0xf9, 0xa4, 0x7a, 0xc5, 0xa7, 0x3b, 0x88, 0xa3, 0xee, 0x42, 0x20, + 0xfd, 0x61, 0x56, 0xc6, 0x4c, 0x13, 0x41, 0x9c +}; + +__fips_constseg static const unsigned char sha256_additionalinput[] = { + 0xbf, 0x74, 0x5b, 0xf6, 0xc5, 0x64, 0x5e, 0x99, 0x34, 0x8f, 0xbc, 0xa4, + 0xe2, 0xbd, 0xd8, 0x85, 0x26, 0x37, 0xea, 0xba, 0x4f, 0xf2, 0x9a, 0x9a, + 0x66, 0xfc, 0xdf, 0x63, 0x26, 0x26, 0x19, 0x87 +}; + +__fips_constseg static const unsigned char sha256_int_returnedbits[] = { + 0xb3, 0xc6, 0x07, 0x07, 0xd6, 0x75, 0xf6, 0x2b, 0xd6, 0x21, 0x96, 0xf1, + 0xae, 0xdb, 0x2b, 0xac, 0x25, 0x2a, 0xae, 0xae, 0x41, 0x72, 0x03, 0x5e, + 0xbf, 0xd3, 0x64, 0xbc, 0x59, 0xf9, 0xc0, 0x76 +}; + +__fips_constseg static const unsigned char sha256_entropyinputreseed[] = { + 0xbf, 0x20, 0x33, 0x56, 0x29, 0xa8, 0x37, 0x04, 0x1f, 0x78, 0x34, 0x3d, + 0x81, 0x2a, 0xc9, 0x86, 0xc6, 0x7a, 0x2f, 0x88, 0x5e, 0xd5, 0xbe, 0x34, + 0x46, 0x20, 0xa4, 0x35, 0xeb, 0xc7, 0xe2, 0x9d +}; + +__fips_constseg static const unsigned char sha256_additionalinputreseed[] = { + 0x9b, 0xae, 0x2d, 0x2d, 0x61, 0xa4, 0x89, 0xeb, 0x43, 0x46, 0xa7, 0xda, + 0xef, 0x40, 0xca, 0x4a, 0x99, 0x11, 0x41, 0xdc, 0x5c, 0x94, 0xe9, 0xac, + 0xd4, 0xd0, 0xe6, 0xbd, 0xfb, 0x03, 0x9c, 0xa8 +}; + +__fips_constseg static const unsigned char sha256_additionalinput2[] = { + 0x23, 0xaa, 0x0c, 0xbd, 0x28, 0x33, 0xe2, 0x51, 0xfc, 0x71, 0xd2, 0x15, + 0x1f, 0x76, 0xfd, 0x0d, 0xe0, 0xb7, 0xb5, 0x84, 0x75, 0x5b, 0xbe, 0xf3, + 0x5c, 0xca, 0xc5, 0x30, 0xf2, 0x75, 0x1f, 0xda +}; + +__fips_constseg static const unsigned char sha256_returnedbits[] = { + 0x90, 0x3c, 0xc1, 0x10, 0x8c, 0x12, 0x01, 0xc6, 0xa6, 0x3a, 0x0f, 0x4d, + 0xb6, 0x3a, 0x4f, 0x41, 0x9c, 0x61, 0x75, 0x84, 0xe9, 0x74, 0x75, 0xfd, + 0xfe, 0xf2, 0x1f, 0x43, 0xd8, 0x5e, 0x24, 0xa3 +}; + +/* SHA-384 PR */ +__fips_constseg static const unsigned char sha384_pr_entropyinput[] = { + 0x71, 0x9d, 0xb2, 0x5a, 0x71, 0x6d, 0x04, 0xe9, 0x1e, 0xc7, 0x92, 0x24, + 0x6e, 0x12, 0x33, 0xa9, 0x52, 0x64, 0x31, 0xef, 0x71, 0xeb, 0x22, 0x55, + 0x28, 0x97, 0x06, 0x6a, 0xc0, 0x0c, 0xa0, 0x7e +}; + +__fips_constseg static const unsigned char sha384_pr_nonce[] = { + 0xf5, 0x0d, 0xfa, 0xb0, 0xec, 0x6a, 0x7c, 0xd6, 0xbd, 0x9b, 0x05, 0xfd, + 0x38, 0x3e, 0x2e, 0x56 +}; + +__fips_constseg static const unsigned char sha384_pr_personalizationstring[] = { + 0x74, 0xac, 0x7e, 0x6d, 0xb1, 0xa4, 0xe7, 0x21, 0xd1, 0x1e, 0x6e, 0x96, + 0x6d, 0x4d, 0x53, 0x46, 0x82, 0x96, 0x6e, 0xcf, 0xaa, 0x81, 0x8d, 0x7d, + 0x9e, 0xe1, 0x0f, 0x15, 0xea, 0x41, 0xbf, 0xe3 +}; + +__fips_constseg static const unsigned char sha384_pr_additionalinput[] = { + 0xda, 0x95, 0xd4, 0xd0, 0xb8, 0x11, 0xd3, 0x49, 0x27, 0x5d, 0xa9, 0x39, + 0x68, 0xf3, 0xa8, 0xe9, 0x5d, 0x19, 0x8a, 0x2b, 0x66, 0xe8, 0x69, 0x06, + 0x7c, 0x9e, 0x03, 0xa1, 0x8b, 0x26, 0x2d, 0x6e +}; + +__fips_constseg static const unsigned char sha384_pr_entropyinputpr[] = { + 0x49, 0xdf, 0x44, 0x00, 0xe4, 0x1c, 0x75, 0x0b, 0x26, 0x5a, 0x59, 0x64, + 0x1f, 0x4e, 0xb1, 0xb2, 0x13, 0xf1, 0x22, 0x4e, 0xb4, 0x6d, 0x9a, 0xcc, + 0xa0, 0x48, 0xe6, 0xcf, 0x1d, 0xd1, 0x92, 0x0d +}; + +__fips_constseg static const unsigned char sha384_pr_int_returnedbits[] = { + 0xc8, 0x52, 0xae, 0xbf, 0x04, 0x3c, 0x27, 0xb7, 0x78, 0x18, 0xaa, 0x8f, + 0xff, 0xcf, 0xa4, 0xf1, 0xcc, 0xe7, 0x68, 0xfa, 0x22, 0xa2, 0x13, 0x45, + 0xe8, 0xdd, 0x87, 0xe6, 0xf2, 0x6e, 0xdd, 0xc7, 0x52, 0x90, 0x9f, 0x7b, + 0xfa, 0x61, 0x2d, 0x9d, 0x9e, 0xcf, 0x98, 0xac, 0x52, 0x40, 0xce, 0xaf +}; + +__fips_constseg static const unsigned char sha384_pr_additionalinput2[] = { + 0x61, 0x7c, 0x03, 0x9a, 0x3e, 0x50, 0x57, 0x60, 0xc5, 0x83, 0xc9, 0xb2, + 0xd1, 0x87, 0x85, 0x66, 0x92, 0x5d, 0x84, 0x0e, 0x53, 0xfb, 0x70, 0x03, + 0x72, 0xfd, 0xba, 0xae, 0x9c, 0x8f, 0xf8, 0x18 +}; + +__fips_constseg static const unsigned char sha384_pr_entropyinputpr2[] = { + 0xf8, 0xeb, 0x89, 0xb1, 0x8d, 0x78, 0xbe, 0x21, 0xe0, 0xbb, 0x9d, 0xb7, + 0x95, 0x0e, 0xd9, 0x46, 0x0c, 0x8c, 0xe2, 0x63, 0xb7, 0x9d, 0x67, 0x90, + 0xbd, 0xc7, 0x0b, 0xa5, 0xce, 0xb2, 0x65, 0x81 +}; + +__fips_constseg static const unsigned char sha384_pr_returnedbits[] = { + 0xe6, 0x9f, 0xfe, 0x68, 0xd6, 0xb5, 0x79, 0xf1, 0x06, 0x5f, 0xa3, 0xbb, + 0x23, 0x85, 0xd8, 0xf0, 0x29, 0x5a, 0x68, 0x9e, 0xf5, 0xf4, 0xa6, 0x12, + 0xe0, 0x9a, 0xe2, 0xac, 0x00, 0x1d, 0x98, 0x26, 0xfc, 0x53, 0x95, 0x53, + 0xe4, 0x3e, 0x17, 0xd5, 0x08, 0x0b, 0x70, 0x3d, 0x67, 0x99, 0xac, 0x66 +}; + +/* SHA-384 No PR */ +__fips_constseg static const unsigned char sha384_entropyinput[] = { + 0x07, 0x15, 0x27, 0x2a, 0xaf, 0x74, 0x24, 0x37, 0xbc, 0xd5, 0x14, 0x69, + 0xce, 0x11, 0xff, 0xa2, 0x6b, 0xb8, 0x05, 0x67, 0x34, 0xf8, 0xbd, 0x6d, + 0x6a, 0xcc, 0xcd, 0x60, 0xa3, 0x68, 0xca, 0xf4 +}; + +__fips_constseg static const unsigned char sha384_nonce[] = { + 0x70, 0x17, 0xc2, 0x5b, 0x5d, 0x22, 0x0b, 0x06, 0x15, 0x54, 0x78, 0x77, + 0x44, 0xaf, 0x2f, 0x09 +}; + +__fips_constseg static const unsigned char sha384_personalizationstring[] = { + 0x89, 0x39, 0x28, 0xb0, 0x60, 0xeb, 0x3d, 0xdc, 0x55, 0x75, 0x86, 0xeb, + 0xae, 0xa2, 0x8f, 0xbc, 0x1b, 0x75, 0xd4, 0xe1, 0x0f, 0xaa, 0x38, 0xca, + 0x62, 0x8b, 0xcb, 0x2c, 0x26, 0xf6, 0xbc, 0xb1 +}; + +__fips_constseg static const unsigned char sha384_additionalinput[] = { + 0x30, 0x2b, 0x42, 0x35, 0xef, 0xda, 0x40, 0x55, 0x28, 0xc6, 0x95, 0xfb, + 0x54, 0x01, 0x62, 0xd7, 0x87, 0x14, 0x48, 0x6d, 0x90, 0x4c, 0xa9, 0x02, + 0x54, 0x40, 0x22, 0xc8, 0x66, 0xa5, 0x48, 0x48 +}; + +__fips_constseg static const unsigned char sha384_int_returnedbits[] = { + 0x82, 0xc4, 0xa1, 0x9c, 0x21, 0xd2, 0xe7, 0xa5, 0xa6, 0xf6, 0x5f, 0x04, + 0x5c, 0xc7, 0x31, 0x9d, 0x8d, 0x59, 0x74, 0x50, 0x19, 0x89, 0x2f, 0x63, + 0xd5, 0xb7, 0x7e, 0xeb, 0x15, 0xe3, 0x70, 0x83, 0xa1, 0x24, 0x59, 0xfa, + 0x2c, 0x56, 0xf6, 0x88, 0x3a, 0x92, 0x93, 0xa1, 0xfb, 0x79, 0xc1, 0x7a +}; + +__fips_constseg static const unsigned char sha384_entropyinputreseed[] = { + 0x39, 0xa6, 0xe8, 0x5c, 0x82, 0x17, 0x71, 0x26, 0x57, 0x4f, 0x9f, 0xc2, + 0x55, 0xff, 0x5c, 0x9b, 0x53, 0x1a, 0xd1, 0x5f, 0xbc, 0x62, 0xe4, 0x27, + 0x2d, 0x32, 0xf0, 0xe4, 0x52, 0x8c, 0xc5, 0x0c +}; + +__fips_constseg static const unsigned char sha384_additionalinputreseed[] = { + 0x8d, 0xcb, 0x8d, 0xce, 0x08, 0xea, 0x80, 0xe8, 0x9b, 0x61, 0xa8, 0x0f, + 0xaf, 0x49, 0x20, 0x9e, 0x74, 0xcb, 0x57, 0x80, 0x42, 0xb0, 0x84, 0x5e, + 0x30, 0x2a, 0x67, 0x08, 0xf4, 0xe3, 0x40, 0x22 +}; + +__fips_constseg static const unsigned char sha384_additionalinput2[] = { + 0x7c, 0x8f, 0xc2, 0xae, 0x22, 0x4a, 0xd6, 0xf6, 0x05, 0xa4, 0x7a, 0xea, + 0xbb, 0x25, 0xd0, 0xb7, 0x5a, 0xd6, 0xcf, 0x9d, 0xf3, 0x6c, 0xe2, 0xb2, + 0x4e, 0xb4, 0xbd, 0xf4, 0xe5, 0x40, 0x80, 0x94 +}; + +__fips_constseg static const unsigned char sha384_returnedbits[] = { + 0x9e, 0x7e, 0xfb, 0x59, 0xbb, 0xaa, 0x3c, 0xf7, 0xe1, 0xf8, 0x76, 0xdd, + 0x63, 0x5f, 0xaf, 0x23, 0xd6, 0x64, 0x61, 0xc0, 0x9a, 0x09, 0x47, 0xc9, + 0x33, 0xdf, 0x6d, 0x55, 0x91, 0x34, 0x79, 0x70, 0xc4, 0x99, 0x6e, 0x54, + 0x09, 0x64, 0x21, 0x1a, 0xbd, 0x1e, 0x80, 0x40, 0x34, 0xad, 0xfa, 0xd7 +}; + +/* SHA-512 PR */ +__fips_constseg static const unsigned char sha512_pr_entropyinput[] = { + 0x13, 0xf7, 0x61, 0x75, 0x65, 0x28, 0xa2, 0x59, 0x13, 0x5a, 0x4a, 0x4f, + 0x56, 0x60, 0x8c, 0x53, 0x7d, 0xb0, 0xbd, 0x06, 0x4f, 0xed, 0xcc, 0xd2, + 0xa2, 0xb5, 0xfd, 0x5b, 0x3a, 0xab, 0xec, 0x28 +}; + +__fips_constseg static const unsigned char sha512_pr_nonce[] = { + 0xbe, 0xa3, 0x91, 0x93, 0x1d, 0xc3, 0x31, 0x3a, 0x23, 0x33, 0x50, 0x67, + 0x88, 0xc7, 0xa2, 0xc4 +}; + +__fips_constseg static const unsigned char sha512_pr_personalizationstring[] = { + 0x1f, 0x59, 0x4d, 0x7b, 0xe6, 0x46, 0x91, 0x48, 0xc1, 0x25, 0xfa, 0xff, + 0x89, 0x12, 0x77, 0x35, 0xdf, 0x3e, 0xf4, 0x80, 0x5f, 0xd9, 0xb0, 0x07, + 0x22, 0x41, 0xdd, 0x48, 0x78, 0x6b, 0x77, 0x2b +}; + +__fips_constseg static const unsigned char sha512_pr_additionalinput[] = { + 0x30, 0xff, 0x63, 0x6f, 0xac, 0xd9, 0x84, 0x39, 0x6f, 0xe4, 0x99, 0xce, + 0x91, 0x7d, 0x7e, 0xc8, 0x58, 0xf2, 0x12, 0xc3, 0xb6, 0xad, 0xda, 0x22, + 0x04, 0xa0, 0xd2, 0x21, 0xfe, 0xf2, 0x95, 0x1d +}; + +__fips_constseg static const unsigned char sha512_pr_entropyinputpr[] = { + 0x64, 0x54, 0x13, 0xec, 0x4f, 0x77, 0xda, 0xb2, 0x92, 0x2e, 0x52, 0x80, + 0x11, 0x10, 0xc2, 0xf8, 0xe6, 0xa7, 0xcd, 0x4b, 0xfc, 0x32, 0x2e, 0x9e, + 0xeb, 0xbb, 0xb1, 0xbf, 0x15, 0x5c, 0x73, 0x08 +}; + +__fips_constseg static const unsigned char sha512_pr_int_returnedbits[] = { + 0xef, 0x1e, 0xdc, 0x0a, 0xa4, 0x36, 0x91, 0x9c, 0x3d, 0x27, 0x97, 0x50, + 0x8d, 0x36, 0x29, 0x8d, 0xce, 0x6a, 0x0c, 0xf7, 0x21, 0xc0, 0x91, 0xae, + 0x0c, 0x96, 0x72, 0xbd, 0x52, 0x81, 0x58, 0xfc, 0x6d, 0xe5, 0xf7, 0xa5, + 0xfd, 0x5d, 0xa7, 0x58, 0x68, 0xc8, 0x99, 0x58, 0x8e, 0xc8, 0xce, 0x95, + 0x01, 0x7d, 0xff, 0xa4, 0xc8, 0xf7, 0x63, 0xfe, 0x5f, 0x69, 0x83, 0x53, + 0xe2, 0xc6, 0x8b, 0xc3 +}; + +__fips_constseg static const unsigned char sha512_pr_additionalinput2[] = { + 0xe6, 0x9b, 0xc4, 0x88, 0x34, 0xca, 0xea, 0x29, 0x2f, 0x98, 0x05, 0xa4, + 0xd3, 0xc0, 0x7b, 0x11, 0xe8, 0xbb, 0x75, 0xf2, 0xbd, 0x29, 0xb7, 0x40, + 0x25, 0x7f, 0xc1, 0xb7, 0xb1, 0xf1, 0x25, 0x61 +}; + +__fips_constseg static const unsigned char sha512_pr_entropyinputpr2[] = { + 0x23, 0x6d, 0xff, 0xde, 0xfb, 0xd1, 0xba, 0x33, 0x18, 0xe6, 0xbe, 0xb5, + 0x48, 0x77, 0x6d, 0x7f, 0xa7, 0xe1, 0x4d, 0x48, 0x1e, 0x3c, 0xa7, 0x34, + 0x1a, 0xc8, 0x60, 0xdb, 0x8f, 0x99, 0x15, 0x99 +}; + +__fips_constseg static const unsigned char sha512_pr_returnedbits[] = { + 0x70, 0x27, 0x31, 0xdb, 0x92, 0x70, 0x21, 0xfe, 0x16, 0xb6, 0xc8, 0x51, + 0x34, 0x87, 0x65, 0xd0, 0x4e, 0xfd, 0xfe, 0x68, 0xec, 0xac, 0xdc, 0x93, + 0x41, 0x38, 0x92, 0x90, 0xb4, 0x94, 0xf9, 0x0d, 0xa4, 0xf7, 0x4e, 0x80, + 0x92, 0x67, 0x48, 0x40, 0xa7, 0x08, 0xc7, 0xbc, 0x66, 0x00, 0xfd, 0xf7, + 0x4c, 0x8b, 0x17, 0x6e, 0xd1, 0x8f, 0x9b, 0xf3, 0x6f, 0xf6, 0x34, 0xdd, + 0x67, 0xf7, 0x68, 0xdd +}; + +/* SHA-512 No PR */ +__fips_constseg static const unsigned char sha512_entropyinput[] = { + 0xb6, 0x0b, 0xb7, 0xbc, 0x84, 0x56, 0xf6, 0x12, 0xaf, 0x45, 0x67, 0x17, + 0x7c, 0xd1, 0xb2, 0x78, 0x2b, 0xa0, 0xf2, 0xbe, 0xb6, 0x6d, 0x8b, 0x56, + 0xc6, 0xbc, 0x4d, 0xe1, 0xf7, 0xbe, 0xce, 0xbd +}; + +__fips_constseg static const unsigned char sha512_nonce[] = { + 0x9d, 0xed, 0xc0, 0xe5, 0x5a, 0x98, 0x6a, 0xcb, 0x51, 0x7d, 0x76, 0x31, + 0x5a, 0x64, 0xf0, 0xf7 +}; + +__fips_constseg static const unsigned char sha512_personalizationstring[] = { + 0xc2, 0x6d, 0xa3, 0xc3, 0x06, 0x74, 0xe5, 0x01, 0x5c, 0x10, 0x17, 0xc7, + 0xaf, 0x83, 0x9d, 0x59, 0x8d, 0x2d, 0x29, 0x38, 0xc5, 0x59, 0x70, 0x8b, + 0x46, 0x48, 0x2d, 0xcf, 0x36, 0x7d, 0x59, 0xc0 +}; + +__fips_constseg static const unsigned char sha512_additionalinput[] = { + 0xec, 0x8c, 0xd4, 0xf7, 0x61, 0x6e, 0x0d, 0x95, 0x79, 0xb7, 0x28, 0xad, + 0x5f, 0x69, 0x74, 0x5f, 0x2d, 0x36, 0x06, 0x8a, 0x6b, 0xac, 0x54, 0x97, + 0xc4, 0xa1, 0x12, 0x85, 0x0a, 0xdf, 0x4b, 0x34 +}; + +__fips_constseg static const unsigned char sha512_int_returnedbits[] = { + 0x84, 0x2f, 0x1f, 0x68, 0x6a, 0xa3, 0xad, 0x1e, 0xfb, 0xf4, 0x15, 0xbd, + 0xde, 0x38, 0xd4, 0x30, 0x80, 0x51, 0xe9, 0xd3, 0xc7, 0x20, 0x88, 0xe9, + 0xf5, 0xcc, 0xdf, 0x57, 0x5c, 0x47, 0x2f, 0x57, 0x3c, 0x5f, 0x13, 0x56, + 0xcc, 0xc5, 0x4f, 0x84, 0xf8, 0x10, 0x41, 0xd5, 0x7e, 0x58, 0x6e, 0x19, + 0x19, 0x9e, 0xaf, 0xc2, 0x22, 0x58, 0x41, 0x50, 0x79, 0xc2, 0xd8, 0x04, + 0x28, 0xd4, 0x39, 0x9a +}; + +__fips_constseg static const unsigned char sha512_entropyinputreseed[] = { + 0xfa, 0x7f, 0x46, 0x51, 0x83, 0x62, 0x98, 0x16, 0x9a, 0x19, 0xa2, 0x49, + 0xa9, 0xe6, 0x4a, 0xd8, 0x85, 0xe7, 0xd4, 0x3b, 0x2c, 0x82, 0xc5, 0x82, + 0xbf, 0x11, 0xf9, 0x9e, 0xbc, 0xd0, 0x01, 0xee +}; + +__fips_constseg static const unsigned char sha512_additionalinputreseed[] = { + 0xb9, 0x12, 0xe0, 0x4f, 0xf7, 0xa7, 0xc4, 0xd8, 0xd0, 0x8e, 0x99, 0x29, + 0x7c, 0x9a, 0xe9, 0xcf, 0xc4, 0x6c, 0xf8, 0xc3, 0xa7, 0x41, 0x83, 0xd6, + 0x2e, 0xfa, 0xb8, 0x5e, 0x8e, 0x6b, 0x78, 0x20 +}; + +__fips_constseg static const unsigned char sha512_additionalinput2[] = { + 0xd7, 0x07, 0x52, 0xb9, 0x83, 0x2c, 0x03, 0x71, 0xee, 0xc9, 0xc0, 0x85, + 0xe1, 0x57, 0xb2, 0xcd, 0x3a, 0xf0, 0xc9, 0x34, 0x24, 0x41, 0x1c, 0x42, + 0x99, 0xb2, 0x84, 0xe9, 0x17, 0xd2, 0x76, 0x92 +}; + +__fips_constseg static const unsigned char sha512_returnedbits[] = { + 0x36, 0x17, 0x5d, 0x98, 0x2b, 0x65, 0x25, 0x8e, 0xc8, 0x29, 0xdf, 0x27, + 0x05, 0x36, 0x26, 0x12, 0x8a, 0x68, 0x74, 0x27, 0x37, 0xd4, 0x7f, 0x32, + 0xb1, 0x12, 0xd6, 0x85, 0x83, 0xeb, 0x2e, 0xa0, 0xed, 0x4b, 0xb5, 0x7b, + 0x6f, 0x39, 0x3c, 0x71, 0x77, 0x02, 0x12, 0xcc, 0x2c, 0x3a, 0x8e, 0x63, + 0xdf, 0x4a, 0xbd, 0x6f, 0x6e, 0x2e, 0xed, 0x0a, 0x85, 0xa5, 0x2f, 0xa2, + 0x68, 0xde, 0x42, 0xb5 +}; + +/* HMAC SHA-1 PR */ +__fips_constseg static const unsigned char hmac_sha1_pr_entropyinput[] = { + 0x26, 0x5f, 0x36, 0x14, 0xff, 0x3d, 0x83, 0xfa, 0x73, 0x5e, 0x75, 0xdc, + 0x2c, 0x18, 0x17, 0x1b +}; + +__fips_constseg static const unsigned char hmac_sha1_pr_nonce[] = { + 0xc8, 0xe3, 0x57, 0xa5, 0x7b, 0x74, 0x86, 0x6e +}; + +__fips_constseg + static const unsigned char hmac_sha1_pr_personalizationstring[] = { + 0x6e, 0xdb, 0x0d, 0xfe, 0x7d, 0xac, 0x79, 0xd0, 0xa5, 0x3a, 0x48, 0x85, + 0x80, 0xe2, 0x7f, 0x2a +}; + +__fips_constseg static const unsigned char hmac_sha1_pr_additionalinput[] = { + 0x31, 0xcd, 0x5e, 0x43, 0xdc, 0xfb, 0x7a, 0x79, 0xca, 0x88, 0xde, 0x1f, + 0xd7, 0xbb, 0x42, 0x09 +}; + +__fips_constseg static const unsigned char hmac_sha1_pr_entropyinputpr[] = { + 0x7c, 0x23, 0x95, 0x38, 0x00, 0x95, 0xc1, 0x78, 0x1f, 0x8f, 0xd7, 0x63, + 0x23, 0x87, 0x2a, 0xed +}; + +__fips_constseg static const unsigned char hmac_sha1_pr_int_returnedbits[] = { + 0xbb, 0x34, 0xe7, 0x93, 0xa3, 0x02, 0x2c, 0x4a, 0xd0, 0x89, 0xda, 0x7f, + 0xed, 0xf4, 0x4c, 0xde, 0x17, 0xec, 0xe5, 0x6c +}; + +__fips_constseg static const unsigned char hmac_sha1_pr_additionalinput2[] = { + 0x49, 0xbc, 0x2d, 0x2c, 0xb7, 0x32, 0xcb, 0x20, 0xdf, 0xf5, 0x77, 0x58, + 0xa0, 0x4b, 0x93, 0x6e +}; + +__fips_constseg static const unsigned char hmac_sha1_pr_entropyinputpr2[] = { + 0x3c, 0xaa, 0xb0, 0x21, 0x42, 0xb0, 0xdd, 0x34, 0xf0, 0x16, 0x7f, 0x0c, + 0x0f, 0xff, 0x2e, 0xaf +}; + +__fips_constseg static const unsigned char hmac_sha1_pr_returnedbits[] = { + 0x8e, 0xcb, 0xa3, 0x64, 0xb2, 0xb8, 0x33, 0x6c, 0x64, 0x3b, 0x78, 0x16, + 0x99, 0x35, 0xc8, 0x30, 0xcb, 0x3e, 0xa0, 0xd8 +}; + +/* HMAC SHA-1 No PR */ +__fips_constseg static const unsigned char hmac_sha1_entropyinput[] = { + 0x32, 0x9a, 0x2a, 0x87, 0x7b, 0x89, 0x7c, 0xf6, 0xcb, 0x95, 0xd5, 0x40, + 0x17, 0xfe, 0x47, 0x70 +}; + +__fips_constseg static const unsigned char hmac_sha1_nonce[] = { + 0x16, 0xd8, 0xe0, 0xc7, 0x52, 0xcf, 0x4a, 0x25 +}; + +__fips_constseg static const unsigned char hmac_sha1_personalizationstring[] = { + 0x35, 0x35, 0xa9, 0xa5, 0x40, 0xbe, 0x9b, 0xd1, 0x56, 0xdd, 0x44, 0x00, + 0x72, 0xf7, 0xd3, 0x5e +}; + +__fips_constseg static const unsigned char hmac_sha1_additionalinput[] = { + 0x1b, 0x2c, 0x84, 0x2d, 0x4a, 0x89, 0x8f, 0x69, 0x19, 0xf1, 0xf3, 0xdb, + 0xbb, 0xe3, 0xaa, 0xea +}; + +__fips_constseg static const unsigned char hmac_sha1_int_returnedbits[] = { + 0xcf, 0xfa, 0x7d, 0x72, 0x0f, 0xe6, 0xc7, 0x96, 0xa0, 0x69, 0x31, 0x11, + 0x9b, 0x0b, 0x1a, 0x20, 0x1f, 0x3f, 0xaa, 0xd1 +}; + +__fips_constseg static const unsigned char hmac_sha1_entropyinputreseed[] = { + 0x90, 0x75, 0x15, 0x04, 0x95, 0xf1, 0xba, 0x81, 0x0c, 0x37, 0x94, 0x6f, + 0x86, 0x52, 0x6d, 0x9c +}; + +__fips_constseg static const unsigned char hmac_sha1_additionalinputreseed[] = { + 0x5b, 0x40, 0xba, 0x5f, 0x17, 0x70, 0xf0, 0x4b, 0xdf, 0xc9, 0x97, 0x92, + 0x79, 0xc5, 0x82, 0x28 +}; + +__fips_constseg static const unsigned char hmac_sha1_additionalinput2[] = { + 0x97, 0xc8, 0x80, 0x90, 0xb3, 0xaa, 0x6e, 0x60, 0xea, 0x83, 0x7a, 0xe3, + 0x8a, 0xca, 0xa4, 0x7f +}; + +__fips_constseg static const unsigned char hmac_sha1_returnedbits[] = { + 0x90, 0xbd, 0x05, 0x56, 0x6d, 0xb5, 0x22, 0xd5, 0xb9, 0x5a, 0x29, 0x2d, + 0xe9, 0x0b, 0xe1, 0xac, 0xde, 0x27, 0x0b, 0xb0 +}; + +/* HMAC SHA-224 PR */ +__fips_constseg static const unsigned char hmac_sha224_pr_entropyinput[] = { + 0x17, 0x32, 0x2b, 0x2e, 0x6f, 0x1b, 0x9c, 0x6d, 0x31, 0xe0, 0x34, 0x07, + 0xcf, 0xed, 0xf6, 0xb6, 0x5a, 0x76, 0x4c, 0xbc, 0x62, 0x85, 0x01, 0x90 +}; + +__fips_constseg static const unsigned char hmac_sha224_pr_nonce[] = { + 0x38, 0xbf, 0x5f, 0x20, 0xb3, 0x68, 0x2f, 0x43, 0x61, 0x05, 0x8f, 0x23 +}; + +__fips_constseg + static const unsigned char hmac_sha224_pr_personalizationstring[] = { + 0xc0, 0xc9, 0x45, 0xac, 0x8d, 0x27, 0x77, 0x08, 0x0b, 0x17, 0x6d, 0xed, + 0xc1, 0x7d, 0xd5, 0x07, 0x9d, 0x6e, 0xf8, 0x23, 0x2a, 0x22, 0x13, 0xbd +}; + +__fips_constseg static const unsigned char hmac_sha224_pr_additionalinput[] = { + 0xa4, 0x3c, 0xe7, 0x3b, 0xea, 0x19, 0x45, 0x32, 0xc2, 0x83, 0x6d, 0x21, + 0x8a, 0xc0, 0xee, 0x67, 0x45, 0xde, 0x13, 0x7d, 0x9d, 0x61, 0x00, 0x3b +}; + +__fips_constseg static const unsigned char hmac_sha224_pr_entropyinputpr[] = { + 0x15, 0x05, 0x74, 0x4a, 0x7f, 0x8d, 0x5c, 0x60, 0x16, 0xe5, 0x7b, 0xad, + 0xf5, 0x41, 0x8f, 0x55, 0x60, 0xc4, 0x09, 0xee, 0x1e, 0x11, 0x81, 0xab +}; + +__fips_constseg static const unsigned char hmac_sha224_pr_int_returnedbits[] = { + 0x6f, 0xf5, 0x9a, 0xe2, 0x54, 0x53, 0x30, 0x3d, 0x5a, 0x27, 0x29, 0x38, + 0x27, 0xf2, 0x0d, 0x05, 0xe9, 0x26, 0xcb, 0x16, 0xc3, 0x51, 0x5f, 0x13, + 0x41, 0xfe, 0x99, 0xf2 +}; + +__fips_constseg static const unsigned char hmac_sha224_pr_additionalinput2[] = { + 0x73, 0x81, 0x88, 0x84, 0x8f, 0xed, 0x6f, 0x10, 0x9f, 0x93, 0xbf, 0x17, + 0x35, 0x7c, 0xef, 0xd5, 0x8d, 0x26, 0xa6, 0x7a, 0xe8, 0x09, 0x36, 0x4f +}; + +__fips_constseg static const unsigned char hmac_sha224_pr_entropyinputpr2[] = { + 0xe6, 0xcf, 0xcf, 0x7e, 0x12, 0xe5, 0x43, 0xd2, 0x38, 0xd8, 0x24, 0x6f, + 0x5a, 0x37, 0x68, 0xbf, 0x4f, 0xa0, 0xff, 0xd5, 0x61, 0x8a, 0x93, 0xe0 +}; + +__fips_constseg static const unsigned char hmac_sha224_pr_returnedbits[] = { + 0xaf, 0xf9, 0xd8, 0x19, 0x91, 0x30, 0x82, 0x6f, 0xa9, 0x1e, 0x9d, 0xd7, + 0xf3, 0x50, 0xe0, 0xc7, 0xd5, 0x64, 0x96, 0x7d, 0x4c, 0x4d, 0x78, 0x03, + 0x6d, 0xd8, 0x9e, 0x72 +}; + +/* HMAC SHA-224 No PR */ +__fips_constseg static const unsigned char hmac_sha224_entropyinput[] = { + 0x11, 0x82, 0xfd, 0xd9, 0x42, 0xf4, 0xfa, 0xc8, 0xf2, 0x41, 0xe6, 0x54, + 0x01, 0xae, 0x22, 0x6e, 0xc6, 0xaf, 0xaf, 0xd0, 0xa6, 0xb2, 0xe2, 0x6d +}; + +__fips_constseg static const unsigned char hmac_sha224_nonce[] = { + 0xa9, 0x48, 0xd7, 0x92, 0x39, 0x7e, 0x2a, 0xdc, 0x30, 0x1f, 0x0e, 0x2b +}; + +__fips_constseg + static const unsigned char hmac_sha224_personalizationstring[] = { + 0x11, 0xd5, 0xf4, 0xbd, 0x67, 0x8c, 0x31, 0xcf, 0xa3, 0x3f, 0x1e, 0x6b, + 0xa8, 0x07, 0x02, 0x0b, 0xc8, 0x2e, 0x6c, 0x64, 0x41, 0x5b, 0xc8, 0x37 +}; + +__fips_constseg static const unsigned char hmac_sha224_additionalinput[] = { + 0x68, 0x18, 0xc2, 0x06, 0xeb, 0x3e, 0x04, 0x95, 0x44, 0x5e, 0xfb, 0xe6, + 0x41, 0xc1, 0x5c, 0xcc, 0x40, 0x2f, 0xb7, 0xd2, 0x0f, 0xf3, 0x6b, 0xe7 +}; + +__fips_constseg static const unsigned char hmac_sha224_int_returnedbits[] = { + 0x7f, 0x45, 0xc7, 0x5d, 0x32, 0xe6, 0x17, 0x60, 0xba, 0xdc, 0xb8, 0x42, + 0x1b, 0x9c, 0xf1, 0xfa, 0x3b, 0x4d, 0x29, 0x54, 0xc6, 0x90, 0xff, 0x5c, + 0xcd, 0xd6, 0xa9, 0xcc +}; + +__fips_constseg static const unsigned char hmac_sha224_entropyinputreseed[] = { + 0xc4, 0x8e, 0x37, 0x95, 0x69, 0x53, 0x28, 0xd7, 0x37, 0xbb, 0x70, 0x95, + 0x1c, 0x07, 0x1d, 0xd9, 0xb7, 0xe6, 0x1b, 0xbb, 0xfe, 0x41, 0xeb, 0xc9 +}; + +__fips_constseg + static const unsigned char hmac_sha224_additionalinputreseed[] = { + 0x53, 0x17, 0xa1, 0x6a, 0xfa, 0x77, 0x47, 0xb0, 0x95, 0x56, 0x9a, 0x20, + 0x57, 0xde, 0x5c, 0x89, 0x9f, 0x7f, 0xe2, 0xde, 0x17, 0x3a, 0x50, 0x23 +}; + +__fips_constseg static const unsigned char hmac_sha224_additionalinput2[] = { + 0x3a, 0x32, 0xf9, 0x85, 0x0c, 0xc1, 0xed, 0x76, 0x2d, 0xdf, 0x40, 0xc3, + 0x06, 0x22, 0x66, 0xd4, 0x9a, 0x9a, 0xff, 0x5a, 0x7e, 0x7a, 0xf3, 0x96 +}; + +__fips_constseg static const unsigned char hmac_sha224_returnedbits[] = { + 0x43, 0xb4, 0x57, 0x5c, 0x38, 0x25, 0x9d, 0xae, 0xec, 0x96, 0xd1, 0x85, + 0x3a, 0x84, 0x8d, 0xfe, 0x68, 0xd5, 0x0e, 0x5c, 0x8f, 0x65, 0xa5, 0x4e, + 0x45, 0x84, 0xa8, 0x94 +}; + +/* HMAC SHA-256 PR */ +__fips_constseg static const unsigned char hmac_sha256_pr_entropyinput[] = { + 0x4d, 0xb0, 0x43, 0xd8, 0x34, 0x4b, 0x10, 0x70, 0xb1, 0x8b, 0xed, 0xea, + 0x07, 0x92, 0x9f, 0x6c, 0x79, 0x31, 0xaf, 0x81, 0x29, 0xeb, 0x6e, 0xca, + 0x32, 0x48, 0x28, 0xe7, 0x02, 0x5d, 0xa6, 0xa6 +}; + +__fips_constseg static const unsigned char hmac_sha256_pr_nonce[] = { + 0x3a, 0xae, 0x15, 0xa9, 0x99, 0xdc, 0xe4, 0x67, 0x34, 0x3b, 0x70, 0x15, + 0xaa, 0xd3, 0x30, 0x9a +}; + +__fips_constseg + static const unsigned char hmac_sha256_pr_personalizationstring[] = { + 0x13, 0x1d, 0x24, 0x04, 0xb0, 0x18, 0x81, 0x15, 0x21, 0x51, 0x2a, 0x24, + 0x52, 0x61, 0xbe, 0x64, 0x82, 0x6b, 0x55, 0x2f, 0xe2, 0xf1, 0x40, 0x7d, + 0x71, 0xd8, 0x01, 0x86, 0x15, 0xb7, 0x8b, 0xb5 +}; + +__fips_constseg static const unsigned char hmac_sha256_pr_additionalinput[] = { + 0x8f, 0xa6, 0x54, 0x5f, 0xb1, 0xd0, 0xd8, 0xc3, 0xe7, 0x0c, 0x15, 0xa9, + 0x23, 0x6e, 0xfe, 0xfb, 0x93, 0xf7, 0x3a, 0xbd, 0x59, 0x01, 0xfa, 0x18, + 0x8e, 0xe9, 0x1a, 0xa9, 0x78, 0xfc, 0x79, 0x0b +}; + +__fips_constseg static const unsigned char hmac_sha256_pr_entropyinputpr[] = { + 0xcf, 0x24, 0xb9, 0xeb, 0xb3, 0xd4, 0xcd, 0x17, 0x37, 0x38, 0x75, 0x79, + 0x15, 0xcb, 0x2d, 0x75, 0x51, 0xf1, 0xcc, 0xaa, 0x32, 0xa4, 0xa7, 0x36, + 0x7c, 0x5c, 0xe4, 0x47, 0xf1, 0x3e, 0x1d, 0xe5 +}; + +__fips_constseg static const unsigned char hmac_sha256_pr_int_returnedbits[] = { + 0x52, 0x42, 0xfa, 0xeb, 0x85, 0xe0, 0x30, 0x22, 0x79, 0x00, 0x16, 0xb2, + 0x88, 0x2f, 0x14, 0x6a, 0xb7, 0xfc, 0xb7, 0x53, 0xdc, 0x4a, 0x12, 0xef, + 0x54, 0xd6, 0x33, 0xe9, 0x20, 0xd6, 0xfd, 0x56 +}; + +__fips_constseg static const unsigned char hmac_sha256_pr_additionalinput2[] = { + 0xf4, 0xf6, 0x49, 0xa1, 0x2d, 0x64, 0x2b, 0x30, 0x58, 0xf8, 0xbd, 0xb8, + 0x75, 0xeb, 0xbb, 0x5e, 0x1c, 0x9b, 0x81, 0x6a, 0xda, 0x14, 0x86, 0x6e, + 0xd0, 0xda, 0x18, 0xb7, 0x88, 0xfb, 0x59, 0xf3 +}; + +__fips_constseg static const unsigned char hmac_sha256_pr_entropyinputpr2[] = { + 0x21, 0xcd, 0x6e, 0x46, 0xad, 0x99, 0x07, 0x17, 0xb4, 0x3d, 0x76, 0x0a, + 0xff, 0x5b, 0x52, 0x50, 0x78, 0xdf, 0x1f, 0x24, 0x06, 0x0d, 0x3f, 0x74, + 0xa9, 0xc9, 0x37, 0xcf, 0xd8, 0x26, 0x25, 0x91 +}; + +__fips_constseg static const unsigned char hmac_sha256_pr_returnedbits[] = { + 0xa7, 0xaf, 0x2f, 0x29, 0xe0, 0x3a, 0x72, 0x95, 0x96, 0x1c, 0xa9, 0xf0, + 0x4a, 0x17, 0x4d, 0x66, 0x06, 0x10, 0xbf, 0x39, 0x89, 0x88, 0xb8, 0x91, + 0x37, 0x18, 0x99, 0xcf, 0x8c, 0x53, 0x3b, 0x7e +}; + +/* HMAC SHA-256 No PR */ +__fips_constseg static const unsigned char hmac_sha256_entropyinput[] = { + 0x96, 0xb7, 0x53, 0x22, 0x1e, 0x52, 0x2a, 0x96, 0xb1, 0x15, 0x3c, 0x35, + 0x5a, 0x8b, 0xd3, 0x4a, 0xa6, 0x6c, 0x83, 0x0a, 0x7d, 0xa3, 0x23, 0x3d, + 0x43, 0xa1, 0x07, 0x2c, 0x2d, 0xe3, 0x81, 0xcc +}; + +__fips_constseg static const unsigned char hmac_sha256_nonce[] = { + 0xf1, 0xac, 0x97, 0xcb, 0x5e, 0x06, 0x48, 0xd2, 0x94, 0xbe, 0x15, 0x2e, + 0xc7, 0xfc, 0xc2, 0x01 +}; + +__fips_constseg + static const unsigned char hmac_sha256_personalizationstring[] = { + 0x98, 0xc5, 0x1e, 0x35, 0x5e, 0x89, 0x0d, 0xce, 0x64, 0x6d, 0x18, 0xa7, + 0x5a, 0xc6, 0xf3, 0xe7, 0xd6, 0x9e, 0xc0, 0xea, 0xb7, 0x3a, 0x8d, 0x65, + 0xb8, 0xeb, 0x10, 0xd7, 0x57, 0x18, 0xa0, 0x32 +}; + +__fips_constseg static const unsigned char hmac_sha256_additionalinput[] = { + 0x1b, 0x10, 0xaf, 0xac, 0xd0, 0x65, 0x95, 0xad, 0x04, 0xad, 0x03, 0x1c, + 0xe0, 0x40, 0xd6, 0x3e, 0x1c, 0x46, 0x53, 0x39, 0x7c, 0xe2, 0xbc, 0xda, + 0x8c, 0xa2, 0x33, 0xa7, 0x9a, 0x26, 0xd3, 0x27 +}; + +__fips_constseg static const unsigned char hmac_sha256_int_returnedbits[] = { + 0xba, 0x61, 0x0e, 0x55, 0xfe, 0x11, 0x8a, 0x9e, 0x0f, 0x80, 0xdf, 0x1d, + 0x03, 0x0a, 0xfe, 0x15, 0x94, 0x28, 0x4b, 0xba, 0xf4, 0x9f, 0x51, 0x25, + 0x88, 0xe5, 0x4e, 0xfb, 0xaf, 0xce, 0x69, 0x90 +}; + +__fips_constseg static const unsigned char hmac_sha256_entropyinputreseed[] = { + 0x62, 0x7f, 0x1e, 0x6b, 0xe8, 0x8e, 0xe1, 0x35, 0x7d, 0x9b, 0x4f, 0xc7, + 0xec, 0xc8, 0xac, 0xef, 0x6b, 0x13, 0x9e, 0x05, 0x56, 0xc1, 0x08, 0xf9, + 0x2f, 0x0f, 0x27, 0x9c, 0xd4, 0x15, 0xed, 0x2d +}; + +__fips_constseg + static const unsigned char hmac_sha256_additionalinputreseed[] = { + 0xc7, 0x76, 0x6e, 0xa9, 0xd2, 0xb2, 0x76, 0x40, 0x82, 0x25, 0x2c, 0xb3, + 0x6f, 0xac, 0xe9, 0x74, 0xef, 0x8f, 0x3c, 0x8e, 0xcd, 0xf1, 0xbf, 0xb3, + 0x49, 0x77, 0x34, 0x88, 0x52, 0x36, 0xe6, 0x2e +}; + +__fips_constseg static const unsigned char hmac_sha256_additionalinput2[] = { + 0x8d, 0xb8, 0x0c, 0xd1, 0xbf, 0x70, 0xf6, 0x19, 0xc3, 0x41, 0x80, 0x9f, + 0xe1, 0xa5, 0xa4, 0x1f, 0x2c, 0x26, 0xb1, 0xe5, 0xd8, 0xeb, 0xbe, 0xf8, + 0xdf, 0x88, 0x6a, 0x89, 0xd6, 0x05, 0xd8, 0x9d +}; + +__fips_constseg static const unsigned char hmac_sha256_returnedbits[] = { + 0x43, 0x12, 0x2a, 0x2c, 0x40, 0x53, 0x2e, 0x7c, 0x66, 0x34, 0xac, 0xc3, + 0x43, 0xe3, 0xe0, 0x6a, 0xfc, 0xfa, 0xea, 0x87, 0x21, 0x1f, 0xe2, 0x26, + 0xc4, 0xf9, 0x09, 0x9a, 0x0d, 0x6e, 0x7f, 0xe0 +}; + +/* HMAC SHA-384 PR */ +__fips_constseg static const unsigned char hmac_sha384_pr_entropyinput[] = { + 0x69, 0x81, 0x98, 0x88, 0x44, 0xf5, 0xd6, 0x2e, 0x00, 0x08, 0x3b, 0xc5, + 0xfb, 0xd7, 0x8e, 0x6f, 0x23, 0xf8, 0x6d, 0x09, 0xd6, 0x85, 0x49, 0xd1, + 0xf8, 0x6d, 0xa4, 0x58, 0x54, 0xfd, 0x88, 0xa9 +}; + +__fips_constseg static const unsigned char hmac_sha384_pr_nonce[] = { + 0x6e, 0x38, 0x81, 0xca, 0xb7, 0xe8, 0x6e, 0x66, 0x49, 0x8a, 0xb2, 0x59, + 0xee, 0x16, 0xc9, 0xde +}; + +__fips_constseg + static const unsigned char hmac_sha384_pr_personalizationstring[] = { + 0xfe, 0x4c, 0xd9, 0xf4, 0x78, 0x3b, 0x08, 0x41, 0x8d, 0x8f, 0x55, 0xc4, + 0x43, 0x56, 0xb6, 0x12, 0x36, 0x6b, 0x30, 0xb7, 0x5e, 0xe1, 0xb9, 0x47, + 0x04, 0xb1, 0x4e, 0xa9, 0x00, 0xa1, 0x52, 0xa1 +}; + +__fips_constseg static const unsigned char hmac_sha384_pr_additionalinput[] = { + 0x89, 0xe9, 0xcc, 0x8f, 0x27, 0x3c, 0x26, 0xd1, 0x95, 0xc8, 0x7d, 0x0f, + 0x5b, 0x1a, 0xf0, 0x78, 0x39, 0x56, 0x6f, 0xa4, 0x23, 0xe7, 0xd1, 0xda, + 0x7c, 0x66, 0x33, 0xa0, 0x90, 0xc9, 0x92, 0x88 +}; + +__fips_constseg static const unsigned char hmac_sha384_pr_entropyinputpr[] = { + 0xbe, 0x3d, 0x7c, 0x0d, 0xca, 0xda, 0x7c, 0x49, 0xb8, 0x12, 0x36, 0xc0, + 0xdb, 0xad, 0x35, 0xa8, 0xc7, 0x0b, 0x2a, 0x2c, 0x69, 0x6d, 0x25, 0x56, + 0x63, 0x82, 0x11, 0x3e, 0xa7, 0x33, 0x70, 0x72 +}; + +__fips_constseg static const unsigned char hmac_sha384_pr_int_returnedbits[] = { + 0x82, 0x3d, 0xe6, 0x54, 0x80, 0x42, 0xf8, 0xba, 0x90, 0x4f, 0x06, 0xa6, + 0xd2, 0x7f, 0xbf, 0x79, 0x7c, 0x12, 0x7d, 0xa6, 0xa2, 0x66, 0xe8, 0xa6, + 0xc0, 0xd6, 0x4a, 0x55, 0xbf, 0xd8, 0x0a, 0xc5, 0xf8, 0x03, 0x88, 0xdd, + 0x8e, 0x87, 0xd1, 0x5a, 0x48, 0x26, 0x72, 0x2a, 0x8e, 0xcf, 0xee, 0xba +}; + +__fips_constseg static const unsigned char hmac_sha384_pr_additionalinput2[] = { + 0x8f, 0xff, 0xd9, 0x84, 0xbb, 0x85, 0x3a, 0x66, 0xa1, 0x21, 0xce, 0xb2, + 0x3a, 0x3a, 0x17, 0x22, 0x19, 0xae, 0xc7, 0xb6, 0x63, 0x81, 0xd5, 0xff, + 0x0d, 0xc8, 0xe1, 0xaf, 0x57, 0xd2, 0xcb, 0x60 +}; + +__fips_constseg static const unsigned char hmac_sha384_pr_entropyinputpr2[] = { + 0xd7, 0xfb, 0xc9, 0xe8, 0xe2, 0xf2, 0xaa, 0x4c, 0xb8, 0x51, 0x2f, 0xe1, + 0x22, 0xba, 0xf3, 0xda, 0x0a, 0x19, 0x76, 0x71, 0x57, 0xb2, 0x1d, 0x94, + 0x09, 0x69, 0x6c, 0xd3, 0x97, 0x51, 0x81, 0x87 +}; + +__fips_constseg static const unsigned char hmac_sha384_pr_returnedbits[] = { + 0xe6, 0x19, 0x28, 0xa8, 0x21, 0xce, 0x5e, 0xdb, 0x24, 0x79, 0x8c, 0x76, + 0x5d, 0x73, 0xb2, 0xdf, 0xac, 0xef, 0x85, 0xa7, 0x3b, 0x19, 0x09, 0x8b, + 0x7f, 0x98, 0x28, 0xa9, 0x93, 0xd8, 0x7a, 0xad, 0x55, 0x8b, 0x24, 0x9d, + 0xe6, 0x98, 0xfe, 0x47, 0xd5, 0x48, 0xc1, 0x23, 0xd8, 0x1d, 0x62, 0x75 +}; + +/* HMAC SHA-384 No PR */ +__fips_constseg static const unsigned char hmac_sha384_entropyinput[] = { + 0xc3, 0x56, 0x2b, 0x1d, 0xc2, 0xbb, 0xa8, 0xf0, 0xae, 0x1b, 0x0d, 0xd3, + 0x5a, 0x6c, 0xda, 0x57, 0x8e, 0xa5, 0x8a, 0x0d, 0x6c, 0x4b, 0x18, 0xb1, + 0x04, 0x3e, 0xb4, 0x99, 0x35, 0xc4, 0xc0, 0x5f +}; + +__fips_constseg static const unsigned char hmac_sha384_nonce[] = { + 0xc5, 0x49, 0x1e, 0x66, 0x27, 0x92, 0xbe, 0xec, 0xb5, 0x1e, 0x4b, 0xb1, + 0x38, 0xe3, 0xeb, 0x62 +}; + +__fips_constseg + static const unsigned char hmac_sha384_personalizationstring[] = { + 0xbe, 0xe7, 0x6b, 0x57, 0xde, 0x88, 0x11, 0x96, 0x9b, 0x6e, 0xea, 0xe5, + 0x63, 0x83, 0x4c, 0xb6, 0x8d, 0x66, 0xaa, 0x1f, 0x8b, 0x54, 0xe7, 0x62, + 0x6d, 0x5a, 0xfc, 0xbf, 0x97, 0xba, 0xcd, 0x77 +}; + +__fips_constseg static const unsigned char hmac_sha384_additionalinput[] = { + 0xe5, 0x28, 0x5f, 0x43, 0xf5, 0x83, 0x6e, 0x0a, 0x83, 0x5c, 0xe3, 0x81, + 0x03, 0xf2, 0xf8, 0x78, 0x00, 0x7c, 0x95, 0x87, 0x16, 0xd6, 0x6c, 0x58, + 0x33, 0x6c, 0x53, 0x35, 0x0d, 0x66, 0xe3, 0xce +}; + +__fips_constseg static const unsigned char hmac_sha384_int_returnedbits[] = { + 0xe2, 0x1f, 0xf3, 0xda, 0x0d, 0x19, 0x99, 0x87, 0xc4, 0x90, 0xa2, 0x31, + 0xca, 0x2a, 0x89, 0x58, 0x43, 0x44, 0xb8, 0xde, 0xcf, 0xa4, 0xbe, 0x3b, + 0x53, 0x26, 0x22, 0x31, 0x76, 0x41, 0x22, 0xb5, 0xa8, 0x70, 0x2f, 0x4b, + 0x64, 0x95, 0x4d, 0x48, 0x96, 0x35, 0xe6, 0xbd, 0x3c, 0x34, 0xdb, 0x1b +}; + +__fips_constseg static const unsigned char hmac_sha384_entropyinputreseed[] = { + 0x77, 0x61, 0xba, 0xbc, 0xf2, 0xc1, 0xf3, 0x4b, 0x86, 0x65, 0xfd, 0x48, + 0x0e, 0x3c, 0x02, 0x5e, 0xa2, 0x7a, 0x6b, 0x7c, 0xed, 0x21, 0x5e, 0xf9, + 0xcd, 0xcd, 0x77, 0x07, 0x2b, 0xbe, 0xc5, 0x5c +}; + +__fips_constseg + static const unsigned char hmac_sha384_additionalinputreseed[] = { + 0x18, 0x24, 0x5f, 0xc6, 0x84, 0xd1, 0x67, 0xc3, 0x9a, 0x11, 0xa5, 0x8c, + 0x07, 0x39, 0x21, 0x83, 0x4d, 0x04, 0xc4, 0x6a, 0x28, 0x19, 0xcf, 0x92, + 0x21, 0xd9, 0x9e, 0x41, 0x72, 0x6c, 0x9e, 0x63 +}; + +__fips_constseg static const unsigned char hmac_sha384_additionalinput2[] = { + 0x96, 0x67, 0x41, 0x28, 0x9b, 0xb7, 0x92, 0x8d, 0x64, 0x3b, 0xe4, 0xcf, + 0x7e, 0xaa, 0x1e, 0xb1, 0x4b, 0x1d, 0x09, 0x56, 0x67, 0x9c, 0xc6, 0x6d, + 0x3b, 0xe8, 0x91, 0x9d, 0xe1, 0x8a, 0xb7, 0x32 +}; + +__fips_constseg static const unsigned char hmac_sha384_returnedbits[] = { + 0xe3, 0x59, 0x61, 0x38, 0x92, 0xec, 0xe2, 0x3c, 0xff, 0xb7, 0xdb, 0x19, + 0x0f, 0x5b, 0x93, 0x68, 0x0d, 0xa4, 0x94, 0x40, 0x72, 0x0b, 0xe0, 0xed, + 0x4d, 0xcd, 0x68, 0xa0, 0x1e, 0xfe, 0x67, 0xb2, 0xfa, 0x21, 0x56, 0x74, + 0xa4, 0xad, 0xcf, 0xb7, 0x60, 0x66, 0x2e, 0x40, 0xde, 0x82, 0xca, 0xfb +}; + +/* HMAC SHA-512 PR */ +__fips_constseg static const unsigned char hmac_sha512_pr_entropyinput[] = { + 0xaa, 0x9e, 0x45, 0x67, 0x0e, 0x00, 0x2a, 0x67, 0x98, 0xd6, 0xda, 0x0b, + 0x0f, 0x17, 0x7e, 0xac, 0xfd, 0x27, 0xc4, 0xca, 0x84, 0xdf, 0xde, 0xba, + 0x85, 0xd9, 0xbe, 0x8f, 0xf3, 0xff, 0x91, 0x4d +}; + +__fips_constseg static const unsigned char hmac_sha512_pr_nonce[] = { + 0x8c, 0x49, 0x2f, 0x58, 0x1e, 0x7a, 0xda, 0x4b, 0x7e, 0x8a, 0x30, 0x7b, + 0x86, 0xea, 0xaf, 0xa2 +}; + +__fips_constseg + static const unsigned char hmac_sha512_pr_personalizationstring[] = { + 0x71, 0xe1, 0xbb, 0xad, 0xa7, 0x4b, 0x2e, 0x31, 0x3b, 0x0b, 0xec, 0x24, + 0x99, 0x38, 0xbc, 0xaa, 0x05, 0x4c, 0x46, 0x44, 0xfa, 0xad, 0x8e, 0x02, + 0xc1, 0x7e, 0xad, 0xec, 0x54, 0xa6, 0xd0, 0xad +}; + +__fips_constseg static const unsigned char hmac_sha512_pr_additionalinput[] = { + 0x3d, 0x6e, 0xa6, 0xa8, 0x29, 0x2a, 0xb2, 0xf5, 0x98, 0x42, 0xe4, 0x92, + 0x78, 0x22, 0x67, 0xfd, 0x1b, 0x15, 0x1e, 0x29, 0xaa, 0x71, 0x3c, 0x3c, + 0xe7, 0x05, 0x20, 0xa9, 0x29, 0xc6, 0x75, 0x71 +}; + +__fips_constseg static const unsigned char hmac_sha512_pr_entropyinputpr[] = { + 0xab, 0xb9, 0x16, 0xd8, 0x55, 0x35, 0x54, 0xb7, 0x97, 0x3f, 0x94, 0xbc, + 0x2f, 0x7c, 0x70, 0xc7, 0xd0, 0xed, 0xb7, 0x4b, 0xf7, 0xf6, 0x6c, 0x03, + 0x0c, 0xb0, 0x03, 0xd8, 0xbb, 0x71, 0xd9, 0x10 +}; + +__fips_constseg static const unsigned char hmac_sha512_pr_int_returnedbits[] = { + 0x8e, 0xd3, 0xfd, 0x52, 0x9e, 0x83, 0x08, 0x49, 0x18, 0x6e, 0x23, 0x56, + 0x5c, 0x45, 0x93, 0x34, 0x05, 0xe2, 0x98, 0x8f, 0x0c, 0xd4, 0x32, 0x0c, + 0xfd, 0xda, 0x5f, 0x92, 0x3a, 0x8c, 0x81, 0xbd, 0xf6, 0x6c, 0x55, 0xfd, + 0xb8, 0x20, 0xce, 0x8d, 0x97, 0x27, 0xe8, 0xe8, 0xe0, 0xb3, 0x85, 0x50, + 0xa2, 0xc2, 0xb2, 0x95, 0x1d, 0x48, 0xd3, 0x7b, 0x4b, 0x78, 0x13, 0x35, + 0x05, 0x17, 0xbe, 0x0d +}; + +__fips_constseg static const unsigned char hmac_sha512_pr_additionalinput2[] = { + 0xc3, 0xfc, 0x95, 0xaa, 0x69, 0x06, 0xae, 0x59, 0x41, 0xce, 0x26, 0x08, + 0x29, 0x6d, 0x45, 0xda, 0xe8, 0xb3, 0x6c, 0x95, 0x60, 0x0f, 0x70, 0x2c, + 0x10, 0xba, 0x38, 0x8c, 0xcf, 0x29, 0x99, 0xaa +}; + +__fips_constseg static const unsigned char hmac_sha512_pr_entropyinputpr2[] = { + 0x3b, 0x9a, 0x25, 0xce, 0xd7, 0xf9, 0x5c, 0xd1, 0x3a, 0x3e, 0xaa, 0x71, + 0x14, 0x3e, 0x19, 0xe8, 0xce, 0xe6, 0xfe, 0x51, 0x84, 0xe9, 0x1b, 0xfe, + 0x3f, 0xa7, 0xf2, 0xfd, 0x76, 0x5f, 0x6a, 0xe7 +}; + +__fips_constseg static const unsigned char hmac_sha512_pr_returnedbits[] = { + 0xb7, 0x82, 0xa9, 0x57, 0x81, 0x67, 0x53, 0xb5, 0xa1, 0xe9, 0x3d, 0x35, + 0xf9, 0xe4, 0x97, 0xbe, 0xa6, 0xca, 0xf1, 0x01, 0x13, 0x09, 0xe7, 0x21, + 0xc0, 0xed, 0x93, 0x5d, 0x4b, 0xf4, 0xeb, 0x8d, 0x53, 0x25, 0x8a, 0xc4, + 0xb1, 0x6f, 0x6e, 0x37, 0xcd, 0x2e, 0xac, 0x39, 0xb2, 0xb6, 0x99, 0xa3, + 0x82, 0x00, 0xb0, 0x21, 0xf0, 0xc7, 0x2f, 0x4c, 0x73, 0x92, 0xfd, 0x00, + 0xb6, 0xaf, 0xbc, 0xd3 +}; + +/* HMAC SHA-512 No PR */ +__fips_constseg static const unsigned char hmac_sha512_entropyinput[] = { + 0x6e, 0x85, 0xe6, 0x25, 0x96, 0x29, 0xa7, 0x52, 0x5b, 0x60, 0xba, 0xaa, + 0xde, 0xdb, 0x36, 0x0a, 0x51, 0x9a, 0x15, 0xae, 0x6e, 0x18, 0xd3, 0xfe, + 0x39, 0xb9, 0x4a, 0x96, 0xf8, 0x77, 0xcb, 0x95 +}; + +__fips_constseg static const unsigned char hmac_sha512_nonce[] = { + 0xe0, 0xa6, 0x5d, 0x08, 0xc3, 0x7c, 0xae, 0x25, 0x2e, 0x80, 0xd1, 0x3e, + 0xd9, 0xaf, 0x43, 0x3c +}; + +__fips_constseg + static const unsigned char hmac_sha512_personalizationstring[] = { + 0x53, 0x99, 0x52, 0x5f, 0x11, 0xa9, 0x64, 0x66, 0x20, 0x5e, 0x1b, 0x5f, + 0x42, 0xb3, 0xf4, 0xda, 0xed, 0xbb, 0x63, 0xc1, 0x23, 0xaf, 0xd0, 0x01, + 0x90, 0x3b, 0xd0, 0x78, 0xe4, 0x0b, 0xa7, 0x20 +}; + +__fips_constseg static const unsigned char hmac_sha512_additionalinput[] = { + 0x85, 0x90, 0x80, 0xd3, 0x98, 0xf1, 0x53, 0x6d, 0x68, 0x15, 0x8f, 0xe5, + 0x60, 0x3f, 0x17, 0x29, 0x55, 0x8d, 0x33, 0xb1, 0x45, 0x64, 0x64, 0x8d, + 0x50, 0x21, 0x89, 0xae, 0xf6, 0xfd, 0x32, 0x73 +}; + +__fips_constseg static const unsigned char hmac_sha512_int_returnedbits[] = { + 0x28, 0x56, 0x30, 0x6f, 0xf4, 0xa1, 0x48, 0xe0, 0xc9, 0xf5, 0x75, 0x90, + 0xcc, 0xfb, 0xdf, 0xdf, 0x71, 0x3d, 0x0a, 0x9a, 0x03, 0x65, 0x3b, 0x18, + 0x61, 0xe3, 0xd1, 0xda, 0xcc, 0x4a, 0xfe, 0x55, 0x38, 0xf8, 0x21, 0x6b, + 0xfa, 0x18, 0x01, 0x42, 0x39, 0x2f, 0x99, 0x53, 0x38, 0x15, 0x82, 0x34, + 0xc5, 0x93, 0x92, 0xbc, 0x4d, 0x75, 0x1a, 0x5f, 0x21, 0x27, 0xcc, 0xa1, + 0xb1, 0x57, 0x69, 0xe8 +}; + +__fips_constseg static const unsigned char hmac_sha512_entropyinputreseed[] = { + 0x8c, 0x52, 0x7e, 0x77, 0x72, 0x3f, 0xa3, 0x04, 0x97, 0x10, 0x9b, 0x41, + 0xbd, 0xe8, 0xff, 0x89, 0xed, 0x80, 0xe3, 0xbd, 0xaa, 0x12, 0x2d, 0xca, + 0x75, 0x82, 0x36, 0x77, 0x88, 0xcd, 0xa6, 0x73 +}; + +__fips_constseg + static const unsigned char hmac_sha512_additionalinputreseed[] = { + 0x7e, 0x32, 0xe3, 0x69, 0x69, 0x07, 0x34, 0xa2, 0x16, 0xa2, 0x5d, 0x1a, + 0x10, 0x91, 0xd3, 0xe2, 0x21, 0xa2, 0xa3, 0xdd, 0xcd, 0x0c, 0x09, 0x86, + 0x11, 0xe1, 0x50, 0xff, 0x5c, 0xb7, 0xeb, 0x5c +}; + +__fips_constseg static const unsigned char hmac_sha512_additionalinput2[] = { + 0x7f, 0x78, 0x66, 0xd8, 0xfb, 0x67, 0xcf, 0x8d, 0x8c, 0x08, 0x30, 0xa5, + 0xf8, 0x7d, 0xcf, 0x44, 0x59, 0xce, 0xf8, 0xdf, 0x58, 0xd3, 0x60, 0xcb, + 0xa8, 0x60, 0xb9, 0x07, 0xc4, 0xb1, 0x95, 0x48 +}; + +__fips_constseg static const unsigned char hmac_sha512_returnedbits[] = { + 0xdf, 0xa7, 0x36, 0xd4, 0xdc, 0x5d, 0x4d, 0x31, 0xad, 0x69, 0x46, 0x9f, + 0xf1, 0x7c, 0xd7, 0x3b, 0x4f, 0x55, 0xf2, 0xd7, 0xb9, 0x9d, 0xad, 0x7a, + 0x79, 0x08, 0x59, 0xa5, 0xdc, 0x74, 0xf5, 0x9b, 0x73, 0xd2, 0x13, 0x25, + 0x0b, 0x81, 0x08, 0x08, 0x25, 0xfb, 0x39, 0xf2, 0xf0, 0xa3, 0xa4, 0x8d, + 0xef, 0x05, 0x9e, 0xb8, 0xc7, 0x52, 0xe4, 0x0e, 0x42, 0xaa, 0x7c, 0x79, + 0xc2, 0xd6, 0xfd, 0xa5 +}; diff --git a/crypto/fips/fips_dsa_selftest.c b/crypto/fips/fips_dsa_selftest.c new file mode 100644 index 0000000..4c0da82 --- /dev/null +++ b/crypto/fips/fips_dsa_selftest.c @@ -0,0 +1,192 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <string.h> +#include <openssl/crypto.h> +#include <openssl/dsa.h> +#include <openssl/fips.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include "fips_locl.h" + +#ifdef OPENSSL_FIPS + +static const unsigned char dsa_test_2048_p[] = { + 0xa8, 0x53, 0x78, 0xd8, 0xfd, 0x3f, 0x8d, 0x72, 0xec, 0x74, 0x18, 0x08, + 0x0d, 0xa2, 0x13, 0x17, 0xe4, 0x3e, 0xc4, 0xb6, 0x2b, 0xa8, 0xc8, 0x62, + 0x3b, 0x7e, 0x4d, 0x04, 0x44, 0x1d, 0xd1, 0xa0, 0x65, 0x86, 0x62, 0x59, + 0x64, 0x93, 0xca, 0x8e, 0x9e, 0x8f, 0xbb, 0x7e, 0x34, 0xaa, 0xdd, 0xb6, + 0x2e, 0x5d, 0x67, 0xb6, 0xd0, 0x9a, 0x6e, 0x61, 0xb7, 0x69, 0xe7, 0xc3, + 0x52, 0xaa, 0x2b, 0x10, 0xe2, 0x0c, 0xa0, 0x63, 0x69, 0x63, 0xb5, 0x52, + 0x3e, 0x86, 0x47, 0x0d, 0xec, 0xbb, 0xed, 0xa0, 0x27, 0xe7, 0x97, 0xe7, + 0xb6, 0x76, 0x35, 0xd4, 0xd4, 0x9c, 0x30, 0x70, 0x0e, 0x74, 0xaf, 0x8a, + 0x0f, 0xf1, 0x56, 0xa8, 0x01, 0xaf, 0x57, 0xa2, 0x6e, 0x70, 0x78, 0xf1, + 0xd8, 0x2f, 0x74, 0x90, 0x8e, 0xcb, 0x6d, 0x07, 0xe7, 0x0b, 0x35, 0x03, + 0xee, 0xd9, 0x4f, 0xa3, 0x2c, 0xf1, 0x7a, 0x7f, 0xc3, 0xd6, 0xcf, 0x40, + 0xdc, 0x7b, 0x00, 0x83, 0x0e, 0x6a, 0x25, 0x66, 0xdc, 0x07, 0x3e, 0x34, + 0x33, 0x12, 0x51, 0x7c, 0x6a, 0xa5, 0x15, 0x2b, 0x4b, 0xfe, 0xcd, 0x2e, + 0x55, 0x1f, 0xee, 0x34, 0x63, 0x18, 0xa1, 0x53, 0x42, 0x3c, 0x99, 0x6b, + 0x0d, 0x5d, 0xcb, 0x91, 0x02, 0xae, 0xdd, 0x38, 0x79, 0x86, 0x16, 0xf1, + 0xf1, 0xe0, 0xd6, 0xc4, 0x03, 0x52, 0x5b, 0x1f, 0x9b, 0x3d, 0x4d, 0xc7, + 0x66, 0xde, 0x2d, 0xfc, 0x4a, 0x56, 0xd7, 0xb8, 0xba, 0x59, 0x63, 0xd6, + 0x0f, 0x3e, 0x16, 0x31, 0x88, 0x70, 0xad, 0x43, 0x69, 0x52, 0xe5, 0x57, + 0x65, 0x37, 0x4e, 0xab, 0x85, 0xe8, 0xec, 0x17, 0xd6, 0xb9, 0xa4, 0x54, + 0x7b, 0x9b, 0x5f, 0x27, 0x52, 0xf3, 0x10, 0x5b, 0xe8, 0x09, 0xb2, 0x3a, + 0x2c, 0x8d, 0x74, 0x69, 0xdb, 0x02, 0xe2, 0x4d, 0x59, 0x23, 0x94, 0xa7, + 0xdb, 0xa0, 0x69, 0xe9 +}; + +static const unsigned char dsa_test_2048_q[] = { + 0xd2, 0x77, 0x04, 0x4e, 0x50, 0xf5, 0xa4, 0xe3, 0xf5, 0x10, 0xa5, 0x0a, + 0x0b, 0x84, 0xfd, 0xff, 0xbc, 0xa0, 0x47, 0xed, 0x27, 0x60, 0x20, 0x56, + 0x74, 0x41, 0xa0, 0xa5 +}; + +static const unsigned char dsa_test_2048_g[] = { + 0x13, 0xd7, 0x54, 0xe2, 0x1f, 0xd2, 0x41, 0x65, 0x5d, 0xa8, 0x91, 0xc5, + 0x22, 0xa6, 0x5a, 0x72, 0xa8, 0x9b, 0xdc, 0x64, 0xec, 0x9b, 0x54, 0xa8, + 0x21, 0xed, 0x4a, 0x89, 0x8b, 0x49, 0x0e, 0x0c, 0x4f, 0xcb, 0x72, 0x19, + 0x2a, 0x4a, 0x20, 0xf5, 0x41, 0xf3, 0xf2, 0x92, 0x53, 0x99, 0xf0, 0xba, + 0xec, 0xf9, 0x29, 0xaa, 0xfb, 0xf7, 0x9d, 0xfe, 0x43, 0x32, 0x39, 0x3b, + 0x32, 0xcd, 0x2e, 0x2f, 0xcf, 0x27, 0x2f, 0x32, 0xa6, 0x27, 0x43, 0x4a, + 0x0d, 0xf2, 0x42, 0xb7, 0x5b, 0x41, 0x4d, 0xf3, 0x72, 0x12, 0x1e, 0x53, + 0xa5, 0x53, 0xf2, 0x22, 0xf8, 0x36, 0xb0, 0x00, 0xf0, 0x16, 0x48, 0x5b, + 0x6b, 0xd0, 0x89, 0x84, 0x51, 0x80, 0x1d, 0xcd, 0x8d, 0xe6, 0x4c, 0xd5, + 0x36, 0x56, 0x96, 0xff, 0xc5, 0x32, 0xd5, 0x28, 0xc5, 0x06, 0x62, 0x0a, + 0x94, 0x2a, 0x03, 0x05, 0x04, 0x6d, 0x8f, 0x18, 0x76, 0x34, 0x1f, 0x1e, + 0x57, 0x0b, 0xc3, 0x97, 0x4b, 0xa6, 0xb9, 0xa4, 0x38, 0xe9, 0x70, 0x23, + 0x02, 0xa2, 0xe6, 0xe6, 0x7b, 0xfd, 0x06, 0xd3, 0x2b, 0xc6, 0x79, 0x96, + 0x22, 0x71, 0xd7, 0xb4, 0x0c, 0xd7, 0x2f, 0x38, 0x6e, 0x64, 0xe0, 0xd7, + 0xef, 0x86, 0xca, 0x8c, 0xa5, 0xd1, 0x42, 0x28, 0xdc, 0x2a, 0x4f, 0x16, + 0xe3, 0x18, 0x98, 0x86, 0xb5, 0x99, 0x06, 0x74, 0xf4, 0x20, 0x0f, 0x3a, + 0x4c, 0xf6, 0x5a, 0x3f, 0x0d, 0xdb, 0xa1, 0xfa, 0x67, 0x2d, 0xff, 0x2f, + 0x5e, 0x14, 0x3d, 0x10, 0xe4, 0xe9, 0x7a, 0xe8, 0x4f, 0x6d, 0xa0, 0x95, + 0x35, 0xd5, 0xb9, 0xdf, 0x25, 0x91, 0x81, 0xa7, 0x9b, 0x63, 0xb0, 0x69, + 0xe9, 0x49, 0x97, 0x2b, 0x02, 0xba, 0x36, 0xb3, 0x58, 0x6a, 0xab, 0x7e, + 0x45, 0xf3, 0x22, 0xf8, 0x2e, 0x4e, 0x85, 0xca, 0x3a, 0xb8, 0x55, 0x91, + 0xb3, 0xc2, 0xa9, 0x66 +}; + +static const unsigned char dsa_test_2048_pub_key[] = { + 0x24, 0x52, 0xf3, 0xcc, 0xbe, 0x9e, 0xd5, 0xca, 0x7d, 0xc7, 0x4c, 0x60, + 0x2b, 0x99, 0x22, 0x6e, 0x8f, 0x2f, 0xab, 0x38, 0xe7, 0xd7, 0xdd, 0xfb, + 0x75, 0x53, 0x9b, 0x17, 0x15, 0x5e, 0x9f, 0xcf, 0xd1, 0xab, 0xa5, 0x64, + 0xeb, 0x85, 0x35, 0xd8, 0x12, 0xc9, 0xc2, 0xdc, 0xf9, 0x72, 0x84, 0x44, + 0x1b, 0xc4, 0x82, 0x24, 0x36, 0x24, 0xc7, 0xf4, 0x57, 0x58, 0x0c, 0x1c, + 0x38, 0xa5, 0x7c, 0x46, 0xc4, 0x57, 0x39, 0x24, 0x70, 0xed, 0xb5, 0x2c, + 0xb5, 0xa6, 0xe0, 0x3f, 0xe6, 0x28, 0x7b, 0xb6, 0xf4, 0x9a, 0x42, 0xa2, + 0x06, 0x5a, 0x05, 0x4f, 0x03, 0x08, 0x39, 0xdf, 0x1f, 0xd3, 0x14, 0x9c, + 0x4c, 0xa0, 0x53, 0x1d, 0xd8, 0xca, 0x8a, 0xaa, 0x9c, 0xc7, 0x33, 0x71, + 0x93, 0x38, 0x73, 0x48, 0x33, 0x61, 0x18, 0x22, 0x45, 0x45, 0xe8, 0x8c, + 0x80, 0xff, 0xd8, 0x76, 0x5d, 0x74, 0x36, 0x03, 0x33, 0xcc, 0xab, 0x99, + 0x72, 0x77, 0x9b, 0x65, 0x25, 0xa6, 0x5b, 0xdd, 0x0d, 0x10, 0xc6, 0x75, + 0xc1, 0x09, 0xbb, 0xd3, 0xe5, 0xbe, 0x4d, 0x72, 0xef, 0x6e, 0xba, 0x6e, + 0x43, 0x8d, 0x52, 0x26, 0x23, 0x7d, 0xb8, 0x88, 0x37, 0x9c, 0x5f, 0xcc, + 0x47, 0xa3, 0x84, 0x7f, 0xf6, 0x37, 0x11, 0xba, 0xed, 0x6d, 0x03, 0xaf, + 0xe8, 0x1e, 0x69, 0x4a, 0x41, 0x3b, 0x68, 0x0b, 0xd3, 0x8a, 0xb4, 0x90, + 0x3f, 0x83, 0x70, 0xa7, 0x07, 0xef, 0x55, 0x1d, 0x49, 0x41, 0x02, 0x6d, + 0x95, 0x79, 0xd6, 0x91, 0xde, 0x8e, 0xda, 0xa1, 0x61, 0x05, 0xeb, 0x9d, + 0xba, 0x3c, 0x2f, 0x4c, 0x1b, 0xec, 0x50, 0x82, 0x75, 0xaa, 0x02, 0x07, + 0xe2, 0x51, 0xb5, 0xec, 0xcb, 0x28, 0x6a, 0x4b, 0x01, 0xd4, 0x49, 0xd3, + 0x0a, 0xcb, 0x67, 0x37, 0x17, 0xa0, 0xd2, 0xfb, 0x3b, 0x50, 0xc8, 0x93, + 0xf7, 0xda, 0xb1, 0x4f +}; + +static const unsigned char dsa_test_2048_priv_key[] = { + 0x0c, 0x4b, 0x30, 0x89, 0xd1, 0xb8, 0x62, 0xcb, 0x3c, 0x43, 0x64, 0x91, + 0xf0, 0x91, 0x54, 0x70, 0xc5, 0x27, 0x96, 0xe3, 0xac, 0xbe, 0xe8, 0x00, + 0xec, 0x55, 0xf6, 0xcc +}; + +static int corrupt_dsa; + +void FIPS_corrupt_dsa() +{ + corrupt_dsa = 1; +} + +int FIPS_selftest_dsa() +{ + DSA *dsa = NULL; + EVP_PKEY *pk = NULL; + int ret = 0; + + dsa = DSA_new(); + + if (dsa == NULL) + goto err; + + fips_load_key_component(dsa, p, dsa_test_2048); + fips_load_key_component(dsa, q, dsa_test_2048); + fips_load_key_component(dsa, g, dsa_test_2048); + fips_load_key_component(dsa, pub_key, dsa_test_2048); + fips_load_key_component(dsa, priv_key, dsa_test_2048); + + if (corrupt_dsa) + BN_set_bit(dsa->pub_key, 2047); + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_assign_DSA(pk, dsa); + + if (!fips_pkey_signature_test(pk, NULL, 0, + NULL, 0, EVP_sha256(), 0, "DSA SHA256")) + goto err; + ret = 1; + + err: + if (pk) + EVP_PKEY_free(pk); + else if (dsa) + DSA_free(dsa); + return ret; +} +#endif diff --git a/crypto/fips/fips_enc.c b/crypto/fips/fips_enc.c new file mode 100644 index 0000000..a1427b9 --- /dev/null +++ b/crypto/fips/fips_enc.c @@ -0,0 +1,189 @@ +/* fipe/evp/fips_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/fips.h> + +const EVP_CIPHER *FIPS_get_cipherbynid(int nid) +{ + switch (nid) { + case NID_aes_128_cbc: + return EVP_aes_128_cbc(); + + case NID_aes_128_ccm: + return EVP_aes_128_ccm(); + + case NID_aes_128_cfb1: + return EVP_aes_128_cfb1(); + + case NID_aes_128_cfb128: + return EVP_aes_128_cfb128(); + + case NID_aes_128_cfb8: + return EVP_aes_128_cfb8(); + + case NID_aes_128_ctr: + return EVP_aes_128_ctr(); + + case NID_aes_128_ecb: + return EVP_aes_128_ecb(); + + case NID_aes_128_gcm: + return EVP_aes_128_gcm(); + + case NID_aes_128_ofb128: + return EVP_aes_128_ofb(); + + case NID_aes_128_xts: + return EVP_aes_128_xts(); + + case NID_aes_192_cbc: + return EVP_aes_192_cbc(); + + case NID_aes_192_ccm: + return EVP_aes_192_ccm(); + + case NID_aes_192_cfb1: + return EVP_aes_192_cfb1(); + + case NID_aes_192_cfb128: + return EVP_aes_192_cfb128(); + + case NID_aes_192_cfb8: + return EVP_aes_192_cfb8(); + + case NID_aes_192_ctr: + return EVP_aes_192_ctr(); + + case NID_aes_192_ecb: + return EVP_aes_192_ecb(); + + case NID_aes_192_gcm: + return EVP_aes_192_gcm(); + + case NID_aes_192_ofb128: + return EVP_aes_192_ofb(); + + case NID_aes_256_cbc: + return EVP_aes_256_cbc(); + + case NID_aes_256_ccm: + return EVP_aes_256_ccm(); + + case NID_aes_256_cfb1: + return EVP_aes_256_cfb1(); + + case NID_aes_256_cfb128: + return EVP_aes_256_cfb128(); + + case NID_aes_256_cfb8: + return EVP_aes_256_cfb8(); + + case NID_aes_256_ctr: + return EVP_aes_256_ctr(); + + case NID_aes_256_ecb: + return EVP_aes_256_ecb(); + + case NID_aes_256_gcm: + return EVP_aes_256_gcm(); + + case NID_aes_256_ofb128: + return EVP_aes_256_ofb(); + + case NID_aes_256_xts: + return EVP_aes_256_xts(); + + case NID_des_ede_ecb: + return EVP_des_ede(); + + case NID_des_ede3_ecb: + return EVP_des_ede3(); + + case NID_des_ede3_cbc: + return EVP_des_ede3_cbc(); + + case NID_des_ede3_cfb1: + return EVP_des_ede3_cfb1(); + + case NID_des_ede3_cfb64: + return EVP_des_ede3_cfb64(); + + case NID_des_ede3_cfb8: + return EVP_des_ede3_cfb8(); + + case NID_des_ede3_ofb64: + return EVP_des_ede3_ofb(); + + case NID_des_ede_cbc: + return EVP_des_ede_cbc(); + + case NID_des_ede_cfb64: + return EVP_des_ede_cfb64(); + + case NID_des_ede_ofb64: + return EVP_des_ede_ofb(); + + default: + return NULL; + + } +} diff --git a/crypto/fips/fips_hmac_selftest.c b/crypto/fips/fips_hmac_selftest.c new file mode 100644 index 0000000..ca46450 --- /dev/null +++ b/crypto/fips/fips_hmac_selftest.c @@ -0,0 +1,134 @@ +/* ==================================================================== + * 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 <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif +#include <openssl/hmac.h> + +#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; n < sizeof(vector) / sizeof(vector[0]); n++, t++) { + md = (*t->alg) (); + 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/crypto/fips/fips_locl.h b/crypto/fips/fips_locl.h new file mode 100644 index 0000000..40f873b --- /dev/null +++ b/crypto/fips/fips_locl.h @@ -0,0 +1,71 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef OPENSSL_FIPS + +# ifdef __cplusplus +extern "C" { +# endif + +# define FIPS_MAX_CIPHER_TEST_SIZE 32 +# define fips_load_key_component(key, comp, pre) \ + key->comp = BN_bin2bn(pre##_##comp, sizeof(pre##_##comp), key->comp); \ + if (!key->comp) \ + goto err + +# define fips_post_started(id, subid, ex) 1 +# define fips_post_success(id, subid, ex) 1 +# define fips_post_failed(id, subid, ex) 1 +# define fips_post_corrupt(id, subid, ex) 1 +# define fips_post_status() 1 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/crypto/fips/fips_md.c b/crypto/fips/fips_md.c new file mode 100644 index 0000000..ef3a439 --- /dev/null +++ b/crypto/fips/fips_md.c @@ -0,0 +1,144 @@ +/* fips/evp/fips_md.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-2001 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). + * + */ + +/* Minimal standalone FIPS versions of Digest operations */ + +#define OPENSSL_FIPSAPI + +#include <stdio.h> +#include <string.h> +#include <openssl/objects.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/fips.h> + +const EVP_MD *FIPS_get_digestbynid(int nid) +{ + switch (nid) { + case NID_sha1: + return EVP_sha1(); + + case NID_sha224: + return EVP_sha224(); + + case NID_sha256: + return EVP_sha256(); + + case NID_sha384: + return EVP_sha384(); + + case NID_sha512: + return EVP_sha512(); + + default: + return NULL; + } +} diff --git a/crypto/fips/fips_post.c b/crypto/fips/fips_post.c new file mode 100644 index 0000000..629f5c2 --- /dev/null +++ b/crypto/fips/fips_post.c @@ -0,0 +1,201 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define OPENSSL_FIPSAPI + +#include <openssl/crypto.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/bio.h> +#include <openssl/hmac.h> +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <string.h> +#include <limits.h> + +#ifdef OPENSSL_FIPS + +/* Power on self test (POST) support functions */ + +# include <openssl/fips.h> +# include "fips_locl.h" + +/* Run all selftests */ +int FIPS_selftest(void) +{ + int rv = 1; + if (!FIPS_selftest_drbg()) + rv = 0; + if (!FIPS_selftest_x931()) + rv = 0; + if (!FIPS_selftest_sha1()) + rv = 0; + if (!FIPS_selftest_sha2()) + rv = 0; + if (!FIPS_selftest_hmac()) + rv = 0; + if (!FIPS_selftest_cmac()) + rv = 0; + if (!FIPS_selftest_aes()) + rv = 0; + if (!FIPS_selftest_aes_ccm()) + rv = 0; + if (!FIPS_selftest_aes_gcm()) + rv = 0; + if (!FIPS_selftest_aes_xts()) + rv = 0; + if (!FIPS_selftest_des()) + rv = 0; + if (!FIPS_selftest_rsa()) + rv = 0; + if (!FIPS_selftest_dsa()) + rv = 0; + return rv; +} + +/* Generalized public key test routine. Signs and verifies the data + * supplied in tbs using mesage digest md and setting option digest + * flags md_flags. If the 'kat' parameter is not NULL it will + * additionally check the signature matches it: a known answer test + * The string "fail_str" is used for identification purposes in case + * of failure. If "pkey" is NULL just perform a message digest check. + */ + +int fips_pkey_signature_test(EVP_PKEY *pkey, + const unsigned char *tbs, int tbslen, + const unsigned char *kat, unsigned int katlen, + const EVP_MD *digest, unsigned int md_flags, + const char *fail_str) +{ + int ret = 0; + unsigned char sigtmp[256], *sig = sigtmp; + unsigned int siglen; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + + if (digest == NULL) + digest = EVP_sha256(); + + if ((pkey->type == EVP_PKEY_RSA) + && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp))) { + sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa)); + if (!sig) { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (tbslen == -1) + tbslen = strlen((char *)tbs); + + if (md_flags) + EVP_MD_CTX_set_flags(&mctx, md_flags); + + if (!EVP_SignInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_SignUpdate(&mctx, tbs, tbslen)) + goto error; + if (!EVP_SignFinal(&mctx, sig, &siglen, pkey)) + goto error; + + if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen))) + goto error; + + if (!EVP_VerifyInit_ex(&mctx, digest, NULL)) + goto error; + if (!EVP_VerifyUpdate(&mctx, tbs, tbslen)) + goto error; + ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey); + + error: + if (sig != sigtmp) + OPENSSL_free(sig); + EVP_MD_CTX_cleanup(&mctx); + if (ret != 1) { + FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST, FIPS_R_TEST_FAILURE); + if (fail_str) + ERR_add_error_data(2, "Type=", fail_str); + return 0; + } + return 1; +} + +/* Generalized symmetric cipher test routine. Encrypt data, verify result + * against known answer, decrypt and compare with original plaintext. + */ + +int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, + const unsigned char *plaintext, + const unsigned char *ciphertext, int len) +{ + unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE]; + unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE]; + + OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE); + memset(pltmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); + memset(citmp, 0, FIPS_MAX_CIPHER_TEST_SIZE); + + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0) + return 0; + if (EVP_Cipher(ctx, citmp, plaintext, len) <= 0) + return 0; + if (memcmp(citmp, ciphertext, len)) + return 0; + if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0) + return 0; + if (EVP_Cipher(ctx, pltmp, citmp, len) <= 0) + return 0; + if (memcmp(pltmp, plaintext, len)) + return 0; + return 1; +} +#endif diff --git a/crypto/fips/fips_rand.c b/crypto/fips/fips_rand.c new file mode 100644 index 0000000..c5060a2 --- /dev/null +++ b/crypto/fips/fips_rand.c @@ -0,0 +1,428 @@ +/* ==================================================================== + * 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 <openssl/crypto.h> +#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 <openssl/rand.h> +#include <openssl/aes.h> +#include <openssl/err.h> +#include <openssl/fips_rand.h> +#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS)) +# include <sys/time.h> +#endif +#if defined(OPENSSL_SYS_VXWORKS) +# include <time.h> +#endif +#include <assert.h> +#ifndef OPENSSL_SYS_WIN32 +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include <unistd.h> +# endif +#endif +#include <string.h> +#include <openssl/fips.h> +#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_x931_stick(int onoff) +{ + fips_prng_fail = onoff; +} + +void FIPS_rng_stick(void) +{ + FIPS_x931_stick(1); +} + +static 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, unsigned int keylen) +{ + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_FIPS_SET_PRNG_KEY, FIPS_R_SELFTEST_FAILED); + return 0; + } + 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, unsigned int seedlen) +{ + unsigned 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; +} + +static 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_x931_test_mode(void) +{ + return fips_set_test_mode(&sctx); +} + +int FIPS_rand_test_mode(void) +{ + return fips_set_test_mode(&sctx); +} + +int FIPS_x931_set_dt(unsigned char *dt) +{ + if (!sctx.test_mode) { + RANDerr(RAND_F_FIPS_X931_SET_DT, RAND_R_NOT_IN_TEST_MODE); + return 0; + } + memcpy(sctx.DT, dt, AES_BLOCK_LENGTH); + return 1; +} + +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; +} + +void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr) +{ +# ifdef OPENSSL_SYS_WIN32 + FILETIME ft; +# elif defined(OPENSSL_SYS_VXWORKS) + struct timespec ts; +# else + struct timeval tv; +# endif + +# 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); +# elif defined(OPENSSL_SYS_VXWORKS) + clock_gettime(CLOCK_REALTIME, &ts); + buf[0] = (unsigned char)(ts.tv_sec & 0xff); + buf[1] = (unsigned char)((ts.tv_sec >> 8) & 0xff); + buf[2] = (unsigned char)((ts.tv_sec >> 16) & 0xff); + buf[3] = (unsigned char)((ts.tv_sec >> 24) & 0xff); + buf[4] = (unsigned char)(ts.tv_nsec & 0xff); + buf[5] = (unsigned char)((ts.tv_nsec >> 8) & 0xff); + buf[6] = (unsigned char)((ts.tv_nsec >> 16) & 0xff); + buf[7] = (unsigned char)((ts.tv_nsec >> 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)(*pctr & 0xff); + buf[9] = (unsigned char)((*pctr >> 8) & 0xff); + buf[10] = (unsigned char)((*pctr >> 16) & 0xff); + buf[11] = (unsigned char)((*pctr >> 24) & 0xff); + + (*pctr)++; + +# 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, unsigned int 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_timevec(ctx->DT, &ctx->counter); + 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_x931_set_key(const unsigned char *key, int 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_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen) +{ + return FIPS_x931_set_key(key, keylen); +} + +int FIPS_x931_seed(const void *seed, int 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_x931_bytes(unsigned char *out, int 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_x931_status(void) +{ + int ret; + CRYPTO_r_lock(CRYPTO_LOCK_RAND); + ret = sctx.seeded; + CRYPTO_r_unlock(CRYPTO_LOCK_RAND); + return ret; +} + +void FIPS_x931_reset(void) +{ + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + fips_rand_prng_reset(&sctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); +} + +static int fips_do_rand_seed(const void *seed, int seedlen) +{ + FIPS_x931_seed(seed, seedlen); + return 1; +} + +static int fips_do_rand_add(const void *seed, int seedlen, double add_entropy) +{ + FIPS_x931_seed(seed, seedlen); + return 1; +} + +static const RAND_METHOD rand_x931_meth = { + fips_do_rand_seed, + FIPS_x931_bytes, + FIPS_x931_reset, + fips_do_rand_add, + FIPS_x931_bytes, + FIPS_x931_status +}; + +const RAND_METHOD *FIPS_x931_method(void) +{ + return &rand_x931_meth; +} + +#endif diff --git a/crypto/fips/fips_rand.h b/crypto/fips/fips_rand.h new file mode 100644 index 0000000..e78eb35 --- /dev/null +++ b/crypto/fips/fips_rand.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. + * + */ + +#ifndef HEADER_FIPS_RAND_H +# define HEADER_FIPS_RAND_H + +# include <openssl/aes.h> +# include <openssl/evp.h> +# include <openssl/hmac.h> +# include <openssl/rand.h> + +# ifdef OPENSSL_FIPS + +# ifdef __cplusplus +extern "C" { +# endif + + int FIPS_x931_set_key(const unsigned char *key, int keylen); + int FIPS_x931_seed(const void *buf, int num); + int FIPS_x931_bytes(unsigned char *out, int outlen); + + int FIPS_x931_test_mode(void); + void FIPS_x931_reset(void); + int FIPS_x931_set_dt(unsigned char *dt); + + int FIPS_x931_status(void); + + const RAND_METHOD *FIPS_x931_method(void); + + typedef struct drbg_ctx_st DRBG_CTX; +/* DRBG external flags */ +/* Flag for CTR mode only: use derivation function ctr_df */ +# define DRBG_FLAG_CTR_USE_DF 0x1 +/* PRNG is in test state */ +# define DRBG_FLAG_TEST 0x2 + + DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags); + int FIPS_drbg_init(DRBG_CTX *dctx, int type, unsigned int flags); + int FIPS_drbg_instantiate(DRBG_CTX *dctx, + const unsigned char *pers, size_t perslen); + int FIPS_drbg_reseed(DRBG_CTX *dctx, const unsigned char *adin, + size_t adinlen); + int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen); + + int FIPS_drbg_uninstantiate(DRBG_CTX *dctx); + void FIPS_drbg_free(DRBG_CTX *dctx); + + int FIPS_drbg_set_callbacks(DRBG_CTX *dctx, + size_t (*get_entropy) (DRBG_CTX *ctx, + unsigned char **pout, + int entropy, + size_t min_len, + size_t max_len), + void (*cleanup_entropy) (DRBG_CTX *ctx, + unsigned char *out, + size_t olen), + size_t entropy_blocklen, + size_t (*get_nonce) (DRBG_CTX *ctx, + unsigned char **pout, + int entropy, + size_t min_len, + size_t max_len), + void (*cleanup_nonce) (DRBG_CTX *ctx, + unsigned char *out, + size_t olen)); + + int FIPS_drbg_set_rand_callbacks(DRBG_CTX *dctx, + size_t (*get_adin) (DRBG_CTX *ctx, + unsigned char + **pout), + void (*cleanup_adin) (DRBG_CTX *ctx, + unsigned char *out, + size_t olen), + int (*rand_seed_cb) (DRBG_CTX *ctx, + const void *buf, + int num), + int (*rand_add_cb) (DRBG_CTX *ctx, + const void *buf, + int num, + double entropy)); + + void *FIPS_drbg_get_app_data(DRBG_CTX *ctx); + void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data); + size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx); + int FIPS_drbg_get_strength(DRBG_CTX *dctx); + void FIPS_drbg_set_check_interval(DRBG_CTX *dctx, int interval); + void FIPS_drbg_set_reseed_interval(DRBG_CTX *dctx, int interval); + + int FIPS_drbg_health_check(DRBG_CTX *dctx); + + DRBG_CTX *FIPS_get_default_drbg(void); + const RAND_METHOD *FIPS_drbg_method(void); + + int FIPS_rand_set_method(const RAND_METHOD *meth); + const RAND_METHOD *FIPS_rand_get_method(void); + + void FIPS_rand_set_bits(int nbits); + + int FIPS_rand_strength(void); + +/* 1.0.0 compat functions */ + 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/crypto/fips/fips_rand_lcl.h b/crypto/fips/fips_rand_lcl.h new file mode 100644 index 0000000..0a1d251 --- /dev/null +++ b/crypto/fips/fips_rand_lcl.h @@ -0,0 +1,213 @@ +/* fips/rand/fips_rand_lcl.h */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +typedef struct drbg_hash_ctx_st DRBG_HASH_CTX; +typedef struct drbg_hmac_ctx_st DRBG_HMAC_CTX; +typedef struct drbg_ctr_ctx_st DRBG_CTR_CTX; + +/* 888 bits from 10.1 table 2 */ +#define HASH_PRNG_MAX_SEEDLEN 111 + +struct drbg_hash_ctx_st { + const EVP_MD *md; + EVP_MD_CTX mctx; + unsigned char V[HASH_PRNG_MAX_SEEDLEN]; + unsigned char C[HASH_PRNG_MAX_SEEDLEN]; + /* Temporary value storage: should always exceed max digest length */ + unsigned char vtmp[HASH_PRNG_MAX_SEEDLEN]; +}; + +struct drbg_hmac_ctx_st { + const EVP_MD *md; + HMAC_CTX hctx; + unsigned char K[EVP_MAX_MD_SIZE]; + unsigned char V[EVP_MAX_MD_SIZE]; +}; + +struct drbg_ctr_ctx_st { + AES_KEY ks; + size_t keylen; + unsigned char K[32]; + unsigned char V[16]; + /* Temp variables used by derivation function */ + AES_KEY df_ks; + AES_KEY df_kxks; + /* Temporary block storage used by ctr_df */ + unsigned char bltmp[16]; + size_t bltmp_pos; + unsigned char KX[48]; +}; + +/* DRBG internal flags */ + +/* Functions shouldn't call err library */ +#define DRBG_FLAG_NOERR 0x1 +/* Custom reseed checking */ +#define DRBG_CUSTOM_RESEED 0x2 + +/* DRBG status values */ +/* not initialised */ +#define DRBG_STATUS_UNINITIALISED 0 +/* ok and ready to generate random bits */ +#define DRBG_STATUS_READY 1 +/* reseed required */ +#define DRBG_STATUS_RESEED 2 +/* fatal error condition */ +#define DRBG_STATUS_ERROR 3 + +/* A default maximum length: larger than any reasonable value used in pratice */ + +#define DRBG_MAX_LENGTH 0x7ffffff0 +/* Maximum DRBG block length: all md sizes are bigger than cipher blocks sizes + * so use max digest length. + */ +#define DRBG_MAX_BLOCK EVP_MAX_MD_SIZE + +#define DRBG_HEALTH_INTERVAL (1 << 24) + +/* DRBG context structure */ + +struct drbg_ctx_st { + /* First types common to all implementations */ + /* DRBG type: a NID for the underlying algorithm */ + int type; + /* Various external flags */ + unsigned int xflags; + /* Various internal use only flags */ + unsigned int iflags; + /* Used for periodic health checks */ + int health_check_cnt, health_check_interval; + + /* The following parameters are setup by mechanism drbg_init() call */ + int strength; + size_t blocklength; + size_t max_request; + + size_t min_entropy, max_entropy; + size_t min_nonce, max_nonce; + size_t max_pers, max_adin; + unsigned int reseed_counter; + unsigned int reseed_interval; + size_t seedlen; + int status; + /* Application data: typically used by test get_entropy */ + void *app_data; + /* Implementation specific structures */ + union { + DRBG_HASH_CTX hash; + DRBG_HMAC_CTX hmac; + DRBG_CTR_CTX ctr; + } d; + /* Initialiase PRNG and setup callbacks below */ + int (*init) (DRBG_CTX *ctx, int nid, int security, unsigned int flags); + /* Intantiate PRNG */ + int (*instantiate) (DRBG_CTX *ctx, + const unsigned char *ent, size_t entlen, + const unsigned char *nonce, size_t noncelen, + const unsigned char *pers, size_t perslen); + /* reseed */ + int (*reseed) (DRBG_CTX *ctx, + const unsigned char *ent, size_t entlen, + const unsigned char *adin, size_t adinlen); + /* generat output */ + int (*generate) (DRBG_CTX *ctx, + unsigned char *out, size_t outlen, + const unsigned char *adin, size_t adinlen); + /* uninstantiate */ + int (*uninstantiate) (DRBG_CTX *ctx); + + /* Entropy source block length */ + size_t entropy_blocklen; + + /* entropy gathering function */ + size_t (*get_entropy) (DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len); + /* Indicates we have finished with entropy buffer */ + void (*cleanup_entropy) (DRBG_CTX *ctx, unsigned char *out, size_t olen); + + /* nonce gathering function */ + size_t (*get_nonce) (DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len); + /* Indicates we have finished with nonce buffer */ + void (*cleanup_nonce) (DRBG_CTX *ctx, unsigned char *out, size_t olen); + + /* Continuous random number test temporary area */ + /* Last block */ + unsigned char lb[EVP_MAX_MD_SIZE]; + /* set if lb is valid */ + int lb_valid; + + /* Callbacks used when called through RAND interface */ + /* Get any additional input for generate */ + size_t (*get_adin) (DRBG_CTX *ctx, unsigned char **pout); + void (*cleanup_adin) (DRBG_CTX *ctx, unsigned char *out, size_t olen); + /* Callback for RAND_seed(), RAND_add() */ + int (*rand_seed_cb) (DRBG_CTX *ctx, const void *buf, int num); + int (*rand_add_cb) (DRBG_CTX *ctx, + const void *buf, int num, double entropy); +}; + +int fips_drbg_ctr_init(DRBG_CTX *dctx); +int fips_drbg_hash_init(DRBG_CTX *dctx); +int fips_drbg_hmac_init(DRBG_CTX *dctx); +int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags); +int fips_drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out); + +const struct env_md_st *FIPS_get_digestbynid(int nid); + +const struct evp_cipher_st *FIPS_get_cipherbynid(int nid); + +#define FIPS_digestinit EVP_DigestInit +#define FIPS_digestupdate EVP_DigestUpdate +#define FIPS_digestfinal EVP_DigestFinal +#define M_EVP_MD_size EVP_MD_size diff --git a/crypto/fips/fips_rand_lib.c b/crypto/fips/fips_rand_lib.c new file mode 100644 index 0000000..6f2ccc6 --- /dev/null +++ b/crypto/fips/fips_rand_lib.c @@ -0,0 +1,181 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <openssl/crypto.h> +#include <openssl/rand.h> +#include <openssl/err.h> +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#include "e_os.h" + +/* FIPS API for PRNG use. Similar to RAND functionality but without + * ENGINE and additional checking for non-FIPS rand methods. + */ + +static const RAND_METHOD *fips_rand_meth = NULL; +static int fips_approved_rand_meth = 0; +static int fips_rand_bits = 0; + +/* Allows application to override number of bits and uses non-FIPS methods */ +void FIPS_rand_set_bits(int nbits) +{ + fips_rand_bits = nbits; +} + +int FIPS_rand_set_method(const RAND_METHOD *meth) +{ + if (!fips_rand_bits) { + if (meth == FIPS_drbg_method()) + fips_approved_rand_meth = 1; + else if (meth == FIPS_x931_method()) + fips_approved_rand_meth = 2; + else { + fips_approved_rand_meth = 0; + if (FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_RAND_SET_METHOD, FIPS_R_NON_FIPS_METHOD); + return 0; + } + } + } + fips_rand_meth = meth; + return 1; +} + +const RAND_METHOD *FIPS_rand_get_method(void) +{ + return fips_rand_meth; +} + +const RAND_METHOD *FIPS_rand_method(void) +{ + return FIPS_rand_get_method(); +} + +void FIPS_rand_reset(void) +{ + if (fips_rand_meth && fips_rand_meth->cleanup) + fips_rand_meth->cleanup(); +} + +int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num) +{ + if (!fips_approved_rand_meth && FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_RAND_SEED, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->seed) + fips_rand_meth->seed(buf, num); + return 1; +} + +void FIPS_rand_add(const void *buf, int num, double entropy) +{ + if (!fips_approved_rand_meth && FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_RAND_ADD, FIPS_R_NON_FIPS_METHOD); + return; + } + if (fips_rand_meth && fips_rand_meth->add) + fips_rand_meth->add(buf, num, entropy); +} + +int FIPS_rand_bytes(unsigned char *buf, FIPS_RAND_SIZE_T num) +{ + if (!fips_approved_rand_meth && FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_RAND_BYTES, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->bytes) + return fips_rand_meth->bytes(buf, num); + return 0; +} + +int FIPS_rand_pseudo_bytes(unsigned char *buf, int num) +{ + if (!fips_approved_rand_meth && FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_RAND_PSEUDO_BYTES, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->pseudorand) + return fips_rand_meth->pseudorand(buf, num); + return -1; +} + +int FIPS_rand_status(void) +{ + if (!fips_approved_rand_meth && FIPS_module_mode()) { + FIPSerr(FIPS_F_FIPS_RAND_STATUS, FIPS_R_NON_FIPS_METHOD); + return 0; + } + if (fips_rand_meth && fips_rand_meth->status) + return fips_rand_meth->status(); + return 0; +} + +/* Return instantiated strength of PRNG. For DRBG this is an internal + * parameter. For X9.31 PRNG it is 80 bits (from SP800-131). Any other + * type of PRNG is not approved and returns 0 in FIPS mode and maximum + * 256 outside FIPS mode. + */ + +int FIPS_rand_strength(void) +{ + if (fips_rand_bits) + return fips_rand_bits; + if (fips_approved_rand_meth == 1) + return FIPS_drbg_get_strength(FIPS_get_default_drbg()); + else if (fips_approved_rand_meth == 2) + return 80; + else if (fips_approved_rand_meth == 0) { + if (FIPS_module_mode()) + return 0; + else + return 256; + } + return 0; +} diff --git a/crypto/fips/fips_rand_selftest.c b/crypto/fips/fips_rand_selftest.c new file mode 100644 index 0000000..d88fdf7 --- /dev/null +++ b/crypto/fips/fips_rand_selftest.c @@ -0,0 +1,176 @@ +/* ==================================================================== + * 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 <string.h> +#include <openssl/err.h> +#include <openssl/fips.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include "fips_locl.h" + +#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} +}; + +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} +}; + +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} +}; + +void FIPS_corrupt_rng() +{ + aes_192_tv.V[0]++; +} + +# define fips_x931_test(key, tv) \ + do_x931_test(key, sizeof key, &tv) + +static int do_x931_test(unsigned char *key, int keylen, AES_PRNG_TV * tv) +{ + unsigned char R[16], V[16]; + int rv = 1; + memcpy(V, tv->V, sizeof(V)); + if (!FIPS_x931_set_key(key, keylen)) + return 0; + if (!fips_post_started(FIPS_TEST_X931, keylen, NULL)) + return 1; + if (!fips_post_corrupt(FIPS_TEST_X931, keylen, NULL)) + V[0]++; + FIPS_x931_seed(V, 16); + FIPS_x931_set_dt(tv->DT); + FIPS_x931_bytes(R, 16); + if (memcmp(R, tv->R, 16)) { + fips_post_failed(FIPS_TEST_X931, keylen, NULL); + rv = 0; + } else if (!fips_post_success(FIPS_TEST_X931, keylen, NULL)) + return 0; + return rv; +} + +int FIPS_selftest_x931() +{ + int rv = 1; + FIPS_x931_reset(); + if (!FIPS_x931_test_mode()) { + FIPSerr(FIPS_F_FIPS_SELFTEST_X931, FIPS_R_SELFTEST_FAILED); + return 0; + } + if (!fips_x931_test(aes_128_key, aes_128_tv)) + rv = 0; + if (!fips_x931_test(aes_192_key, aes_192_tv)) + rv = 0; + if (!fips_x931_test(aes_256_key, aes_256_tv)) + rv = 0; + FIPS_x931_reset(); + if (!rv) + FIPSerr(FIPS_F_FIPS_SELFTEST_X931, FIPS_R_SELFTEST_FAILED); + return rv; +} + +int FIPS_selftest_rng(void) +{ + return FIPS_selftest_x931(); +} + +#endif diff --git a/crypto/fips/fips_randtest.c b/crypto/fips/fips_randtest.c new file mode 100644 index 0000000..283f5bd --- /dev/null +++ b/crypto/fips/fips_randtest.c @@ -0,0 +1,247 @@ +/* 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <openssl/rand.h> +#include <openssl/fips_rand.h> +#include <openssl/err.h> +#include <openssl/bn.h> + +#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" +# include <openssl/fips.h> + +typedef struct { + unsigned char DT[16]; + unsigned char V[16]; + unsigned char R[16]; +} AES_PRNG_MCT; + +static const unsigned char aes_128_mct_key[16] = + { 0x9f, 0x5b, 0x51, 0x20, 0x0b, 0xf3, 0x34, 0xb5, + 0xd8, 0x2b, 0xe8, 0xc3, 0x72, 0x55, 0xc8, 0x48 +}; + +static const 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 const 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 const 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 const 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 const 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(const unsigned char *key, int keylen, + const AES_PRNG_MCT * tv) +{ + unsigned char buf[16], dt[16]; + int i, j; + FIPS_x931_reset(); + FIPS_x931_test_mode(); + FIPS_x931_set_key(key, keylen); + FIPS_x931_seed(tv->V, 16); + memcpy(dt, tv->DT, 16); + for (i = 0; i < 10000; i++) { + FIPS_x931_set_dt(dt); + FIPS_x931_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/crypto/fips/fips_rsa_selftest.c b/crypto/fips/fips_rsa_selftest.c new file mode 100644 index 0000000..e87fbda --- /dev/null +++ b/crypto/fips/fips_rsa_selftest.c @@ -0,0 +1,444 @@ +/* ==================================================================== + * 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 <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif +#include <openssl/rsa.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include <openssl/opensslconf.h> + +#ifdef OPENSSL_FIPS + +static const 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 corrupt_rsa; + +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); + if (corrupt_rsa) + BN_set_bit(key->n, 1024); + 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() +{ + corrupt_rsa = 1; +} + +/* Known Answer Test (KAT) data for the above RSA private key signing + * kat_tbs. + */ + +static const unsigned char kat_tbs[] = + "OpenSSL FIPS 140-2 Public Key RSA KAT"; + +static const unsigned char kat_RSA_PSS_SHA1[] = { + 0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F, + 0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB, + 0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3, + 0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C, + 0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7, + 0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5, + 0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45, + 0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31, + 0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8, + 0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84, + 0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9 +}; + +static const unsigned char kat_RSA_PSS_SHA224[] = { + 0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7, + 0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA, + 0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57, + 0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89, + 0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE, + 0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22, + 0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5, + 0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49, + 0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D, + 0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00, + 0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0 +}; + +static const unsigned char kat_RSA_PSS_SHA256[] = { + 0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89, + 0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F, + 0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28, + 0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E, + 0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05, + 0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA, + 0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6, + 0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F, + 0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D, + 0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6, + 0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C +}; + +static const unsigned char kat_RSA_PSS_SHA384[] = { + 0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2, + 0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E, + 0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD, + 0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F, + 0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C, + 0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB, + 0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F, + 0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89, + 0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F, + 0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55, + 0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1 +}; + +static const unsigned char kat_RSA_PSS_SHA512[] = { + 0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C, + 0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A, + 0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD, + 0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39, + 0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7, + 0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61, + 0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13, + 0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63, + 0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE, + 0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88, + 0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B +}; + +static const unsigned char kat_RSA_SHA1[] = { + 0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C, + 0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B, + 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF, + 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8, + 0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1, + 0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA, + 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E, + 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F, + 0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F, + 0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95, + 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4 +}; + +static const unsigned char kat_RSA_SHA224[] = { + 0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9, + 0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D, + 0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89, + 0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD, + 0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5, + 0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC, + 0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B, + 0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2, + 0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35, + 0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC, + 0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D +}; + +static const unsigned char kat_RSA_SHA256[] = { + 0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23, + 0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23, + 0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35, + 0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E, + 0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18, + 0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30, + 0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A, + 0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38, + 0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA, + 0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90, + 0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A +}; + +static const unsigned char kat_RSA_SHA384[] = { + 0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F, + 0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7, + 0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C, + 0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55, + 0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF, + 0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2, + 0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C, + 0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD, + 0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1, + 0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04, + 0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF +}; + +static const unsigned char kat_RSA_SHA512[] = { + 0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF, + 0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A, + 0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1, + 0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8, + 0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5, + 0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B, + 0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6, + 0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05, + 0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D, + 0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91, + 0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84 +}; + +static const unsigned char kat_RSA_X931_SHA1[] = { + 0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF, + 0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75, + 0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC, + 0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97, + 0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6, + 0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19, + 0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7, + 0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99, + 0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76, + 0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67, + 0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49 +}; + +static const unsigned char kat_RSA_X931_SHA256[] = { + 0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89, + 0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD, + 0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF, + 0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B, + 0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B, + 0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98, + 0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC, + 0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C, + 0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD, + 0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC, + 0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80 +}; + +static const unsigned char kat_RSA_X931_SHA384[] = { + 0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B, + 0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB, + 0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3, + 0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6, + 0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31, + 0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1, + 0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79, + 0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF, + 0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35, + 0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D, + 0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28 +}; + +static const unsigned char kat_RSA_X931_SHA512[] = { + 0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63, + 0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC, + 0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7, + 0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28, + 0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5, + 0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF, + 0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0, + 0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09, + 0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C, + 0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B, + 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3 +}; + +int FIPS_selftest_rsa() +{ + int ret = 0; + RSA *key; + EVP_PKEY *pk = NULL; + + if ((key = RSA_new()) == NULL) + goto err; + setrsakey(key); + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_assign_RSA(pk, key); + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA1, sizeof(kat_RSA_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA1 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA224, sizeof(kat_RSA_SHA224), + EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA224 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA256, sizeof(kat_RSA_SHA256), + EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA256 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA384, sizeof(kat_RSA_SHA384), + EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA384 PKCS#1")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA512, sizeof(kat_RSA_SHA512), + EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1, + "RSA SHA512 PKCS#1")) + goto err; + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1), + EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, + "RSA SHA1 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA224, + sizeof(kat_RSA_PSS_SHA224), EVP_sha224(), + EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA224 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA256, + sizeof(kat_RSA_PSS_SHA256), EVP_sha256(), + EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA256 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA384, + sizeof(kat_RSA_PSS_SHA384), EVP_sha384(), + EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA384 PSS")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_PSS_SHA512, + sizeof(kat_RSA_PSS_SHA512), EVP_sha512(), + EVP_MD_CTX_FLAG_PAD_PSS, "RSA SHA512 PSS")) + goto err; + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA1, + sizeof(kat_RSA_X931_SHA1), EVP_sha1(), + EVP_MD_CTX_FLAG_PAD_X931, "RSA SHA1 X931")) + goto err; + /* NB: SHA224 not supported in X9.31 */ + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA256, + sizeof(kat_RSA_X931_SHA256), EVP_sha256(), + EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA256 X931")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA384, + sizeof(kat_RSA_X931_SHA384), EVP_sha384(), + EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA384 X931")) + goto err; + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_X931_SHA512, + sizeof(kat_RSA_X931_SHA512), EVP_sha512(), + EVP_MD_CTX_FLAG_PAD_X931, + "RSA SHA512 X931")) + goto err; + + ret = 1; + + err: + if (pk) + EVP_PKEY_free(pk); + else if (key) + RSA_free(key); + return ret; +} + +#endif /* def OPENSSL_FIPS */ diff --git a/crypto/fips/fips_rsa_x931g.c b/crypto/fips/fips_rsa_x931g.c new file mode 100644 index 0000000..c70e272 --- /dev/null +++ b/crypto/fips/fips_rsa_x931g.c @@ -0,0 +1,273 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <openssl/err.h> +#include <openssl/bn.h> +#include <openssl/rsa.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> + +extern int fips_check_rsa(RSA *rsa); +#endif + +/* X9.31 RSA key derivation and generation */ + +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, + BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2, + const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb) +{ + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL; + BN_CTX *ctx = NULL, *ctx2 = NULL; + + if (!rsa) + goto err; + + ctx = BN_CTX_new(); + if (!ctx) + goto err; + BN_CTX_start(ctx); + + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + + if (r3 == NULL) + goto err; + if (!rsa->e) { + rsa->e = BN_dup(e); + if (!rsa->e) + goto err; + } else + e = rsa->e; + + /* If not all parameters present only calculate what we can. + * This allows test programs to output selective parameters. + */ + + if (Xp && !rsa->p) { + rsa->p = BN_new(); + if (!rsa->p) + goto err; + + if (!BN_X931_derive_prime_ex(rsa->p, p1, p2, + Xp, Xp1, Xp2, e, ctx, cb)) + goto err; + } + + if (Xq && !rsa->q) { + rsa->q = BN_new(); + if (!rsa->q) + goto err; + if (!BN_X931_derive_prime_ex(rsa->q, q1, q2, + Xq, Xq1, Xq2, e, ctx, cb)) + goto err; + } + + if (!rsa->p || !rsa->q) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return 2; + } + + /* Since both primes are set we can now calculate all remaining + * components. + */ + + /* calculate n */ + rsa->n = BN_new(); + if (rsa->n == NULL) + goto err; + if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1, rsa->p, BN_value_one())) + goto err; /* p-1 */ + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; /* q-1 */ + if (!BN_mul(r0, r1, r2, ctx)) + goto err; /* (p-1)(q-1) */ + + if (!BN_gcd(r3, r1, r2, ctx)) + goto err; + + if (!BN_div(r0, NULL, r0, r3, ctx)) + goto err; /* LCM((p-1)(q-1)) */ + + ctx2 = BN_CTX_new(); + if (!ctx2) + goto err; + + rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */ + if (rsa->d == NULL) + goto err; + + /* calculate d mod (p-1) */ + rsa->dmp1 = BN_new(); + if (rsa->dmp1 == NULL) + goto err; + if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx)) + goto err; + + /* calculate d mod (q-1) */ + rsa->dmq1 = BN_new(); + if (rsa->dmq1 == NULL) + goto err; + if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx)) + goto err; + + /* calculate inverse of q mod p */ + rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2); + + err: + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (ctx2) + BN_CTX_free(ctx2); + /* If this is set all calls successful */ + if (rsa && rsa->iqmp != NULL) + return 1; + + return 0; + +} + +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, + BN_GENCB *cb) +{ + int ok = 0; + BIGNUM *Xp = NULL, *Xq = NULL; + BN_CTX *ctx = NULL; + +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) && + (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX, FIPS_R_KEY_TOO_SHORT); + return 0; + } + + if (bits & 0xff) { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX, FIPS_R_INVALID_KEY_LENGTH); + return 0; + } + + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX, FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } +#endif + + ctx = BN_CTX_new(); + if (!ctx) + goto error; + + BN_CTX_start(ctx); + Xp = BN_CTX_get(ctx); + Xq = BN_CTX_get(ctx); + if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx)) + goto error; + + rsa->p = BN_new(); + rsa->q = BN_new(); + if (!rsa->p || !rsa->q) + goto error; + + /* Generate two primes from Xp, Xq */ + + if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp, + e, ctx, cb)) + goto error; + + if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq, + e, ctx, cb)) + goto error; + + /* Since rsa->p and rsa->q are valid this call will just derive + * remaining RSA components. + */ + + if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, e, cb)) + goto error; + +#ifdef OPENSSL_FIPS + if (!fips_check_rsa(rsa)) + goto error; +#endif + + ok = 1; + + error: + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + if (ok) + return 1; + + return 0; + +} diff --git a/crypto/fips/fips_sha_selftest.c b/crypto/fips/fips_sha_selftest.c new file mode 100644 index 0000000..446ddd9 --- /dev/null +++ b/crypto/fips/fips_sha_selftest.c @@ -0,0 +1,145 @@ +/* ==================================================================== + * 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 <string.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif +#include <openssl/evp.h> +#include <openssl/sha.h> + +#ifdef OPENSSL_FIPS +static const 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}, +}; + +static int corrupt_sha; + +void FIPS_corrupt_sha1() +{ + corrupt_sha = 1; +} + +int FIPS_selftest_sha1() +{ + int n; + + for (n = 0; n < sizeof(test) / sizeof(test[0]); ++n) { + unsigned char md[SHA_DIGEST_LENGTH]; + + EVP_Digest(test[n], strlen(test[n]) + corrupt_sha, md, NULL, + EVP_sha1(), NULL); + if (memcmp(md, ret[n], sizeof md)) { + FIPSerr(FIPS_F_FIPS_SELFTEST_SHA1, FIPS_R_SELFTEST_FAILED); + return 0; + } + } + return 1; +} + +static const unsigned char msg_sha256[] = + { 0xfa, 0x48, 0x59, 0x2a, 0xe1, 0xae, 0x1f, 0x30, + 0xfc +}; + +static const unsigned char dig_sha256[] = + { 0xf7, 0x26, 0xd8, 0x98, 0x47, 0x91, 0x68, 0x5b, + 0x9e, 0x39, 0xb2, 0x58, 0xbb, 0x75, 0xbf, 0x01, + 0x17, 0x0c, 0x84, 0x00, 0x01, 0x7a, 0x94, 0x83, + 0xf3, 0x0b, 0x15, 0x84, 0x4b, 0x69, 0x88, 0x8a +}; + +static const unsigned char msg_sha512[] = + { 0x37, 0xd1, 0x35, 0x9d, 0x18, 0x41, 0xe9, 0xb7, + 0x6d, 0x9a, 0x13, 0xda, 0x5f, 0xf3, 0xbd +}; + +static const unsigned char dig_sha512[] = + { 0x11, 0x13, 0xc4, 0x19, 0xed, 0x2b, 0x1d, 0x16, + 0x11, 0xeb, 0x9b, 0xbe, 0xf0, 0x7f, 0xcf, 0x44, + 0x8b, 0xd7, 0x57, 0xbd, 0x8d, 0xa9, 0x25, 0xb0, + 0x47, 0x25, 0xd6, 0x6c, 0x9a, 0x54, 0x7f, 0x8f, + 0x0b, 0x53, 0x1a, 0x10, 0x68, 0x32, 0x03, 0x38, + 0x82, 0xc4, 0x87, 0xc4, 0xea, 0x0e, 0xd1, 0x04, + 0xa9, 0x98, 0xc1, 0x05, 0xa3, 0xf3, 0xf8, 0xb1, + 0xaf, 0xbc, 0xd9, 0x78, 0x7e, 0xee, 0x3d, 0x43 +}; + +int FIPS_selftest_sha2(void) +{ + unsigned char md[SHA512_DIGEST_LENGTH]; + + EVP_Digest(msg_sha256, sizeof(msg_sha256), md, NULL, EVP_sha256(), NULL); + if (memcmp(dig_sha256, md, sizeof(dig_sha256))) { + FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED); + return 0; + } + + EVP_Digest(msg_sha512, sizeof(msg_sha512), md, NULL, EVP_sha512(), NULL); + if (memcmp(dig_sha512, md, sizeof(dig_sha512))) { + FIPSerr(FIPS_F_FIPS_MODE_SET, FIPS_R_SELFTEST_FAILED); + return 0; + } + + return 1; +} + +#endif diff --git a/crypto/fips/fips_standalone_hmac.c b/crypto/fips/fips_standalone_hmac.c new file mode 100644 index 0000000..ffc3411 --- /dev/null +++ b/crypto/fips/fips_standalone_hmac.c @@ -0,0 +1,268 @@ +/* ==================================================================== + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <openssl/opensslconf.h> +#include <openssl/sha.h> +#include <openssl/hmac.h> + +#ifndef FIPSCANISTER_O +int FIPS_selftest_failed() +{ + return 0; +} + +void FIPS_selftest_check() +{ +} +#endif + +#ifdef OPENSSL_FIPS +int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + return 0; +}; + +int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + return 0; +}; + +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) + +unsigned int OPENSSL_ia32cap_P[4]; +unsigned long *OPENSSL_ia32cap_loc(void) +{ + if (sizeof(long) == 4) + /* + * If 32-bit application pulls address of OPENSSL_ia32cap_P[0] + * clear second element to maintain the illusion that vector + * is 32-bit. + */ + OPENSSL_ia32cap_P[1] = 0; + + OPENSSL_ia32cap_P[2] = 0; + + return (unsigned long *)OPENSSL_ia32cap_P; +} + +# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) +# define OPENSSL_CPUID_SETUP +# if defined(_WIN32) +typedef unsigned __int64 IA32CAP; +# else +typedef unsigned long long IA32CAP; +# endif +void OPENSSL_cpuid_setup(void) +{ + static int trigger = 0; + IA32CAP OPENSSL_ia32_cpuid(unsigned int *); + IA32CAP vec; + char *env; + + if (trigger) + return; + + trigger = 1; + if ((env = getenv("OPENSSL_ia32cap"))) { + int off = (env[0] == '~') ? 1 : 0; +# if defined(_WIN32) + if (!sscanf(env + off, "%I64i", &vec)) + vec = strtoul(env + off, NULL, 0); +# else + if (!sscanf(env + off, "%lli", (long long *)&vec)) + vec = strtoul(env + off, NULL, 0); +# endif + if (off) + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec; + else if (env[0] == ':') + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); + + OPENSSL_ia32cap_P[2] = 0; + if ((env = strchr(env, ':'))) { + unsigned int vecx; + env++; + off = (env[0] == '~') ? 1 : 0; + vecx = strtoul(env + off, NULL, 0); + if (off) + OPENSSL_ia32cap_P[2] &= ~vecx; + else + OPENSSL_ia32cap_P[2] = vecx; + } + } else + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); + + /* + * |(1<<10) sets a reserved bit to signal that variable + * was initialized already... This is to avoid interference + * with cpuid snippets in ELF .init segment. + */ + OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); + OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); +} +# else +unsigned int OPENSSL_ia32cap_P[4]; +# endif + +# else +unsigned long *OPENSSL_ia32cap_loc(void) +{ + return NULL; +} +# endif +int OPENSSL_NONPIC_relocated = 0; +# if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) +void OPENSSL_cpuid_setup(void) +{ +} +# endif + +static void hmac_init(SHA256_CTX *md_ctx, SHA256_CTX *o_ctx, const char *key) +{ + size_t len = strlen(key); + int i; + unsigned char keymd[HMAC_MAX_MD_CBLOCK]; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + + if (len > SHA_CBLOCK) { + SHA256_Init(md_ctx); + SHA256_Update(md_ctx, key, len); + SHA256_Final(keymd, md_ctx); + len = SHA256_DIGEST_LENGTH; + } 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]; + SHA256_Init(md_ctx); + SHA256_Update(md_ctx, pad, SHA256_CBLOCK); + + for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) + pad[i] = 0x5c ^ keymd[i]; + SHA256_Init(o_ctx); + SHA256_Update(o_ctx, pad, SHA256_CBLOCK); +} + +static void hmac_final(unsigned char *md, SHA256_CTX *md_ctx, + SHA256_CTX *o_ctx) +{ + unsigned char buf[SHA256_DIGEST_LENGTH]; + + SHA256_Final(buf, md_ctx); + SHA256_Update(o_ctx, buf, sizeof buf); + SHA256_Final(md, o_ctx); +} + +#endif + +int main(int argc, char **argv) +{ +#ifdef OPENSSL_FIPS + static char key[] = "orboDeJITITejsirpADONivirpUkvarP"; + int n, binary = 0; + + if (argc < 2) { + fprintf(stderr, "%s [<file>]+\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"); + SHA256_CTX md_ctx, o_ctx; + unsigned char md[SHA256_DIGEST_LENGTH]; + int i; + + if (!f) { + perror(argv[n]); + exit(2); + } + + hmac_init(&md_ctx, &o_ctx, key); + for (;;) { + char buf[1024]; + size_t l = fread(buf, 1, sizeof buf, f); + + if (l == 0) { + if (ferror(f)) { + perror(argv[n]); + exit(3); + } else + break; + } + SHA256_Update(&md_ctx, buf, l); + } + hmac_final(md, &md_ctx, &o_ctx); + + if (binary) { + fwrite(md, SHA256_DIGEST_LENGTH, 1, stdout); + break; /* ... for single(!) file */ + } + +/* printf("HMAC-SHA1(%s)= ",argv[n]); */ + for (i = 0; i < SHA256_DIGEST_LENGTH; ++i) + printf("%02x", md[i]); + printf("\n"); + } +#endif + return 0; +} diff --git a/crypto/fips/fips_test_suite.c b/crypto/fips/fips_test_suite.c new file mode 100644 index 0000000..1e4b69c --- /dev/null +++ b/crypto/fips/fips_test_suite.c @@ -0,0 +1,639 @@ +/* ==================================================================== + * 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 <stdio.h> +#include <assert.h> +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <openssl/aes.h> +#include <openssl/des.h> +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <openssl/dh.h> +#include <openssl/hmac.h> +#include <openssl/err.h> + +#include <openssl/bn.h> +#include <openssl/rand.h> +#include <openssl/sha.h> + +#ifndef OPENSSL_FIPS +int main(int argc, char *argv[]) +{ + printf("No FIPS support\n"); + return (0); +} +#else + +# include <openssl/fips.h> +# include "fips_utl.h" + +/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext +*/ +static int FIPS_aes_test(void) +{ + int ret = 0; + unsigned char pltmp[16]; + unsigned char citmp[16]; + unsigned char key[16] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + unsigned char plaintext[16] = "etaonrishdlcu"; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 16); + if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 16); + if (memcmp(pltmp, plaintext, 16)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} + +static int FIPS_des3_test(void) +{ + int ret = 0; + unsigned char pltmp[8]; + unsigned char citmp[8]; + unsigned char key[] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24 + }; + unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' }; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 1) <= 0) + goto err; + EVP_Cipher(&ctx, citmp, plaintext, 8); + if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 0) <= 0) + goto err; + EVP_Cipher(&ctx, pltmp, citmp, 8); + if (memcmp(pltmp, plaintext, 8)) + goto err; + ret = 1; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} + +/* + * DSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_dsa_test(int bad) +{ + DSA *dsa = NULL; + EVP_PKEY pk; + unsigned char dgst[] = "etaonrishdlc"; + unsigned char buf[60]; + unsigned int slen; + int r = 0; + EVP_MD_CTX mctx; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + dsa = DSA_new(); + if (!dsa) + goto end; + if (!DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL)) + goto end; + if (!DSA_generate_key(dsa)) + goto end; + if (bad) + BN_add_word(dsa->pub_key, 1); + + pk.type = EVP_PKEY_DSA; + pk.pkey.dsa = dsa; + + if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (dsa) + DSA_free(dsa); + if (r != 1) + return 0; + return 1; +} + +/* + * RSA: generate keys and sign, verify input plaintext. + */ +static int FIPS_rsa_test(int bad) +{ + RSA *key; + unsigned char input_ptext[] = "etaonrishdlc"; + unsigned char buf[256]; + unsigned int slen; + BIGNUM *bn; + EVP_MD_CTX mctx; + EVP_PKEY pk; + int r = 0; + + ERR_clear_error(); + EVP_MD_CTX_init(&mctx); + key = RSA_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024, bn, NULL)) + return 0; + BN_free(bn); + if (bad) + BN_add_word(key->n, 1); + + pk.type = EVP_PKEY_RSA; + pk.pkey.rsa = key; + + if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + if (!EVP_SignFinal(&mctx, buf, &slen, &pk)) + goto end; + + if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL)) + goto end; + if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1)) + goto end; + r = EVP_VerifyFinal(&mctx, buf, slen, &pk); + end: + EVP_MD_CTX_cleanup(&mctx); + if (key) + RSA_free(key); + if (r != 1) + return 0; + return 1; +} + +/* SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha1_test() +{ + unsigned char digest[SHA_DIGEST_LENGTH] = + { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, +0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 }; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha1(), NULL)) + return 0; + if (memcmp(md, digest, sizeof(md))) + return 0; + return 1; +} + +/* SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha256_test() +{ + unsigned char digest[SHA256_DIGEST_LENGTH] = + { 0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, +0x68, 0xc0, 0xea, 0x40, 0x91, + 0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, + 0x50, 0x4f, 0x47, 0x57 + }; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA256_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha256(), NULL)) + return 0; + if (memcmp(md, digest, sizeof(md))) + return 0; + return 1; +} + +/* SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_sha512_test() +{ + unsigned char digest[SHA512_DIGEST_LENGTH] = + { 0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, +0x94, 0x71, 0x64, 0x28, 0xca, + 0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, + 0xd0, 0xe7, 0x0b, 0x94, 0x4a, + 0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, + 0x24, 0xb1, 0xd9, 0x40, 0x22, + 0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, + 0xeb, 0x2d, 0x42, 0x1d, 0xa3 + }; + unsigned char str[] = "etaonrishd"; + + unsigned char md[SHA512_DIGEST_LENGTH]; + + ERR_clear_error(); + if (!EVP_Digest(str, sizeof(str) - 1, md, NULL, EVP_sha512(), NULL)) + return 0; + if (memcmp(md, digest, sizeof(md))) + return 0; + return 1; +} + +/* HMAC-SHA1: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha1_test() +{ + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + { 0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, +0x56, 0x1b, 0x61, 0x2e, 0x70, + 0xb2, 0xfb, 0xec, 0xc6 + }; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC + (EVP_sha1(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out, &outlen)) + return 0; + if (memcmp(out, kaval, outlen)) + return 0; + return 1; +} + +/* HMAC-SHA224: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha224_test() +{ + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + { 0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, +0x1c, 0xb2, 0xf0, 0x20, 0x35, + 0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19 + }; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC + (EVP_sha224(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out, + &outlen)) + return 0; + if (memcmp(out, kaval, outlen)) + return 0; + return 1; +} + +/* HMAC-SHA256: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha256_test() +{ + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + { 0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, +0x02, 0xf5, 0x72, 0x33, 0x87, + 0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, + 0x51, 0xff, 0xda, 0x24, 0xf4 + }; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC + (EVP_sha256(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out, + &outlen)) + return 0; + if (memcmp(out, kaval, outlen)) + return 0; + return 1; +} + +/* HMAC-SHA384: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha384_test() +{ + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + { 0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, +0x26, 0x99, 0xef, 0x3b, 0x10, + 0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, + 0xac, 0xb0, 0x07, 0x39, 0x08, + 0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, + 0xf3, 0xb8, 0x9b, 0x88, 0x1c + }; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC + (EVP_sha384(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out, + &outlen)) + return 0; + if (memcmp(out, kaval, outlen)) + return 0; + return 1; +} + +/* HMAC-SHA512: generate hash of known digest value and compare to known + precomputed correct hash +*/ +static int FIPS_hmac_sha512_test() +{ + unsigned char key[] = "etaonrishd"; + unsigned char iv[] = "Sample text"; + unsigned char kaval[EVP_MAX_MD_SIZE] = + { 0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, +0x77, 0x59, 0x85, 0xa9, 0xe6, + 0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, + 0xad, 0x7e, 0x24, 0xca, 0xb1, + 0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, + 0x6b, 0x61, 0x7f, 0xeb, 0x9c, + 0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, + 0x3d, 0xa6, 0xd9, 0x2a, 0x53 + }; + + unsigned char out[EVP_MAX_MD_SIZE]; + unsigned int outlen; + + ERR_clear_error(); + if (!HMAC + (EVP_sha512(), key, sizeof(key) - 1, iv, sizeof(iv) - 1, out, + &outlen)) + return 0; + if (memcmp(out, kaval, outlen)) + return 0; + return 1; +} + +/* DH: generate shared parameters +*/ +static int dh_test() +{ + DH *dh; + ERR_clear_error(); + dh = FIPS_dh_new(); + if (!dh) + return 0; + if (!DH_generate_parameters_ex(dh, 1024, 2, NULL)) + return 0; + FIPS_dh_free(dh); + return 1; +} + +/* Zeroize +*/ +static int Zeroize() +{ + RSA *key; + BIGNUM *bn; + unsigned char userkey[16] = + { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, +0x83, 0x02, 0xb1, 0x09, 0x68 }; + int i, n; + + key = FIPS_rsa_new(); + bn = BN_new(); + if (!key || !bn) + return 0; + BN_set_word(bn, 65537); + if (!RSA_generate_key_ex(key, 1024, bn, NULL)) + return 0; + BN_free(bn); + + n = BN_num_bytes(key->d); + printf(" Generated %d byte RSA private key\n", n); + printf("\tBN key before overwriting:\n"); + do_bn_print(stdout, key->d); + BN_rand(key->d, n * 8, -1, 0); + printf("\tBN key after overwriting:\n"); + do_bn_print(stdout, key->d); + + printf("\tchar buffer key before overwriting: \n\t\t"); + for (i = 0; i < sizeof(userkey); i++) + printf("%02x", userkey[i]); + printf("\n"); + RAND_bytes(userkey, sizeof userkey); + printf("\tchar buffer key after overwriting: \n\t\t"); + for (i = 0; i < sizeof(userkey); i++) + printf("%02x", userkey[i]); + printf("\n"); + + return 1; +} + +static int Error; +const char *Fail(const char *msg) +{ + do_print_errors(); + Error++; + return msg; +} + +int main(int argc, char **argv) +{ + + int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0; + int bad_rsa = 0, bad_dsa = 0; + int do_rng_stick = 0; + int no_exit = 0; + + printf("\tFIPS-mode test application\n\n"); + + /* Load entropy from external file, if any */ + RAND_load_file(".rnd", 1024); + + if (argv[1]) { + /* Corrupted KAT tests */ + if (!strcmp(argv[1], "aes")) { + FIPS_corrupt_aes(); + printf("AES encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "des")) { + FIPS_corrupt_des(); + printf("DES3-ECB encryption/decryption with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "dsa")) { + FIPS_corrupt_dsa(); + printf + ("DSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsa")) { + FIPS_corrupt_rsa(); + printf + ("RSA key generation and signature validation with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rsakey")) { + printf + ("RSA key generation and signature validation with corrupted key...\n"); + bad_rsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "rsakeygen")) { + do_corrupt_rsa_keygen = 1; + no_exit = 1; + printf + ("RSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "dsakey")) { + printf + ("DSA key generation and signature validation with corrupted key...\n"); + bad_dsa = 1; + no_exit = 1; + } else if (!strcmp(argv[1], "dsakeygen")) { + do_corrupt_dsa_keygen = 1; + no_exit = 1; + printf + ("DSA key generation and signature validation with corrupted keygen...\n"); + } else if (!strcmp(argv[1], "sha1")) { + FIPS_corrupt_sha1(); + printf("SHA-1 hash with corrupted KAT...\n"); + } else if (!strcmp(argv[1], "rng")) { + FIPS_corrupt_rng(); + } else if (!strcmp(argv[1], "rngstick")) { + do_rng_stick = 1; + no_exit = 1; + printf("RNG test with stuck continuous test...\n"); + } else { + printf("Bad argument \"%s\"\n", argv[1]); + exit(1); + } + if (!no_exit) { + if (!FIPS_mode_set(1)) { + do_print_errors(); + printf("Power-up self test failed\n"); + exit(1); + } + printf("Power-up self test successful\n"); + exit(0); + } + } + + /* Non-Approved cryptographic operation + */ + printf("1. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf(dh_test()? "successful\n" : Fail("FAILED!\n")); + + /* Power-up self test + */ + ERR_clear_error(); + printf("2. Automatic power-up self test..."); + if (!FIPS_mode_set(1)) { + do_print_errors(); + printf(Fail("FAILED!\n")); + exit(1); + } + printf("successful\n"); + if (do_corrupt_dsa_keygen) + FIPS_corrupt_dsa_keygen(); + if (do_corrupt_rsa_keygen) + FIPS_corrupt_rsa_keygen(); + if (do_rng_stick) + FIPS_rng_stick(); + + /* AES encryption/decryption + */ + printf("3. AES encryption/decryption..."); + printf(FIPS_aes_test()? "successful\n" : Fail("FAILED!\n")); + + /* RSA key generation and encryption/decryption + */ + printf("4. RSA key generation and encryption/decryption..."); + printf(FIPS_rsa_test(bad_rsa) ? "successful\n" : Fail("FAILED!\n")); + + /* DES-CBC encryption/decryption + */ + printf("5. DES-ECB encryption/decryption..."); + printf(FIPS_des3_test()? "successful\n" : Fail("FAILED!\n")); + + /* DSA key generation and signature validation + */ + printf("6. DSA key generation and signature validation..."); + printf(FIPS_dsa_test(bad_dsa) ? "successful\n" : Fail("FAILED!\n")); + + /* SHA-1 hash + */ + printf("7a. SHA-1 hash..."); + printf(FIPS_sha1_test()? "successful\n" : Fail("FAILED!\n")); + + /* SHA-256 hash + */ + printf("7b. SHA-256 hash..."); + printf(FIPS_sha256_test()? "successful\n" : Fail("FAILED!\n")); + + /* SHA-512 hash + */ + printf("7c. SHA-512 hash..."); + printf(FIPS_sha512_test()? "successful\n" : Fail("FAILED!\n")); + + /* HMAC-SHA-1 hash + */ + printf("7d. HMAC-SHA-1 hash..."); + printf(FIPS_hmac_sha1_test()? "successful\n" : Fail("FAILED!\n")); + + /* HMAC-SHA-224 hash + */ + printf("7e. HMAC-SHA-224 hash..."); + printf(FIPS_hmac_sha224_test()? "successful\n" : Fail("FAILED!\n")); + + /* HMAC-SHA-256 hash + */ + printf("7f. HMAC-SHA-256 hash..."); + printf(FIPS_hmac_sha256_test()? "successful\n" : Fail("FAILED!\n")); + + /* HMAC-SHA-384 hash + */ + printf("7g. HMAC-SHA-384 hash..."); + printf(FIPS_hmac_sha384_test()? "successful\n" : Fail("FAILED!\n")); + + /* HMAC-SHA-512 hash + */ + printf("7h. HMAC-SHA-512 hash..."); + printf(FIPS_hmac_sha512_test()? "successful\n" : Fail("FAILED!\n")); + + /* Non-Approved cryptographic operation + */ + printf("8. Non-Approved cryptographic operation test...\n"); + printf("\ta. Included algorithm (D-H)..."); + printf(dh_test()? "successful as expected\n" + : Fail("failed INCORRECTLY!\n")); + + /* Zeroization + */ + printf("9. Zero-ization...\n"); + printf(Zeroize()? "\tsuccessful as expected\n" + : Fail("\tfailed INCORRECTLY!\n")); + + printf("\nAll tests completed with %d errors\n", Error); + return Error ? 1 : 0; +} + +#endif diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c index 51a0a3e..cca5d78 100644 --- a/crypto/hmac/hmac.c +++ b/crypto/hmac/hmac.c @@ -89,12 +89,6 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS); return 0; } - /* - * Other algorithm blocking will be done in FIPS_cmac_init, via - * FIPS_hmac_init_ex(). - */ - if (!impl && !ctx->i_ctx.engine) - return FIPS_hmac_init_ex(ctx, key, len, md, NULL); } #endif /* If we are changing MD then we must have a key */ @@ -111,6 +105,13 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, } if (key != NULL) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS) + && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW) + || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))) + goto err; +#endif reset = 1; j = EVP_MD_block_size(md); OPENSSL_assert(j <= (int)sizeof(ctx->key)); @@ -164,10 +165,6 @@ int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) - return FIPS_hmac_update(ctx, data, len); -#endif if (!ctx->md) return 0; @@ -178,10 +175,6 @@ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { unsigned int i; unsigned char buf[EVP_MAX_MD_SIZE]; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) - return FIPS_hmac_final(ctx, md, len); -#endif if (!ctx->md) goto err; @@ -225,12 +218,6 @@ int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) void HMAC_CTX_cleanup(HMAC_CTX *ctx) { -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) { - FIPS_hmac_ctx_cleanup(ctx); - return; - } -#endif EVP_MD_CTX_cleanup(&ctx->i_ctx); EVP_MD_CTX_cleanup(&ctx->o_ctx); EVP_MD_CTX_cleanup(&ctx->md_ctx); diff --git a/crypto/md2/md2_dgst.c b/crypto/md2/md2_dgst.c index 9cd79f8..7a49951 100644 --- a/crypto/md2/md2_dgst.c +++ b/crypto/md2/md2_dgst.c @@ -62,6 +62,11 @@ #include <openssl/md2.h> #include <openssl/opensslv.h> #include <openssl/crypto.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif + +#include <openssl/err.h> const char MD2_version[] = "MD2" OPENSSL_VERSION_PTEXT; @@ -119,7 +124,7 @@ const char *MD2_options(void) return ("md2(int)"); } -fips_md_init(MD2) +nonfips_md_init(MD2) { c->num = 0; memset(c->state, 0, sizeof c->state); diff --git a/crypto/md4/md4_dgst.c b/crypto/md4/md4_dgst.c index 614fca0..d14f01f 100644 --- a/crypto/md4/md4_dgst.c +++ b/crypto/md4/md4_dgst.c @@ -72,7 +72,7 @@ const char MD4_version[] = "MD4" OPENSSL_VERSION_PTEXT; #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -fips_md_init(MD4) +nonfips_md_init(MD4) { memset(c, 0, sizeof(*c)); c->A = INIT_DATA_A; diff --git a/crypto/md5/md5_dgst.c b/crypto/md5/md5_dgst.c index 2b51946..0a28b9b 100644 --- a/crypto/md5/md5_dgst.c +++ b/crypto/md5/md5_dgst.c @@ -72,7 +72,7 @@ const char MD5_version[] = "MD5" OPENSSL_VERSION_PTEXT; #define INIT_DATA_C (unsigned long)0x98badcfeL #define INIT_DATA_D (unsigned long)0x10325476L -fips_md_init(MD5) +nonfips_md_init(MD5) { memset(c, 0, sizeof(*c)); c->A = INIT_DATA_A; diff --git a/crypto/mdc2/mdc2dgst.c b/crypto/mdc2/mdc2dgst.c index 6615cf8..f4dd0ad 100644 --- a/crypto/mdc2/mdc2dgst.c +++ b/crypto/mdc2/mdc2dgst.c @@ -76,7 +76,7 @@ *((c)++)=(unsigned char)(((l)>>24L)&0xff)) static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); -fips_md_init(MDC2) +nonfips_md_init(MDC2) { c->num = 0; c->pad_type = 1; diff --git a/crypto/o_fips.c b/crypto/o_fips.c index f56d5bb..0abd233 100644 --- a/crypto/o_fips.c +++ b/crypto/o_fips.c @@ -80,6 +80,8 @@ int FIPS_mode_set(int r) # ifndef FIPS_AUTH_USER_PASS # define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password" # endif + if (r && FIPS_module_mode()) /* can be implicitly initialized by OPENSSL_init() */ + return 1; if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS)) return 0; if (r) diff --git a/crypto/o_init.c b/crypto/o_init.c index 2088388..2f754ef 100644 --- a/crypto/o_init.c +++ b/crypto/o_init.c @@ -56,8 +56,37 @@ #include <e_os.h> #include <openssl/err.h> #ifdef OPENSSL_FIPS +# include <sys/types.h> +# include <sys/stat.h> +# include <fcntl.h> +# include <unistd.h> +# include <errno.h> +# include <stdlib.h> # include <openssl/fips.h> # include <openssl/rand.h> + +# define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled" + +static void init_fips_mode(void) +{ + char buf[2] = "0"; + int fd; + + if (getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) { + buf[0] = '1'; + } else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) { + while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR) ; + close(fd); + } + /* Failure reading the fips mode switch file means just not + * switching into FIPS mode. We would break too many things + * otherwise.. + */ + + if (buf[0] == '1') { + FIPS_mode_set(1); + } +} #endif /* @@ -65,19 +94,26 @@ * sets FIPS callbacks */ -void OPENSSL_init(void) +void OPENSSL_init_library(void) { static int done = 0; if (done) return; done = 1; #ifdef OPENSSL_FIPS - FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); - FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); - FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); RAND_init_fips(); + init_fips_mode(); + if (!FIPS_mode()) { + /* Clean up prematurely set default rand method */ + RAND_set_rand_method(NULL); + } #endif #if 0 fprintf(stderr, "Called OPENSSL_init\n"); #endif } + +void OPENSSL_init(void) +{ + OPENSSL_init_library(); +} diff --git a/crypto/opensslconf.h.in b/crypto/opensslconf.h.in index 7a1c85d..e86ec45 100644 --- a/crypto/opensslconf.h.in +++ b/crypto/opensslconf.h.in @@ -1,5 +1,20 @@ /* crypto/opensslconf.h.in */ +#ifdef OPENSSL_DOING_MAKEDEPEND + +/* Include any symbols here that have to be explicitly set to enable a feature + * that should be visible to makedepend. + * + * [Our "make depend" doesn't actually look at this, we use actual build settings + * instead; we want to make it easy to remove subdirectories with disabled algorithms.] + */ + +#ifndef OPENSSL_FIPS +#define OPENSSL_FIPS +#endif + +#endif + /* Generate 80386 code? */ #undef I386_ONLY diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index 5c13d57..05c982d 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -391,7 +391,10 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); crypto_lock_rand = 1; - if (!initialized) { + /* always poll for external entropy in FIPS mode, drbg provides the + * expansion + */ + if (!initialized || FIPS_module_mode()) { RAND_poll(); initialized = 1; } diff --git a/crypto/rand/rand.h b/crypto/rand/rand.h index 2553afd..09dc4cc 100644 --- a/crypto/rand/rand.h +++ b/crypto/rand/rand.h @@ -133,16 +133,34 @@ void ERR_load_RAND_strings(void); /* Error codes for the RAND functions. */ /* Function codes. */ +# define RAND_F_ENG_RAND_GET_RAND_METHOD 108 +# define RAND_F_FIPS_RAND 103 +# define RAND_F_FIPS_RAND_BYTES 102 +# define RAND_F_FIPS_RAND_SET_DT 106 +# define RAND_F_FIPS_X931_SET_DT 106 +# define RAND_F_FIPS_SET_DT 104 +# define RAND_F_FIPS_SET_PRNG_SEED 107 +# define RAND_F_FIPS_SET_TEST_MODE 105 # define RAND_F_RAND_GET_RAND_METHOD 101 -# define RAND_F_RAND_INIT_FIPS 102 +# define RAND_F_RAND_INIT_FIPS 109 # define RAND_F_SSLEAY_RAND_BYTES 100 /* Reason codes. */ -# define RAND_R_DUAL_EC_DRBG_DISABLED 104 -# define RAND_R_ERROR_INITIALISING_DRBG 102 -# define RAND_R_ERROR_INSTANTIATING_DRBG 103 -# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +# define RAND_R_DUAL_EC_DRBG_DISABLED 114 +# define RAND_R_ERROR_INITIALISING_DRBG 112 +# define RAND_R_ERROR_INSTANTIATING_DRBG 113 +# define RAND_R_NON_FIPS_METHOD 105 +# define RAND_R_NOT_IN_TEST_MODE 106 +# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 111 +# define RAND_R_NO_KEY_SET 107 +# define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101 +# define RAND_R_PRNG_ERROR 108 +# define RAND_R_PRNG_KEYED 109 +# define RAND_R_PRNG_NOT_REKEYED 102 +# define RAND_R_PRNG_NOT_RESEEDED 103 # define RAND_R_PRNG_NOT_SEEDED 100 +# define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110 +# define RAND_R_PRNG_STUCK 104 #ifdef __cplusplus } diff --git a/crypto/ripemd/rmd_dgst.c b/crypto/ripemd/rmd_dgst.c index 4ddd939..2d21dd7 100644 --- a/crypto/ripemd/rmd_dgst.c +++ b/crypto/ripemd/rmd_dgst.c @@ -70,7 +70,7 @@ void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p, size_t num); void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num); #endif -fips_md_init(RIPEMD160) +nonfips_md_init(RIPEMD160) { memset(c, 0, sizeof(*c)); c->A = RIPEMD160_A; diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h index d2ee374..d2e93dd 100644 --- a/crypto/rsa/rsa.h +++ b/crypto/rsa/rsa.h @@ -168,6 +168,8 @@ struct rsa_st { # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 # endif +# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + # ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 # endif @@ -329,6 +331,13 @@ RSA *RSA_generate_key(int bits, unsigned long e, void /* New version */ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, + BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2, + const BIGNUM *Xp, const BIGNUM *Xq1, + const BIGNUM *Xq2, const BIGNUM *Xq, + const BIGNUM *e, BN_GENCB *cb); +int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, + BN_GENCB *cb); int RSA_check_key(const RSA *); /* next 4 return -1 on error */ @@ -538,7 +547,7 @@ void ERR_load_RSA_strings(void); # define RSA_F_RSA_ALGOR_TO_MD 157 # define RSA_F_RSA_BUILTIN_KEYGEN 129 # define RSA_F_RSA_CHECK_KEY 123 -# define RSA_F_RSA_CMS_DECRYPT 158 +# define RSA_F_RSA_CMS_DECRYPT 258 # define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 # define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 # define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 @@ -559,7 +568,7 @@ void ERR_load_RSA_strings(void); # define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 # define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 160 # define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 -# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 158 # define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 # define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 # define RSA_F_RSA_PADDING_ADD_SSLV23 110 @@ -573,21 +582,23 @@ void ERR_load_RSA_strings(void); # define RSA_F_RSA_PADDING_CHECK_X931 128 # define RSA_F_RSA_PRINT 115 # define RSA_F_RSA_PRINT_FP 116 -# define RSA_F_RSA_PRIVATE_DECRYPT 150 -# define RSA_F_RSA_PRIVATE_ENCRYPT 151 +# define RSA_F_RSA_PRIVATE_DECRYPT 157 +# define RSA_F_RSA_PRIVATE_ENCRYPT 148 # define RSA_F_RSA_PRIV_DECODE 137 # define RSA_F_RSA_PRIV_ENCODE 138 # define RSA_F_RSA_PSS_TO_CTX 162 -# define RSA_F_RSA_PUBLIC_DECRYPT 152 +# define RSA_F_RSA_PUBLIC_DECRYPT 149 # define RSA_F_RSA_PUBLIC_ENCRYPT 153 # define RSA_F_RSA_PUB_DECODE 139 # define RSA_F_RSA_SETUP_BLINDING 136 +# define RSA_F_RSA_SET_DEFAULT_METHOD 150 +# define RSA_F_RSA_SET_METHOD 151 # define RSA_F_RSA_SIGN 117 # define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 # define RSA_F_RSA_VERIFY 119 # define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 # define RSA_F_RSA_VERIFY_PKCS1_PSS 126 -# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 +# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 152 /* Reason codes. */ # define RSA_R_ALGORITHM_MISMATCH 100 @@ -620,21 +631,22 @@ void ERR_load_RSA_strings(void); # define RSA_R_INVALID_OAEP_PARAMETERS 162 # define RSA_R_INVALID_PADDING 138 # define RSA_R_INVALID_PADDING_MODE 141 -# define RSA_R_INVALID_PSS_PARAMETERS 149 +# define RSA_R_INVALID_PSS_PARAMETERS 157 # define RSA_R_INVALID_PSS_SALTLEN 146 -# define RSA_R_INVALID_SALT_LENGTH 150 +# define RSA_R_INVALID_SALT_LENGTH 158 # define RSA_R_INVALID_TRAILER 139 # define RSA_R_INVALID_X931_DIGEST 142 # define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 # define RSA_R_KEY_SIZE_TOO_SMALL 120 # define RSA_R_LAST_OCTET_INVALID 134 # define RSA_R_MODULUS_TOO_LARGE 105 -# define RSA_R_NON_FIPS_RSA_METHOD 157 +# define RSA_R_NON_FIPS_RSA_METHOD 149 +# define RSA_R_NON_FIPS_METHOD 149 # define RSA_R_NO_PUBLIC_EXPONENT 140 # define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 # define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 # define RSA_R_OAEP_DECODING_ERROR 121 -# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 +# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 150 # define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 # define RSA_R_PADDING_CHECK_FAILED 114 # define RSA_R_PKCS_DECODING_ERROR 159 diff --git a/crypto/rsa/rsa_crpt.c b/crypto/rsa/rsa_crpt.c index 5c416b5..81e00d9 100644 --- a/crypto/rsa/rsa_crpt.c +++ b/crypto/rsa/rsa_crpt.c @@ -89,9 +89,9 @@ int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { #ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); + if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, + RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif @@ -115,9 +115,9 @@ int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { #ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); + if (FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, + RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c index b147fff..2de7afc 100644 --- a/crypto/rsa/rsa_eay.c +++ b/crypto/rsa/rsa_eay.c @@ -114,6 +114,10 @@ #include <openssl/bn.h> #include <openssl/rsa.h> #include <openssl/rand.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif #ifndef RSA_NULL @@ -140,7 +144,7 @@ static RSA_METHOD rsa_pkcs1_eay_meth = { * if e == 3 */ RSA_eay_init, RSA_eay_finish, - 0, /* flags */ + RSA_FLAG_FIPS_METHOD, /* flags */ NULL, 0, /* rsa_sign */ 0, /* rsa_verify */ @@ -160,6 +164,22 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *buf = NULL; BN_CTX *ctx = NULL; +# ifdef OPENSSL_FIPS + if (FIPS_mode()) { + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT, + FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +# endif + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; @@ -361,6 +381,22 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; +# ifdef OPENSSL_FIPS + if (FIPS_mode()) { + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT, + FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +# endif + if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); @@ -497,6 +533,22 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; +# ifdef OPENSSL_FIPS + if (FIPS_mode()) { + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT, + FIPS_R_FIPS_SELFTEST_FAILED); + return -1; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +# endif + if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); @@ -623,6 +675,22 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, unsigned char *buf = NULL; BN_CTX *ctx = NULL; +# ifdef OPENSSL_FIPS + if (FIPS_mode()) { + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT, + FIPS_R_FIPS_SELFTEST_FAILED); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + } +# endif + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; @@ -886,6 +954,9 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) static int RSA_eay_init(RSA *rsa) { +# ifdef OPENSSL_FIPS + FIPS_selftest_check(); +# endif rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE; return (1); } diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c index 0bab05e..9557e1d 100644 --- a/crypto/rsa/rsa_err.c +++ b/crypto/rsa/rsa_err.c @@ -136,6 +136,8 @@ static ERR_STRING_DATA RSA_str_functs[] = { {ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"}, {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, + {ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD), "RSA_set_default_method"}, + {ERR_FUNC(RSA_F_RSA_SET_METHOD), "RSA_set_method"}, {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), "RSA_sign_ASN1_OCTET_STRING"}, diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c index 7f7dca3..c6c0a75 100644 --- a/crypto/rsa/rsa_gen.c +++ b/crypto/rsa/rsa_gen.c @@ -69,8 +69,80 @@ #include <openssl/rsa.h> #ifdef OPENSSL_FIPS # include <openssl/fips.h> -extern int FIPS_rsa_x931_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, - BN_GENCB *cb); +# include <openssl/err.h> +# include <openssl/evp.h> + +static int fips_rsa_pairwise_fail = 0; + +void FIPS_corrupt_rsa_keygen(void) +{ + fips_rsa_pairwise_fail = 1; +} + +int fips_check_rsa(RSA *rsa) +{ + const unsigned char tbs[] = "RSA Pairwise Check Data"; + unsigned char *ctbuf = NULL, *ptbuf = NULL; + int len, ret = 0; + EVP_PKEY *pk; + + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + + EVP_PKEY_set1_RSA(pk, rsa); + + /* Perform pairwise consistency signature test */ + if (!fips_pkey_signature_test(pk, tbs, -1, + NULL, 0, EVP_sha1(), + EVP_MD_CTX_FLAG_PAD_PKCS1, NULL) + || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(), + EVP_MD_CTX_FLAG_PAD_X931, NULL) + || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(), + EVP_MD_CTX_FLAG_PAD_PSS, NULL)) + goto err; + /* Now perform pairwise consistency encrypt/decrypt test */ + ctbuf = OPENSSL_malloc(RSA_size(rsa)); + if (!ctbuf) + goto err; + + len = + RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, + RSA_PKCS1_PADDING); + if (len <= 0) + goto err; + /* Check ciphertext doesn't match plaintext */ + if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len)) + goto err; + ptbuf = OPENSSL_malloc(RSA_size(rsa)); + + if (!ptbuf) + goto err; + len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); + if (len != (sizeof(tbs) - 1)) + goto err; + if (memcmp(ptbuf, tbs, len)) + goto err; + + ret = 1; + + if (!ptbuf) + goto err; + + err: + if (ret == 0) { + fips_set_selftest_fail(); + FIPSerr(FIPS_F_FIPS_CHECK_RSA, FIPS_R_PAIRWISE_TEST_FAILED); + } + + if (ctbuf) + OPENSSL_free(ctbuf); + if (ptbuf) + OPENSSL_free(ptbuf); + if (pk) + EVP_PKEY_free(pk); + + return ret; +} #endif static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, @@ -86,7 +158,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { #ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + if (FIPS_module_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD); return 0; @@ -94,10 +166,6 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) #endif if (rsa->meth->rsa_keygen) return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_rsa_x931_generate_key_ex(rsa, bits, e_value, cb); -#endif return rsa_builtin_keygen(rsa, bits, e_value, cb); } @@ -110,6 +178,20 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, int bitsp, bitsq, ok = -1, n = 0; BN_CTX *ctx = NULL; +#ifdef OPENSSL_FIPS + if (FIPS_module_mode()) { + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_FIPS_SELFTEST_FAILED); + return 0; + } + + if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_KEY_TOO_SHORT); + return 0; + } + } +#endif + ctx = BN_CTX_new(); if (ctx == NULL) goto err; @@ -235,6 +317,16 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) goto err; +#ifdef OPENSSL_FIPS + if (FIPS_module_mode()) { + if (fips_rsa_pairwise_fail) + BN_add_word(rsa->n, 1); + + if (!fips_check_rsa(rsa)) + goto err; + } +#endif + ok = 1; err: if (ok == -1) { diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index a6805de..fe7b520 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -84,23 +84,22 @@ RSA *RSA_new(void) void RSA_set_default_method(const RSA_METHOD *meth) { +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) { + RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD); + return; + } +#endif default_RSA_meth = meth; } const RSA_METHOD *RSA_get_default_method(void) { if (default_RSA_meth == NULL) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_rsa_pkcs1_ssleay(); - else - return RSA_PKCS1_SSLeay(); -#else -# ifdef RSA_NULL +#ifdef RSA_NULL default_RSA_meth = RSA_null_method(); -# else +#else default_RSA_meth = RSA_PKCS1_SSLeay(); -# endif #endif } @@ -119,6 +118,12 @@ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) * to deal with which ENGINE it comes from. */ const RSA_METHOD *mtmp; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD)) { + RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_METHOD); + return 0; + } +#endif mtmp = rsa->meth; if (mtmp->finish) mtmp->finish(rsa); @@ -165,6 +170,17 @@ RSA *RSA_new_method(ENGINE *engine) } } #endif +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD)) { + RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD); +# ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +# endif + OPENSSL_free(ret); + return NULL; + } +#endif ret->pad = 0; ret->version = 0; @@ -183,7 +199,7 @@ RSA *RSA_new_method(ENGINE *engine) ret->blinding = NULL; ret->mt_blinding = NULL; ret->bignum_data = NULL; - ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + ret->flags = ret->meth->flags; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { #ifndef OPENSSL_NO_ENGINE if (ret->engine) diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c index 2036355..3deba38 100644 --- a/crypto/rsa/rsa_pmeth.c +++ b/crypto/rsa/rsa_pmeth.c @@ -228,20 +228,6 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); return -1; } -#ifdef OPENSSL_FIPS - if (ret > 0) { - unsigned int slen; - ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, &slen); - if (ret > 0) - *siglen = slen; - else - *siglen = 0; - return ret; - } -#endif if (EVP_MD_type(rctx->md) == NID_mdc2) { unsigned int sltmp; @@ -359,17 +345,6 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, } #endif if (rctx->md) { -#ifdef OPENSSL_FIPS - if (rv > 0) { - return FIPS_rsa_verify_digest(rsa, - tbs, tbslen, - rctx->md, - rctx->pad_mode, - rctx->saltlen, - rctx->mgf1md, sig, siglen); - - } -#endif if (rctx->pad_mode == RSA_PKCS1_PADDING) return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index 82ca832..a77e7d3 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -132,7 +132,10 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, i2d_X509_SIG(&sig, &p); s = tmps; } - i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); + /* NB: call underlying method directly to avoid FIPS blocking */ + i = rsa->meth->rsa_priv_enc ? rsa->meth->rsa_priv_enc(i, s, sigret, rsa, + RSA_PKCS1_PADDING) : + 0; if (i <= 0) ret = 0; else @@ -188,8 +191,10 @@ int int_rsa_verify(int dtype, const unsigned char *m, } if ((dtype == NID_md5_sha1) && rm) { - i = RSA_public_decrypt((int)siglen, - sigbuf, rm, rsa, RSA_PKCS1_PADDING); + i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen, + sigbuf, rm, rsa, + RSA_PKCS1_PADDING) + : 0; if (i <= 0) return 0; *prm_len = i; @@ -205,7 +210,11 @@ int int_rsa_verify(int dtype, const unsigned char *m, RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); goto err; } - i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); + /* NB: call underlying method directly to avoid FIPS blocking */ + i = rsa->meth->rsa_pub_dec ? rsa->meth->rsa_pub_dec((int)siglen, sigbuf, + s, rsa, + RSA_PKCS1_PADDING) : + 0; if (i <= 0) goto err; diff --git a/crypto/sha/sha.h b/crypto/sha/sha.h index e5169e4..ccec037 100644 --- a/crypto/sha/sha.h +++ b/crypto/sha/sha.h @@ -105,9 +105,6 @@ typedef struct SHAstate_st { } SHA_CTX; # ifndef OPENSSL_NO_SHA0 -# ifdef OPENSSL_FIPS -int private_SHA_Init(SHA_CTX *c); -# endif int SHA_Init(SHA_CTX *c); int SHA_Update(SHA_CTX *c, const void *data, size_t len); int SHA_Final(unsigned char *md, SHA_CTX *c); @@ -115,9 +112,6 @@ unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md); void SHA_Transform(SHA_CTX *c, const unsigned char *data); # endif # ifndef OPENSSL_NO_SHA1 -# ifdef OPENSSL_FIPS -int private_SHA1_Init(SHA_CTX *c); -# endif int SHA1_Init(SHA_CTX *c); int SHA1_Update(SHA_CTX *c, const void *data, size_t len); int SHA1_Final(unsigned char *md, SHA_CTX *c); @@ -139,10 +133,6 @@ typedef struct SHA256state_st { } SHA256_CTX; # ifndef OPENSSL_NO_SHA256 -# ifdef OPENSSL_FIPS -int private_SHA224_Init(SHA256_CTX *c); -int private_SHA256_Init(SHA256_CTX *c); -# endif int SHA224_Init(SHA256_CTX *c); int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); int SHA224_Final(unsigned char *md, SHA256_CTX *c); @@ -192,10 +182,6 @@ typedef struct SHA512state_st { # endif # ifndef OPENSSL_NO_SHA512 -# ifdef OPENSSL_FIPS -int private_SHA384_Init(SHA512_CTX *c); -int private_SHA512_Init(SHA512_CTX *c); -# endif int SHA384_Init(SHA512_CTX *c); int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); int SHA384_Final(unsigned char *md, SHA512_CTX *c); diff --git a/crypto/sha/sha256.c b/crypto/sha/sha256.c index 72a1159..a6cf450 100644 --- a/crypto/sha/sha256.c +++ b/crypto/sha/sha256.c @@ -12,12 +12,19 @@ # include <openssl/crypto.h> # include <openssl/sha.h> +# ifdef OPENSSL_FIPS +# include <openssl/fips.h> +# endif + # include <openssl/opensslv.h> const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT; fips_md_init_ctx(SHA224, SHA256) { +# ifdef OPENSSL_FIPS + FIPS_selftest_check(); +# endif memset(c, 0, sizeof(*c)); c->h[0] = 0xc1059ed8UL; c->h[1] = 0x367cd507UL; @@ -33,6 +40,9 @@ fips_md_init_ctx(SHA224, SHA256) fips_md_init(SHA256) { +# ifdef OPENSSL_FIPS + FIPS_selftest_check(); +# endif memset(c, 0, sizeof(*c)); c->h[0] = 0x6a09e667UL; c->h[1] = 0xbb67ae85UL; diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c index 3bf66ae..f6e7c99 100644 --- a/crypto/sha/sha512.c +++ b/crypto/sha/sha512.c @@ -5,6 +5,10 @@ * ==================================================================== */ #include <openssl/opensslconf.h> +#ifdef OPENSSL_FIPS +# include <openssl/fips.h> +#endif + #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) /*- * IMPLEMENTATION NOTES. @@ -62,6 +66,9 @@ const char SHA512_version[] = "SHA-512" OPENSSL_VERSION_PTEXT; fips_md_init_ctx(SHA384, SHA512) { +# ifdef OPENSSL_FIPS + FIPS_selftest_check(); +# endif c->h[0] = U64(0xcbbb9d5dc1059ed8); c->h[1] = U64(0x629a292a367cd507); c->h[2] = U64(0x9159015a3070dd17); @@ -80,6 +87,9 @@ fips_md_init_ctx(SHA384, SHA512) fips_md_init(SHA512) { +# ifdef OPENSSL_FIPS + FIPS_selftest_check(); +# endif c->h[0] = U64(0x6a09e667f3bcc908); c->h[1] = U64(0xbb67ae8584caa73b); c->h[2] = U64(0x3c6ef372fe94f82b); diff --git a/crypto/sha/sha_locl.h b/crypto/sha/sha_locl.h index 03bd411..84ce5ca 100644 --- a/crypto/sha/sha_locl.h +++ b/crypto/sha/sha_locl.h @@ -123,11 +123,14 @@ void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num); #define INIT_DATA_h4 0xc3d2e1f0UL #ifdef SHA_0 -fips_md_init(SHA) +nonfips_md_init(SHA) #else fips_md_init_ctx(SHA1, SHA) #endif { +#if defined(SHA_1) && defined(OPENSSL_FIPS) + FIPS_selftest_check(); +#endif memset(c, 0, sizeof(*c)); c->h0 = INIT_DATA_h0; c->h1 = INIT_DATA_h1; diff --git a/crypto/whrlpool/wp_dgst.c b/crypto/whrlpool/wp_dgst.c index e33bb4f..050b281 100644 --- a/crypto/whrlpool/wp_dgst.c +++ b/crypto/whrlpool/wp_dgst.c @@ -55,7 +55,7 @@ #include <openssl/crypto.h> #include <string.h> -fips_md_init(WHIRLPOOL) +nonfips_md_init(WHIRLPOOL) { memset(c, 0, sizeof(*c)); return (1); diff --git a/ssl/ssl_algs.c b/ssl/ssl_algs.c index e6f515f..34c0ab9 100644 --- a/ssl/ssl_algs.c +++ b/ssl/ssl_algs.c @@ -64,6 +64,11 @@ int SSL_library_init(void) { +#ifdef OPENSSL_FIPS + OPENSSL_init_library(); + if (!FIPS_mode()) { +#endif + #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); @@ -142,6 +147,48 @@ int SSL_library_init(void) EVP_add_digest(EVP_sha()); EVP_add_digest(EVP_dss()); #endif +#ifdef OPENSSL_FIPS + } else { +# ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_ede3_cbc()); +# endif +# ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_256_gcm()); +# endif +# ifndef OPENSSL_NO_MD5 + /* needed even in the FIPS mode for TLS MAC */ + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); +# endif +# ifndef OPENSSL_NO_SHA + EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); +# endif +# ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +# endif +# ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +# endif +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) + EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); +# endif +# ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +# endif + } +#endif #ifndef OPENSSL_NO_COMP /* * This will initialise the built-in compression algorithms. The value
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor