From 76938e3042d8086c4f4acec0d3a53ab6e32b2864 Mon Sep 17 00:00:00 2001 From: James Antill Date: Mon, 27 Feb 2023 14:25:10 -0500 Subject: [PATCH] Import rpm: c8s --- .gitignore | 2 + Makefile.certificate | 82 + README.FIPS | 75 + ec_curve.c | 455 + ectest.c | 994 ++ hobble-openssl | 47 + make-dummy-cert | 28 + ...l-drop-unneeded-reference-to-dlfcn-h.patch | 10 + mingw-openssl-fix-fips-build-failure.patch | 97 + mingw-openssl.spec | 749 + mingw32-openssl-1.0.0-beta3-libversion.patch | 50 + mingw32-openssl-1.0.2a-sfx.patch | 14 + openssl-1.0.0-beta4-ca-dir.patch | 36 + openssl-1.0.0-timezone.patch | 21 + openssl-1.0.1c-aliasing.patch | 12 + openssl-1.0.1c-perlfind.patch | 16 + openssl-1.0.1i-algo-doc.patch | 77 + openssl-1.0.2a-apps-dgst.patch | 110 + openssl-1.0.2a-compat-symbols.patch | 46 + openssl-1.0.2a-defaults.patch | 60 + openssl-1.0.2a-dtls1-abi.patch | 23 + openssl-1.0.2a-env-zlib.patch | 39 + openssl-1.0.2a-fips-md5-allow.patch | 21 + openssl-1.0.2a-issuer-hash.patch | 11 + openssl-1.0.2a-no-rpath.patch | 12 + openssl-1.0.2a-padlock64.patch | 198 + openssl-1.0.2a-readme-warning.patch | 50 + openssl-1.0.2a-test-use-localhost.patch | 21 + openssl-1.0.2a-version-add-engines.patch | 47 + openssl-1.0.2a-x509.patch | 28 + openssl-1.0.2c-default-paths.patch | 63 + openssl-1.0.2c-ecc-suiteb.patch | 195 + openssl-1.0.2d-secp256k1.patch | 82 + openssl-1.0.2e-remove-nistp224.patch | 15 + openssl-1.0.2e-rpmbuild.patch | 115 + openssl-1.0.2e-speed-doc.patch | 58 + openssl-1.0.2e-wrap-pad.patch | 541 + openssl-1.0.2g-manfix.patch | 90 + openssl-1.0.2h-pkgconfig.patch | 24 + openssl-1.0.2i-chil-fixes.patch | 15 + openssl-1.0.2i-enc-fail.patch | 25 + openssl-1.0.2i-enginesdir.patch | 83 + openssl-1.0.2i-fips.patch | 13703 ++++++++++++++++ openssl-1.0.2i-trusted-first-doc.patch | 286 + openssl-1.0.2j-deprecate-algos.patch | 229 + openssl-1.0.2j-downgrade-strength.patch | 138 + openssl-1.0.2j-krb5keytab.patch | 172 + openssl-1.0.2k-backports.patch | 244 + openssl-1.0.2k-cc-reqs.patch | 27 + openssl-1.0.2k-cve-2017-3735.patch | 20 + openssl-1.0.2k-cve-2017-3736.patch | 43 + openssl-1.0.2k-cve-2017-3737.patch | 232 + openssl-1.0.2k-cve-2017-3738.patch | 80 + openssl-1.0.2k-cve-2018-0495.patch | 905 + openssl-1.0.2k-cve-2018-0732.patch | 24 + openssl-1.0.2k-cve-2018-0737.patch | 96 + openssl-1.0.2k-cve-2018-0739.patch | 217 + openssl-1.0.2k-long-hello.patch | 36 + openssl-1.0.2k-name-sensitive.patch | 57 + openssl-1.0.2k-no-ssl2.patch | 217 + openssl-1.0.2k-ppc-update.patch | 1932 +++ openssl-1.0.2k-req-x509.patch | 30 + openssl-1.0.2k-s390x-update.patch | 1368 ++ openssl-dont-include-winsock-h.patch | 11 + openssl-mingw64-dont-use-secure-getenv.patch | 26 + openssl-thread-test.c | 400 + openssl_mingw64_install_fix.patch | 11 + opensslconf-new-warning.h | 7 + opensslconf-new.h | 47 + renew-dummy-cert | 42 + sources | 1 + 71 files changed, 25338 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile.certificate create mode 100644 README.FIPS create mode 100644 ec_curve.c create mode 100644 ectest.c create mode 100755 hobble-openssl create mode 100755 make-dummy-cert create mode 100644 mingw-openssl-drop-unneeded-reference-to-dlfcn-h.patch create mode 100644 mingw-openssl-fix-fips-build-failure.patch create mode 100644 mingw-openssl.spec create mode 100644 mingw32-openssl-1.0.0-beta3-libversion.patch create mode 100644 mingw32-openssl-1.0.2a-sfx.patch create mode 100644 openssl-1.0.0-beta4-ca-dir.patch create mode 100644 openssl-1.0.0-timezone.patch create mode 100644 openssl-1.0.1c-aliasing.patch create mode 100644 openssl-1.0.1c-perlfind.patch create mode 100644 openssl-1.0.1i-algo-doc.patch create mode 100644 openssl-1.0.2a-apps-dgst.patch create mode 100644 openssl-1.0.2a-compat-symbols.patch create mode 100644 openssl-1.0.2a-defaults.patch create mode 100644 openssl-1.0.2a-dtls1-abi.patch create mode 100644 openssl-1.0.2a-env-zlib.patch create mode 100644 openssl-1.0.2a-fips-md5-allow.patch create mode 100644 openssl-1.0.2a-issuer-hash.patch create mode 100644 openssl-1.0.2a-no-rpath.patch create mode 100644 openssl-1.0.2a-padlock64.patch create mode 100644 openssl-1.0.2a-readme-warning.patch create mode 100644 openssl-1.0.2a-test-use-localhost.patch create mode 100644 openssl-1.0.2a-version-add-engines.patch create mode 100644 openssl-1.0.2a-x509.patch create mode 100644 openssl-1.0.2c-default-paths.patch create mode 100644 openssl-1.0.2c-ecc-suiteb.patch create mode 100644 openssl-1.0.2d-secp256k1.patch create mode 100644 openssl-1.0.2e-remove-nistp224.patch create mode 100644 openssl-1.0.2e-rpmbuild.patch create mode 100644 openssl-1.0.2e-speed-doc.patch create mode 100644 openssl-1.0.2e-wrap-pad.patch create mode 100644 openssl-1.0.2g-manfix.patch create mode 100644 openssl-1.0.2h-pkgconfig.patch create mode 100644 openssl-1.0.2i-chil-fixes.patch create mode 100644 openssl-1.0.2i-enc-fail.patch create mode 100644 openssl-1.0.2i-enginesdir.patch create mode 100644 openssl-1.0.2i-fips.patch create mode 100644 openssl-1.0.2i-trusted-first-doc.patch create mode 100644 openssl-1.0.2j-deprecate-algos.patch create mode 100644 openssl-1.0.2j-downgrade-strength.patch create mode 100644 openssl-1.0.2j-krb5keytab.patch create mode 100644 openssl-1.0.2k-backports.patch create mode 100644 openssl-1.0.2k-cc-reqs.patch create mode 100644 openssl-1.0.2k-cve-2017-3735.patch create mode 100644 openssl-1.0.2k-cve-2017-3736.patch create mode 100644 openssl-1.0.2k-cve-2017-3737.patch create mode 100644 openssl-1.0.2k-cve-2017-3738.patch create mode 100644 openssl-1.0.2k-cve-2018-0495.patch create mode 100644 openssl-1.0.2k-cve-2018-0732.patch create mode 100644 openssl-1.0.2k-cve-2018-0737.patch create mode 100644 openssl-1.0.2k-cve-2018-0739.patch create mode 100644 openssl-1.0.2k-long-hello.patch create mode 100644 openssl-1.0.2k-name-sensitive.patch create mode 100644 openssl-1.0.2k-no-ssl2.patch create mode 100644 openssl-1.0.2k-ppc-update.patch create mode 100644 openssl-1.0.2k-req-x509.patch create mode 100644 openssl-1.0.2k-s390x-update.patch create mode 100644 openssl-dont-include-winsock-h.patch create mode 100644 openssl-mingw64-dont-use-secure-getenv.patch create mode 100644 openssl-thread-test.c create mode 100644 openssl_mingw64_install_fix.patch create mode 100644 opensslconf-new-warning.h create mode 100644 opensslconf-new.h create mode 100755 renew-dummy-cert create mode 100644 sources diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21f1c71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/openssl-1.0.2k-hobbled.tar.xz +/openssl-1.0.2k-hobbled.tar.xz diff --git a/Makefile.certificate b/Makefile.certificate new file mode 100644 index 0000000..cc88c52 --- /dev/null +++ b/Makefile.certificate @@ -0,0 +1,82 @@ +UTF8 := $(shell locale -c LC_CTYPE -k | grep -q charmap.*UTF-8 && echo -utf8) +DAYS=365 +KEYLEN=2048 +TYPE=rsa:$(KEYLEN) +EXTRA_FLAGS= +ifdef SERIAL + EXTRA_FLAGS+=-set_serial $(SERIAL) +endif + +.PHONY: usage +.SUFFIXES: .key .csr .crt .pem +.PRECIOUS: %.key %.csr %.crt %.pem + +usage: + @echo "This makefile allows you to create:" + @echo " o public/private key pairs" + @echo " o SSL certificate signing requests (CSRs)" + @echo " o self-signed SSL test certificates" + @echo + @echo "To create a key pair, run \"make SOMETHING.key\"." + @echo "To create a CSR, run \"make SOMETHING.csr\"." + @echo "To create a test certificate, run \"make SOMETHING.crt\"." + @echo "To create a key and a test certificate in one file, run \"make SOMETHING.pem\"." + @echo + @echo "To create a key for use with Apache, run \"make genkey\"." + @echo "To create a CSR for use with Apache, run \"make certreq\"." + @echo "To create a test certificate for use with Apache, run \"make testcert\"." + @echo + @echo "To create a test certificate with serial number other than random, add SERIAL=num" + @echo "You can also specify key length with KEYLEN=n and expiration in days with DAYS=n" + @echo "Any additional options can be passed to openssl req via EXTRA_FLAGS" + @echo + @echo Examples: + @echo " make server.key" + @echo " make server.csr" + @echo " make server.crt" + @echo " make stunnel.pem" + @echo " make genkey" + @echo " make certreq" + @echo " make testcert" + @echo " make server.crt SERIAL=1" + @echo " make stunnel.pem EXTRA_FLAGS=-sha384" + @echo " make testcert DAYS=600" + +%.pem: + umask 77 ; \ + PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ + PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ + /usr/bin/openssl req $(UTF8) -newkey $(TYPE) -keyout $$PEM1 -nodes -x509 -days $(DAYS) -out $$PEM2 $(EXTRA_FLAGS) ; \ + cat $$PEM1 > $@ ; \ + echo "" >> $@ ; \ + cat $$PEM2 >> $@ ; \ + $(RM) $$PEM1 $$PEM2 + +%.key: + umask 77 ; \ + /usr/bin/openssl genrsa -aes128 $(KEYLEN) > $@ + +%.csr: %.key + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $^ -out $@ + +%.crt: %.key + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $^ -x509 -days $(DAYS) -out $@ $(EXTRA_FLAGS) + +TLSROOT=/etc/pki/tls +KEY=$(TLSROOT)/private/localhost.key +CSR=$(TLSROOT)/certs/localhost.csr +CRT=$(TLSROOT)/certs/localhost.crt + +genkey: $(KEY) +certreq: $(CSR) +testcert: $(CRT) + +$(CSR): $(KEY) + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $(KEY) -out $(CSR) + +$(CRT): $(KEY) + umask 77 ; \ + /usr/bin/openssl req $(UTF8) -new -key $(KEY) -x509 -days $(DAYS) -out $(CRT) $(EXTRA_FLAGS) diff --git a/README.FIPS b/README.FIPS new file mode 100644 index 0000000..bf3229b --- /dev/null +++ b/README.FIPS @@ -0,0 +1,75 @@ +User guide for the FIPS Red Hat Enterprise Linux - OpenSSL Module +================================================================= + +This package contains libraries which comprise the FIPS 140-2 +Red Hat Enterprise Linux - OPENSSL Module. + +The module files +================ +/usr/lib[64]/libcrypto.so.1.0.2j +/usr/lib[64]/libssl.so.1.0.2j +/usr/lib[64]/.libcrypto.so.1.0.2j.hmac +/usr/lib[64]/.libssl.so.1.0.2j.hmac + +Dependencies +============ + +The approved mode of operation requires kernel with /dev/urandom RNG running +with properties as defined in the security policy of the module. This is +provided by kernel packages with validated Red Hat Enterprise Linux - IPSec +Crytographic Module. + +Installation +============ + +The RPM package of the module can be installed by standard tools recommended +for installation of RPM packages on the Red Hat Enterprise Linux system (yum, +rpm, RHN remote management tool). + +For proper operation of the in-module integrity verification the prelink has to +be disabled. This can be done with setting PRELINKING=no in the +/etc/sysconfig/prelink configuration file. If the libraries were already +prelinked the prelink should be undone on all the system files with the +'prelink -u -a' command. + +Usage and API +============= + +The module respects kernel command line FIPS setting. If the kernel command +line contains option fips=1 the module will initialize in the FIPS approved +mode of operation automatically. To allow for the automatic initialization the +application using the module has to call one of the following API calls: + +- void OPENSSL_init_library(void) - this will do only a basic initialization +of the library and does initialization of the FIPS approved mode without setting +up EVP API with supported algorithms. + +- void OPENSSL_add_all_algorithms(void) - this API function calls +OPENSSL_init() implicitly and also adds all approved algorithms to the EVP API +in the approved mode + +- void SSL_library_init(void) - it calls OPENSSL_init() implicitly and also +adds algorithms which are necessary for TLS protocol support and initializes +the SSL library. + +To explicitely put the library to the approved mode the application can call +the following function: + +- int FIPS_mode_set(int on) - if called with 1 as a parameter it will switch +the library from the non-approved to the approved mode. If any of the selftests +and integrity verification tests fail, the library is put into the error state +and 0 is returned. If they succeed the return value is 1. + +To query the module whether it is in the approved mode or not: + +- int FIPS_mode(void) - returns 1 if the module is in the approved mode, +0 otherwise. + +To query whether the module is in the error state: + +- int FIPS_selftest_failed(void) - returns 1 if the module is in the error +state, 0 otherwise. + +To zeroize the FIPS RNG key and internal state the application calls: + +- void RAND_cleanup(void) diff --git a/ec_curve.c b/ec_curve.c new file mode 100644 index 0000000..ea3a479 --- /dev/null +++ b/ec_curve.c @@ -0,0 +1,455 @@ +/* crypto/ec/ec_curve.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * 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). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include "ec_lcl.h" +#include +#include +#include + +#ifdef OPENSSL_FIPS +# include +#endif + +typedef struct { + int field_type, /* either NID_X9_62_prime_field or + * NID_X9_62_characteristic_two_field */ + seed_len, param_len; + unsigned int cofactor; /* promoted to BN_ULONG */ +} EC_CURVE_DATA; + +/* the nist prime curves */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 48 * 6]; +} _EC_NIST_PRIME_384 = { + { + NID_X9_62_prime_field, 20, 48, 1 + }, + { + /* seed */ + 0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A, + 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, + /* x */ + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, + /* y */ + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, + 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, + 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 66 * 6]; +} _EC_NIST_PRIME_521 = { + { + NID_X9_62_prime_field, 20, 66, 1 + }, + { + /* seed */ + 0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17, + 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA, + /* p */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, + /* x */ + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, + /* y */ + 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, + 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, + 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, + 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, + 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, + /* order */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 32 * 6]; +} _EC_X9_62_PRIME_256V1 = { + { + NID_X9_62_prime_field, 20, 32, 1 + }, + { + /* seed */ + 0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1, + 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B, + /* x */ + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, + /* y */ + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, + 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 + } +}; + +typedef struct _ec_list_element_st { + int nid; + const EC_CURVE_DATA *data; + const EC_METHOD *(*meth) (void); + const char *comment; +} ec_list_element; + +static const ec_list_element curve_list[] = { + /* prime field curves */ + /* secg curves */ + /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ + {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, + "NIST/SECG curve over a 384 bit prime field"}, +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, + "NIST/SECG curve over a 521 bit prime field"}, +#else + {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, + "NIST/SECG curve over a 521 bit prime field"}, +#endif + /* X9.62 curves */ + {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, +#if defined(ECP_NISTZ256_ASM) + EC_GFp_nistz256_method, +#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp256_method, +#else + 0, +#endif + "X9.62/SECG curve over a 256 bit prime field"}, +}; + +#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element)) + +static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) +{ + EC_GROUP *group = NULL; + EC_POINT *P = NULL; + BN_CTX *ctx = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = + NULL; + int ok = 0; + int seed_len, param_len; + const EC_METHOD *meth; + const EC_CURVE_DATA *data; + const unsigned char *params; + + if ((ctx = BN_CTX_new()) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); + goto err; + } + + data = curve.data; + seed_len = data->seed_len; + param_len = data->param_len; + params = (const unsigned char *)(data + 1); /* skip header */ + params += seed_len; /* skip seed */ + + if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) + || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) + || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + + if (curve.meth != 0) { + meth = curve.meth(); + if (((group = EC_GROUP_new(meth)) == NULL) || + (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } else if (data->field_type == NID_X9_62_prime_field) { + if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* field_type == + * NID_X9_62_characteristic_two_field */ + + if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } +#endif + + if ((P = EC_POINT_new(group)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + + if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) + || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) + || !BN_set_word(x, (BN_ULONG)data->cofactor)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + if (!EC_GROUP_set_generator(group, P, order, x)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + if (seed_len) { + if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } + ok = 1; + err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + if (P) + EC_POINT_free(P); + if (ctx) + BN_CTX_free(ctx); + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (order) + BN_free(order); + if (x) + BN_free(x); + if (y) + BN_free(y); + return group; +} + +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) +{ + size_t i; + EC_GROUP *ret = NULL; + + if (nid <= 0) + return NULL; + + for (i = 0; i < curve_list_length; i++) + if (curve_list[i].nid == nid) { + ret = ec_group_new_from_data(curve_list[i]); + break; + } + + if (ret == NULL) { + ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); + return NULL; + } + + EC_GROUP_set_curve_name(ret, nid); + + return ret; +} + +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) +{ + size_t i, min; + + if (r == NULL || nitems == 0) + return curve_list_length; + + min = nitems < curve_list_length ? nitems : curve_list_length; + + for (i = 0; i < min; i++) { + r[i].nid = curve_list[i].nid; + r[i].comment = curve_list[i].comment; + } + + return curve_list_length; +} + +/* Functions to translate between common NIST curve names and NIDs */ + +typedef struct { + const char *name; /* NIST Name of curve */ + int nid; /* Curve NID */ +} EC_NIST_NAME; + +static EC_NIST_NAME nist_curves[] = { + {"B-163", NID_sect163r2}, + {"B-233", NID_sect233r1}, + {"B-283", NID_sect283r1}, + {"B-409", NID_sect409r1}, + {"B-571", NID_sect571r1}, + {"K-163", NID_sect163k1}, + {"K-233", NID_sect233k1}, + {"K-283", NID_sect283k1}, + {"K-409", NID_sect409k1}, + {"K-571", NID_sect571k1}, + {"P-192", NID_X9_62_prime192v1}, + {"P-224", NID_secp224r1}, + {"P-256", NID_X9_62_prime256v1}, + {"P-384", NID_secp384r1}, + {"P-521", NID_secp521r1} +}; + +const char *EC_curve_nid2nist(int nid) +{ + size_t i; + for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { + if (nist_curves[i].nid == nid) + return nist_curves[i].name; + } + return NULL; +} + +int EC_curve_nist2nid(const char *name) +{ + size_t i; + for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { + if (!strcmp(nist_curves[i].name, name)) + return nist_curves[i].nid; + } + return NID_undef; +} diff --git a/ectest.c b/ectest.c new file mode 100644 index 0000000..701e706 --- /dev/null +++ b/ectest.c @@ -0,0 +1,994 @@ +/* crypto/ec/ectest.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * 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). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include +#ifdef FLAT_INC +# include "e_os.h" +#else +# include "../e_os.h" +#endif +#include +#include + +#ifdef OPENSSL_NO_EC +int main(int argc, char *argv[]) +{ + puts("Elliptic curves are disabled."); + return 0; +} +#else + +# include +# ifndef OPENSSL_NO_ENGINE +# include +# endif +# include +# include +# include +# include +# include +# include + +# if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12) +/* suppress "too big too optimize" warning */ +# pragma warning(disable:4959) +# endif + +# define ABORT do { \ + fflush(stdout); \ + fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \ + ERR_print_errors_fp(stderr); \ + EXIT(1); \ +} while (0) + +# define TIMING_BASE_PT 0 +# define TIMING_RAND_PT 1 +# define TIMING_SIMUL 2 + +# if 0 +static void timings(EC_GROUP *group, int type, BN_CTX *ctx) +{ + clock_t clck; + int i, j; + BIGNUM *s; + BIGNUM *r[10], *r0[10]; + EC_POINT *P; + + s = BN_new(); + if (s == NULL) + ABORT; + + fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group)); + if (!EC_GROUP_get_order(group, s, ctx)) + ABORT; + fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s)); + fflush(stdout); + + P = EC_POINT_new(group); + if (P == NULL) + ABORT; + EC_POINT_copy(P, EC_GROUP_get0_generator(group)); + + for (i = 0; i < 10; i++) { + if ((r[i] = BN_new()) == NULL) + ABORT; + if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) + ABORT; + if (type != TIMING_BASE_PT) { + if ((r0[i] = BN_new()) == NULL) + ABORT; + if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) + ABORT; + } + } + + clck = clock(); + for (i = 0; i < 10; i++) { + for (j = 0; j < 10; j++) { + if (!EC_POINT_mul + (group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, + (type != TIMING_BASE_PT) ? P : NULL, + (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) + ABORT; + } + } + clck = clock() - clck; + + fprintf(stdout, "\n"); + +# ifdef CLOCKS_PER_SEC + /* + * "To determine the time in seconds, the value returned by the clock + * function should be divided by the value of the macro CLOCKS_PER_SEC." + * -- ISO/IEC 9899 + */ +# define UNIT "s" +# else + /* + * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on + * NeXTstep/OpenStep + */ +# define UNIT "units" +# define CLOCKS_PER_SEC 1 +# endif + + if (type == TIMING_BASE_PT) { + fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, + "base point multiplications", (double)clck / CLOCKS_PER_SEC); + } else if (type == TIMING_RAND_PT) { + fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, + "random point multiplications", + (double)clck / CLOCKS_PER_SEC); + } else if (type == TIMING_SIMUL) { + fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, + "s*P+t*Q operations", (double)clck / CLOCKS_PER_SEC); + } + fprintf(stdout, "average: %.4f " UNIT "\n", + (double)clck / (CLOCKS_PER_SEC * i * j)); + + EC_POINT_free(P); + BN_free(s); + for (i = 0; i < 10; i++) { + BN_free(r[i]); + if (type != TIMING_BASE_PT) + BN_free(r0[i]); + } +} +# endif + +/* test multiplication with group order, long and negative scalars */ +static void group_order_tests(EC_GROUP *group) +{ + BIGNUM *n1, *n2, *order; + EC_POINT *P = EC_POINT_new(group); + EC_POINT *Q = EC_POINT_new(group); + BN_CTX *ctx = BN_CTX_new(); + int i; + + n1 = BN_new(); + n2 = BN_new(); + order = BN_new(); + fprintf(stdout, "verify group order ..."); + fflush(stdout); + if (!EC_GROUP_get_order(group, order, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + fprintf(stdout, "."); + fflush(stdout); + if (!EC_GROUP_precompute_mult(group, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + fprintf(stdout, " ok\n"); + fprintf(stdout, "long/negative scalar tests "); + for (i = 1; i <= 2; i++) { + const BIGNUM *scalars[6]; + const EC_POINT *points[6]; + + fprintf(stdout, i == 1 ? + "allowing precomputation ... " : + "without precomputation ... "); + if (!BN_set_word(n1, i)) + ABORT; + /* + * If i == 1, P will be the predefined generator for which + * EC_GROUP_precompute_mult has set up precomputation. + */ + if (!EC_POINT_mul(group, P, n1, NULL, NULL, ctx)) + ABORT; + + if (!BN_one(n1)) + ABORT; + /* n1 = 1 - order */ + if (!BN_sub(n1, n1, order)) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + + /* n2 = 1 + order */ + if (!BN_add(n2, order, BN_value_one())) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + + /* n2 = (1 - order) * (1 + order) = 1 - order^2 */ + if (!BN_mul(n2, n1, n2, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + + /* n2 = order^2 - 1 */ + BN_set_negative(n2, 0); + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + /* Add P to verify the result. */ + if (!EC_POINT_add(group, Q, Q, P, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + + /* Exercise EC_POINTs_mul, including corner cases. */ + if (EC_POINT_is_at_infinity(group, P)) + ABORT; + scalars[0] = n1; + points[0] = Q; /* => infinity */ + scalars[1] = n2; + points[1] = P; /* => -P */ + scalars[2] = n1; + points[2] = Q; /* => infinity */ + scalars[3] = n2; + points[3] = Q; /* => infinity */ + scalars[4] = n1; + points[4] = P; /* => P */ + scalars[5] = n2; + points[5] = Q; /* => infinity */ + if (!EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + } + fprintf(stdout, "ok\n"); + + EC_POINT_free(P); + EC_POINT_free(Q); + BN_free(n1); + BN_free(n2); + BN_free(order); + BN_CTX_free(ctx); +} + +static void prime_field_tests(void) +{ + BN_CTX *ctx = NULL; + BIGNUM *p, *a, *b; + EC_GROUP *group; + EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = + NULL, *P_384 = NULL, *P_521 = NULL; + EC_POINT *P, *Q, *R; + BIGNUM *x, *y, *z; + unsigned char buf[100]; + size_t i, len; + int k; + +# if 1 /* optional */ + ctx = BN_CTX_new(); + if (!ctx) + ABORT; +# endif + + p = BN_new(); + a = BN_new(); + b = BN_new(); + if (!p || !a || !b) + ABORT; + + group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use + * EC_GROUP_new_curve_GFp so + * that the library gets to + * choose the EC_METHOD */ + if (!group) + ABORT; + + P = EC_POINT_new(group); + Q = EC_POINT_new(group); + R = EC_POINT_new(group); + if (!P || !Q || !R) + ABORT; + + x = BN_new(); + y = BN_new(); + z = BN_new(); + if (!x || !y || !z) + ABORT; + + /* Curve P-256 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn + (&p, + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn + (&a, + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) + ABORT; + if (!BN_hex2bn + (&b, + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn + (&x, + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" + "84F3B9CAC2FC632551")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn + (&z, + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 256) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_256, group)) + ABORT; + + /* Curve P-384 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141" + "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" + "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14" + "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 384) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_384, group)) + ABORT; + + /* Curve P-521 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B" + "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573" + "DF883D2C34F1EF451FD46B503F00")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F" + "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" + "3C1856A429BF97E7E31C2E5BD66")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" + "C9B8899C47AEBB6FB71E91386409")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579" + "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C" + "7086A272C24088BE94769FD16650")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 521) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_521, group)) + ABORT; + + /* more tests using the last curve */ + + if (!EC_POINT_copy(Q, P)) + ABORT; + if (EC_POINT_is_at_infinity(group, Q)) + ABORT; + if (!EC_POINT_dbl(group, P, P, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!EC_POINT_invert(group, Q, ctx)) + ABORT; /* P = -2Q */ + + if (!EC_POINT_add(group, R, P, Q, ctx)) + ABORT; + if (!EC_POINT_add(group, R, R, Q, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, R)) + ABORT; /* R = P + 2Q */ + + { + const EC_POINT *points[4]; + const BIGNUM *scalars[4]; + BIGNUM scalar3; + + if (EC_POINT_is_at_infinity(group, Q)) + ABORT; + points[0] = Q; + points[1] = Q; + points[2] = Q; + points[3] = Q; + + if (!EC_GROUP_get_order(group, z, ctx)) + ABORT; + if (!BN_add(y, z, BN_value_one())) + ABORT; + if (BN_is_odd(y)) + ABORT; + if (!BN_rshift1(y, y)) + ABORT; + scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ + scalars[1] = y; + + fprintf(stdout, "combined multiplication ..."); + fflush(stdout); + + /* z is still the group order */ + if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) + ABORT; + if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, R, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, R, Q, ctx)) + ABORT; + + fprintf(stdout, "."); + fflush(stdout); + + if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) + ABORT; + if (!BN_add(z, z, y)) + ABORT; + BN_set_negative(z, 1); + scalars[0] = y; + scalars[1] = z; /* z = -(order + y) */ + + if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + fprintf(stdout, "."); + fflush(stdout); + + if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) + ABORT; + if (!BN_add(z, x, y)) + ABORT; + BN_set_negative(z, 1); + scalars[0] = x; + scalars[1] = y; + scalars[2] = z; /* z = -(x+y) */ + + BN_init(&scalar3); + BN_zero(&scalar3); + scalars[3] = &scalar3; + + if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + fprintf(stdout, " ok\n\n"); + + BN_free(&scalar3); + } + +# if 0 + timings(P_256, TIMING_BASE_PT, ctx); + timings(P_256, TIMING_RAND_PT, ctx); + timings(P_256, TIMING_SIMUL, ctx); + timings(P_384, TIMING_BASE_PT, ctx); + timings(P_384, TIMING_RAND_PT, ctx); + timings(P_384, TIMING_SIMUL, ctx); + timings(P_521, TIMING_BASE_PT, ctx); + timings(P_521, TIMING_RAND_PT, ctx); + timings(P_521, TIMING_SIMUL, ctx); +# endif + + if (ctx) + BN_CTX_free(ctx); + BN_free(p); + BN_free(a); + BN_free(b); + EC_GROUP_free(group); + EC_POINT_free(P); + EC_POINT_free(Q); + EC_POINT_free(R); + BN_free(x); + BN_free(y); + BN_free(z); + + if (P_160) + EC_GROUP_free(P_160); + if (P_192) + EC_GROUP_free(P_192); + if (P_224) + EC_GROUP_free(P_224); + if (P_256) + EC_GROUP_free(P_256); + if (P_384) + EC_GROUP_free(P_384); + if (P_521) + EC_GROUP_free(P_521); + +} + + +static void internal_curve_test(void) +{ + EC_builtin_curve *curves = NULL; + size_t crv_len = 0, n = 0; + int ok = 1; + + crv_len = EC_get_builtin_curves(NULL, 0); + + curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); + + if (curves == NULL) + return; + + if (!EC_get_builtin_curves(curves, crv_len)) { + OPENSSL_free(curves); + return; + } + + fprintf(stdout, "testing internal curves: "); + + for (n = 0; n < crv_len; n++) { + EC_GROUP *group = NULL; + int nid = curves[n].nid; + if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { + ok = 0; + fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with" + " curve %s\n", OBJ_nid2sn(nid)); + /* try next curve */ + continue; + } + if (!EC_GROUP_check(group, NULL)) { + ok = 0; + fprintf(stdout, "\nEC_GROUP_check() failed with" + " curve %s\n", OBJ_nid2sn(nid)); + EC_GROUP_free(group); + /* try the next curve */ + continue; + } + fprintf(stdout, "."); + fflush(stdout); + EC_GROUP_free(group); + } + if (ok) + fprintf(stdout, " ok\n\n"); + else { + fprintf(stdout, " failed\n\n"); + ABORT; + } + OPENSSL_free(curves); + return; +} + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/* + * nistp_test_params contains magic numbers for testing our optimized + * implementations of several NIST curves with characteristic > 3. + */ +struct nistp_test_params { + const EC_METHOD *(*meth) (); + int degree; + /* + * Qx, Qy and D are taken from + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf + * Otherwise, values are standard curve parameters from FIPS 180-3 + */ + const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d; +}; + +static const struct nistp_test_params nistp_tests_params[] = { + { + /* P-256 */ + EC_GFp_nistp256_method, + 256, + /* p */ + "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + /* a */ + "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", + /* b */ + "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", + /* Qx */ + "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", + /* Qy */ + "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", + /* Gx */ + "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + /* Gy */ + "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + /* order */ + "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + /* d */ + "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", + }, + { + /* P-521 */ + EC_GFp_nistp521_method, + 521, + /* p */ + "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + /* a */ + "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", + /* b */ + "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", + /* Qx */ + "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", + /* Qy */ + "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", + /* Gx */ + "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", + /* Gy */ + "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + /* order */ + "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", + /* d */ + "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", + }, +}; + +static void nistp_single_test(const struct nistp_test_params *test) +{ + BN_CTX *ctx; + BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; + EC_GROUP *NISTP; + EC_POINT *G, *P, *Q, *Q_CHECK; + + fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", + test->degree); + ctx = BN_CTX_new(); + p = BN_new(); + a = BN_new(); + b = BN_new(); + x = BN_new(); + y = BN_new(); + m = BN_new(); + n = BN_new(); + order = BN_new(); + + NISTP = EC_GROUP_new(test->meth()); + if (!NISTP) + ABORT; + if (!BN_hex2bn(&p, test->p)) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, test->a)) + ABORT; + if (!BN_hex2bn(&b, test->b)) + ABORT; + if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) + ABORT; + G = EC_POINT_new(NISTP); + P = EC_POINT_new(NISTP); + Q = EC_POINT_new(NISTP); + Q_CHECK = EC_POINT_new(NISTP); + if (!BN_hex2bn(&x, test->Qx)) + ABORT; + if (!BN_hex2bn(&y, test->Qy)) + ABORT; + if (!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) + ABORT; + if (!BN_hex2bn(&x, test->Gx)) + ABORT; + if (!BN_hex2bn(&y, test->Gy)) + ABORT; + if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) + ABORT; + if (!BN_hex2bn(&order, test->order)) + ABORT; + if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) + ABORT; + + fprintf(stdout, "verify degree ... "); + if (EC_GROUP_get_degree(NISTP) != test->degree) + ABORT; + fprintf(stdout, "ok\n"); + + fprintf(stdout, "NIST test vectors ... "); + if (!BN_hex2bn(&n, test->d)) + ABORT; + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + /* set generator to P = 2*G, where G is the standard generator */ + if (!EC_POINT_dbl(NISTP, P, G, ctx)) + ABORT; + if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) + ABORT; + /* set the scalar to m=n/2, where n is the NIST test scalar */ + if (!BN_rshift(m, n, 1)) + ABORT; + + /* test the non-standard generator */ + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + /* + * We have not performed precomputation so have_precompute mult should be + * false + */ + if (EC_GROUP_have_precompute_mult(NISTP)) + ABORT; + + /* now repeat all tests with precomputation */ + if (!EC_GROUP_precompute_mult(NISTP, ctx)) + ABORT; + if (!EC_GROUP_have_precompute_mult(NISTP)) + ABORT; + + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + /* reset generator */ + if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) + ABORT; + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + fprintf(stdout, "ok\n"); + group_order_tests(NISTP); +# if 0 + timings(NISTP, TIMING_BASE_PT, ctx); + timings(NISTP, TIMING_RAND_PT, ctx); +# endif + EC_GROUP_free(NISTP); + EC_POINT_free(G); + EC_POINT_free(P); + EC_POINT_free(Q); + EC_POINT_free(Q_CHECK); + BN_free(n); + BN_free(m); + BN_free(p); + BN_free(a); + BN_free(b); + BN_free(x); + BN_free(y); + BN_free(order); + BN_CTX_free(ctx); +} + +static void nistp_tests() +{ + unsigned i; + + for (i = 0; + i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); + i++) { + nistp_single_test(&nistp_tests_params[i]); + } +} +# endif + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +int main(int argc, char *argv[]) +{ + + /* enable memory leak checking unless explicitly disabled */ + if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) + && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + } else { + /* OPENSSL_DEBUG_MEMORY=off */ + CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); + } + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + ERR_load_crypto_strings(); + + RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ + + prime_field_tests(); + puts(""); +# ifndef OPENSSL_NO_EC2M + char2_field_tests(); +# endif +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + nistp_tests(); +# endif + /* test the internal curves */ + internal_curve_test(); + +# ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +# endif + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + ERR_remove_thread_state(NULL); + CRYPTO_mem_leaks_fp(stderr); + + return 0; +} +#endif diff --git a/hobble-openssl b/hobble-openssl new file mode 100755 index 0000000..8750ad6 --- /dev/null +++ b/hobble-openssl @@ -0,0 +1,47 @@ +#!/bin/sh + +# Quit out if anything fails. +set -e + +# Clean out patent-or-otherwise-encumbered code. +# MDC-2: 4,908,861 13/03/2007 - expired, we do not remove it but do not enable it anyway +# IDEA: 5,214,703 07/01/2012 - expired, we do not remove it anymore +# RC5: 5,724,428 01/11/2015 - expired, we do not remove it anymore +# EC: ????????? ??/??/2020 +# SRP: ????????? ??/??/20?? + +# Remove assembler portions of IDEA, MDC2, and RC5. +# (find crypto/rc5/asm -type f | xargs -r rm -fv) + +# SRP. +for a in srp; do + for c in `find crypto/$a -name "*.c" -a \! -name "*test*" -type f` ; do + echo Destroying $c + > $c + done +done + +for c in `find crypto/bn -name "*gf2m.c"`; do + echo Destroying $c + > $c +done + +for c in `find crypto/ec -name "ec2*.c" -o -name "ec_curve.c" -o -name "ecp_nistp22?.c" -o -name "ectest.c"`; do + echo Destroying $c + > $c +done + +for h in `find crypto ssl apps test -name "*.h"` ; do + echo Removing SRP and EC2M references from $h + cat $h | \ + awk 'BEGIN {ech=1;} \ + /^#[ \t]*ifndef.*NO_SRP/ {ech--; next;} \ + /^#[ \t]*ifndef.*NO_EC2M/ {ech--; next;} \ + /^#[ \t]*if/ {if(ech < 1) ech--;} \ + {if(ech>0) {;print $0};} \ + /^#[ \t]*endif/ {if(ech < 1) ech++;}' > $h.hobbled && \ + mv $h.hobbled $h +done + +# Make the makefiles happy. +# touch crypto/rc5/asm/rc5-586.pl diff --git a/make-dummy-cert b/make-dummy-cert new file mode 100755 index 0000000..f5f0453 --- /dev/null +++ b/make-dummy-cert @@ -0,0 +1,28 @@ +#!/bin/sh +umask 077 + +answers() { + echo -- + echo SomeState + echo SomeCity + echo SomeOrganization + echo SomeOrganizationalUnit + echo localhost.localdomain + echo root@localhost.localdomain +} + +if [ $# -eq 0 ] ; then + echo $"Usage: `basename $0` filename [...]" + exit 0 +fi + +for target in $@ ; do + PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` + PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` + trap "rm -f $PEM1 $PEM2" SIGINT + answers | /usr/bin/openssl req -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 365 -out $PEM2 2> /dev/null + cat $PEM1 > ${target} + echo "" >> ${target} + cat $PEM2 >> ${target} + rm -f $PEM1 $PEM2 +done diff --git a/mingw-openssl-drop-unneeded-reference-to-dlfcn-h.patch b/mingw-openssl-drop-unneeded-reference-to-dlfcn-h.patch new file mode 100644 index 0000000..255374a --- /dev/null +++ b/mingw-openssl-drop-unneeded-reference-to-dlfcn-h.patch @@ -0,0 +1,10 @@ +--- crypto/fips/fips.c.orig 2010-10-07 23:33:08.293664062 +0200 ++++ crypto/fips/fips.c 2010-10-07 23:33:20.723360688 +0200 +@@ -57,7 +57,6 @@ + #include + #include + #include +-#include + #include + #include + #include "fips_locl.h" diff --git a/mingw-openssl-fix-fips-build-failure.patch b/mingw-openssl-fix-fips-build-failure.patch new file mode 100644 index 0000000..fccae0f --- /dev/null +++ b/mingw-openssl-fix-fips-build-failure.patch @@ -0,0 +1,97 @@ +--- openssl-1.0.1c/crypto/fips/fips_rand_selftest.c.orig 2012-11-03 18:59:03.620066556 +0100 ++++ openssl-1.0.1c/crypto/fips/fips_rand_selftest.c 2012-11-03 19:57:33.156686682 +0100 +@@ -47,6 +47,8 @@ + * + */ + ++#ifdef OPENSSL_FIPS ++ + #include + #include + #include +@@ -54,8 +56,6 @@ + #include + #include "fips_locl.h" + +-#ifdef OPENSSL_FIPS +- + typedef struct { + unsigned char DT[16]; + unsigned char V[16]; +--- openssl-1.0.1c/crypto/fips/fips_dsa_selftest.c.orig 2012-11-03 20:03:20.546180631 +0100 ++++ openssl-1.0.1c/crypto/fips/fips_dsa_selftest.c 2012-11-03 20:03:46.069328396 +0100 +@@ -47,6 +47,8 @@ + * + */ + ++#ifdef OPENSSL_FIPS ++ + #include + #include + #include +@@ -56,8 +58,6 @@ + #include + #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, +--- openssl-1.0.1c/crypto/fips/fips_rand.c.orig 2012-11-03 20:07:49.956891942 +0100 ++++ openssl-1.0.1c/crypto/fips/fips_rand.c 2012-11-03 20:08:14.260048118 +0100 +@@ -47,6 +47,8 @@ + * + */ + ++#ifdef OPENSSL_FIPS ++ + /* + * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4. + */ +@@ -82,8 +84,6 @@ + #include + #include "fips_locl.h" + +-#ifdef OPENSSL_FIPS +- + void *OPENSSL_stderr(void); + + # define AES_BLOCK_LENGTH 16 +--- openssl-1.0.1c/crypto/rand/md_rand.c.orig 2012-11-03 20:19:31.461754618 +0100 ++++ openssl-1.0.1c/crypto/rand/md_rand.c 2012-11-03 20:20:58.294282662 +0100 +@@ -394,7 +394,11 @@ + /* always poll for external entropy in FIPS mode, drbg provides the + * expansion + */ ++#ifdef OPENSSL_FIPS + if (!initialized || FIPS_module_mode()) { ++#else ++ if (!initialized) { ++#endif + RAND_poll(); + initialized = 1; + } +--- openssl-1.0.1c/crypto/opensslconf.h.in 2012-11-09 20:34:03.434391630 +0100 ++++ openssl-1.0.1c/crypto/opensslconf.h.in.fips 2005-12-16 11:37:23.000000000 +0100 +@@ -1,20 +1,5 @@ + /* 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/mingw-openssl.spec b/mingw-openssl.spec new file mode 100644 index 0000000..3e1effa --- /dev/null +++ b/mingw-openssl.spec @@ -0,0 +1,749 @@ +%?mingw_package_header + +# For the curious: +# 0.9.5a soversion = 0 +# 0.9.6 soversion = 1 +# 0.9.6a soversion = 2 +# 0.9.6c soversion = 3 +# 0.9.7a soversion = 4 +# 0.9.7ef soversion = 5 +# 0.9.8ab soversion = 6 +# 0.9.8g soversion = 7 +# 0.9.8jk + EAP-FAST soversion = 8 +# 1.0.0 soversion = 10 +%global soversion 10 + +# Enable the tests. +# These only work some of the time, but fail randomly at other times +# (although I have had them complete a few times, so I don't think +# there is any actual problem with the binaries). +%global run_tests 0 + +# Number of threads to spawn when testing some threading fixes. +%global thread_test_threads %{?threads:%{threads}}%{!?threads:1} + +Name: mingw-openssl +Version: 1.0.2k +Release: 3%{?dist} +Summary: MinGW port of the OpenSSL toolkit + +License: OpenSSL +Group: Development/Libraries +URL: http://www.openssl.org/ + +# We have to remove certain patented algorithms from the openssl source +# tarball with the hobble-openssl script which is included below. +# The original openssl upstream tarball cannot be shipped in the .src.rpm. +Source: openssl-%{version}-hobbled.tar.xz + +Source1: hobble-openssl +Source2: Makefile.certificate +Source6: make-dummy-cert +Source7: renew-dummy-cert +Source8: openssl-thread-test.c +Source9: opensslconf-new.h +Source10: opensslconf-new-warning.h +Source11: README.FIPS +Source12: ec_curve.c +Source13: ectest.c + +# Build changes +Patch1: openssl-1.0.2e-rpmbuild.patch +Patch2: openssl-1.0.2a-defaults.patch +Patch4: openssl-1.0.2i-enginesdir.patch +Patch5: openssl-1.0.2a-no-rpath.patch +Patch6: openssl-1.0.2a-test-use-localhost.patch +Patch7: openssl-1.0.0-timezone.patch +Patch8: openssl-1.0.1c-perlfind.patch +Patch9: openssl-1.0.1c-aliasing.patch +# Bug fixes +Patch23: openssl-1.0.2c-default-paths.patch +Patch24: openssl-1.0.2a-issuer-hash.patch +# Functionality changes +Patch33: openssl-1.0.0-beta4-ca-dir.patch +Patch34: openssl-1.0.2a-x509.patch +Patch35: openssl-1.0.2a-version-add-engines.patch +# Patch39: openssl-1.0.2a-ipv6-apps.patch +Patch40: openssl-1.0.2i-fips.patch +Patch43: openssl-1.0.2j-krb5keytab.patch +Patch45: openssl-1.0.2a-env-zlib.patch +Patch47: openssl-1.0.2a-readme-warning.patch +Patch49: openssl-1.0.1i-algo-doc.patch +Patch50: openssl-1.0.2a-dtls1-abi.patch +# Patch51: openssl-1.0.2a-version.patch +# Patch56: openssl-1.0.2a-rsa-x931.patch +Patch58: openssl-1.0.2a-fips-md5-allow.patch +Patch60: openssl-1.0.2a-apps-dgst.patch +# Patch63: openssl-1.0.2k-starttls.patch +Patch65: openssl-1.0.2i-chil-fixes.patch +Patch66: openssl-1.0.2h-pkgconfig.patch +# Patch68: openssl-1.0.2i-secure-getenv.patch +# Patch70: openssl-1.0.2a-fips-ec.patch +Patch71: openssl-1.0.2g-manfix.patch +# Patch72: openssl-1.0.2a-fips-ctor.patch +Patch73: openssl-1.0.2c-ecc-suiteb.patch +Patch74: openssl-1.0.2j-deprecate-algos.patch +Patch75: openssl-1.0.2a-compat-symbols.patch +# Patch76: openssl-1.0.2j-new-fips-reqs.patch +Patch77: openssl-1.0.2j-downgrade-strength.patch +Patch78: openssl-1.0.2k-cc-reqs.patch +Patch90: openssl-1.0.2i-enc-fail.patch +Patch94: openssl-1.0.2d-secp256k1.patch +Patch95: openssl-1.0.2e-remove-nistp224.patch +Patch96: openssl-1.0.2e-speed-doc.patch +Patch97: openssl-1.0.2k-no-ssl2.patch +Patch98: openssl-1.0.2k-long-hello.patch +# Patch99: openssl-1.0.2k-fips-randlock.patch +# Backported fixes including security fixes +Patch80: openssl-1.0.2e-wrap-pad.patch +Patch81: openssl-1.0.2a-padlock64.patch +Patch82: openssl-1.0.2i-trusted-first-doc.patch +Patch83: openssl-1.0.2k-backports.patch +Patch84: openssl-1.0.2k-ppc-update.patch +Patch85: openssl-1.0.2k-req-x509.patch +Patch86: openssl-1.0.2k-cve-2017-3736.patch +Patch87: openssl-1.0.2k-cve-2017-3737.patch +Patch88: openssl-1.0.2k-cve-2017-3738.patch +Patch89: openssl-1.0.2k-s390x-update.patch +Patch100: openssl-1.0.2k-name-sensitive.patch +Patch101: openssl-1.0.2k-cve-2017-3735.patch +Patch102: openssl-1.0.2k-cve-2018-0732.patch +Patch103: openssl-1.0.2k-cve-2018-0737.patch +Patch104: openssl-1.0.2k-cve-2018-0739.patch +Patch105: openssl-1.0.2k-cve-2018-0495.patch + +# MinGW-specific patches. +# Rename *eay32.dll to lib*.dll +Patch1001: mingw32-openssl-1.0.0-beta3-libversion.patch +# Fix engines/ install target after lib rename +Patch1002: mingw32-openssl-1.0.2a-sfx.patch +# Some .c file contains in #include while it +# doesn't really use anything from that header +Patch1003: mingw-openssl-drop-unneeded-reference-to-dlfcn-h.patch +# Mingw-w64 compatibility patch +Patch1004: openssl_mingw64_install_fix.patch +# Prevent a build failure which occurs because we don't have FIPS enabled +Patch1005: mingw-openssl-fix-fips-build-failure.patch +# The function secure_getenv is a GNU extension which isn't available on Windows +Patch1006: openssl-mingw64-dont-use-secure-getenv.patch +# Don't include the old winsock.h as it will cause warnings/errors in packages +# using the openssl headers like: Please include winsock2.h before windows.h +Patch1007: openssl-dont-include-winsock-h.patch + +BuildArch: noarch +ExclusiveArch: %{ix86} x86_64 + +BuildRequires: mingw32-filesystem >= 95 +BuildRequires: mingw32-gcc +BuildRequires: mingw32-binutils +BuildRequires: mingw32-zlib + +BuildRequires: mingw64-filesystem >= 95 +BuildRequires: mingw64-gcc +BuildRequires: mingw64-binutils +BuildRequires: mingw64-zlib + +BuildRequires: perl-interpreter +BuildRequires: sed +BuildRequires: /usr/bin/cmp +BuildRequires: lksctp-tools-devel +BuildRequires: /usr/bin/rename +BuildRequires: /usr/bin/pod2man + +# XXX Not really sure about this one. The build script uses +# /usr/bin/makedepend which comes from imake. +BuildRequires: imake + +%if %{run_tests} +# Required both to build, and to run the tests. +# XXX This needs to be fixed - cross-compilation should not +# require running executables. +BuildRequires: wine + +# Required to run the tests. +BuildRequires: xorg-x11-server-Xvfb +%endif + + +%description +The OpenSSL toolkit provides support for secure communications between +machines. OpenSSL includes a certificate management tool and shared +libraries which provide various cryptographic algorithms and +protocols. + +This package contains Windows (MinGW) libraries and development tools. + + +# Win32 +%package -n mingw32-openssl +Summary: MinGW port of the OpenSSL toolkit +#Requires: ca-certificates >= 2008-5 +Requires: pkgconfig + +%description -n mingw32-openssl +The OpenSSL toolkit provides support for secure communications between +machines. OpenSSL includes a certificate management tool and shared +libraries which provide various cryptographic algorithms and +protocols. + +This package contains Windows (MinGW) libraries and development tools. + +%package -n mingw32-openssl-static +Summary: Static version of the MinGW port of the OpenSSL toolkit +Requires: mingw32-openssl = %{version}-%{release} + +%description -n mingw32-openssl-static +Static version of the MinGW port of the OpenSSL toolkit. + +# Win64 +%package -n mingw64-openssl +Summary: MinGW port of the OpenSSL toolkit +#Requires: ca-certificates >= 2008-5 +Requires: pkgconfig + +%description -n mingw64-openssl +The OpenSSL toolkit provides support for secure communications between +machines. OpenSSL includes a certificate management tool and shared +libraries which provide various cryptographic algorithms and +protocols. + +This package contains Windows (MinGW) libraries and development tools. + +%package -n mingw64-openssl-static +Summary: Static version of the MinGW port of the OpenSSL toolkit +Requires: mingw64-openssl = %{version}-%{release} + +%description -n mingw64-openssl-static +Static version of the MinGW port of the OpenSSL toolkit. + + +%?mingw_debug_package + + +%prep +%setup -q -n openssl-%{version} + +# The hobble_openssl is called here redundantly, just to be sure. +# The tarball has already the sources removed. +%{SOURCE1} > /dev/null + +cp %{SOURCE12} %{SOURCE13} crypto/ec/ + +%patch1 -p1 -b .rpmbuild +%patch2 -p1 -b .defaults +%patch4 -p1 -b .enginesdir %{?_rawbuild} +%patch5 -p1 -b .no-rpath +%patch6 -p1 -b .use-localhost +%patch7 -p1 -b .timezone +%patch8 -p1 -b .perlfind %{?_rawbuild} +%patch9 -p1 -b .aliasing + +%patch23 -p1 -b .default-paths +%patch24 -p1 -b .issuer-hash + +%patch33 -p1 -b .ca-dir +%patch34 -p1 -b .x509 +%patch35 -p1 -b .version-add-engines +#patch39 -p1 -b .ipv6-apps +%patch40 -p1 -b .fips +%patch43 -p1 -b .krb5keytab +%patch45 -p1 -b .env-zlib +%patch47 -p1 -b .warning +%patch49 -p1 -b .algo-doc +%patch50 -p1 -b .dtls1-abi +#patch51 -p1 -b .version +#patch56 -p1 -b .x931 +%patch58 -p1 -b .md5-allow +%patch60 -p1 -b .dgst +#patch63 -p1 -b .starttls +%patch65 -p1 -b .chil +%patch66 -p1 -b .pkgconfig +#patch68 -p1 -b .secure-getenv +#patch70 -p1 -b .fips-ec +%patch71 -p1 -b .manfix +#patch72 -p1 -b .fips-ctor +%patch73 -p1 -b .suiteb +%patch74 -p1 -b .deprecate-algos +%patch75 -p1 -b .compat +#patch76 -p1 -b .fips-reqs +%patch77 -p1 -b .strength +%patch78 -p1 -b .cc-reqs +%patch90 -p1 -b .enc-fail +%patch94 -p1 -b .secp256k1 +%patch95 -p1 -b .nistp224 +%patch96 -p1 -b .speed-doc +%patch97 -p1 -b .no-ssl2 +%patch98 -p1 -b .long-hello +#patch99 -p1 -b .randlock + +%patch80 -p1 -b .wrap +%patch81 -p1 -b .padlock64 +%patch82 -p1 -b .trusted-first +%patch83 -p1 -b .backports +%patch84 -p1 -b .ppc-update +%patch85 -p1 -b .req-x509 +%patch86 -p1 -b .mont5-carry +%patch87 -p1 -b .ssl-err +%patch88 -p1 -b .rsaz-overflow +%patch89 -p1 -b .s390x-update +%patch100 -p1 -b .name-sensitive +%patch101 -p1 -b .overread +%patch102 -p1 -b .large-dh +%patch103 -p1 -b .gen-timing +%patch104 -p1 -b .asn1-recursive +%patch105 -p1 -b .rohnp-fix + +# MinGW specific patches +%patch1001 -p1 -b .mingw-libversion +%patch1002 -p1 -b .mingw-sfx +%patch1003 -p0 -b .dlfcn +%patch1004 -p0 -b .mingw64 +%patch1005 -p1 -b .fips_mingw +%patch1006 -p1 -b .secure_getenv_mingw +%patch1007 -p0 -b .winsock + +sed -i 's/SHLIB_VERSION_NUMBER "1.0.0"/SHLIB_VERSION_NUMBER "%{version}"/' crypto/opensslv.h + +# Modify the various perl scripts to reference perl in the right location. +perl util/perlpath.pl `dirname %{__perl}` + +# Generate a table with the compile settings for my perusal. +touch Makefile +make TABLE PERL=%{__perl} + +# Create two copies of the source folder as OpenSSL doesn't support out of source builds +mkdir ../build_win32 +mv * ../build_win32 +mv ../build_win32 . +mkdir build_win64 +cp -Rp build_win32/* build_win64 + +# Use mingw cflags instead of hardcoded ones +sed -i -e '/^"mingw"/ s/-fomit-frame-pointer -O3 -march=i486 -Wall/%{mingw32_cflags}/' build_win32/Configure +sed -i -e '/^"mingw"/ s/-O3 -Wall/%{mingw64_cflags}/' build_win64/Configure + + +%build +############################################################################### +# Win32 +############################################################################### +pushd build_win32 + +PERL=%{__perl} \ +./Configure \ + --prefix=%{mingw32_prefix} \ + --openssldir=%{mingw32_sysconfdir}/pki/tls \ + zlib enable-camellia enable-seed enable-tlsext enable-rfc3779 \ + enable-cms enable-md2 enable-rc5 \ + no-mdc2 no-ec2m no-gost no-srp \ + no-fips no-hw \ + --cross-compile-prefix=%{mingw32_target}- \ + --enginesdir=%{mingw32_libdir}/openssl/engines \ + shared mingw + +# Regenerate def files as we disabled some algorithms above +perl util/mkdef.pl crypto ssl update + +make depend +make all build-shared + +# Generate hashes for the included certs. +make rehash build-shared + +popd + +############################################################################### +# Win64 +############################################################################### +pushd build_win64 + +PERL=%{__perl} \ +./Configure \ + --prefix=%{mingw64_prefix} \ + --openssldir=%{mingw64_sysconfdir}/pki/tls \ + zlib enable-camellia enable-seed enable-tlsext enable-rfc3779 \ + enable-cms enable-md2 \ + no-mdc2 no-rc5 no-ec2m no-gost no-srp \ + no-fips no-hw \ + --cross-compile-prefix=%{mingw64_target}- \ + --enginesdir=%{mingw64_libdir}/openssl/engines \ + shared mingw64 + +# Regenerate def files as we disabled some algorithms above +perl util/mkdef.pl crypto ssl update + +make depend +make all build-shared + +# Generate hashes for the included certs. +make rehash build-shared + +popd + +# Clean up the .pc files +for i in build_win{32,64}/libcrypto.pc build_win{32,64}/libssl.pc build_win{32,64}/openssl.pc ; do + sed -i '/^Libs.private:/{s/-L[^ ]* //;s/-Wl[^ ]* //}' $i +done + + +%if %{run_tests} +%check +#---------------------------------------------------------------------- +# Run some tests. + +# We must revert patch33 before tests otherwise they will fail +patch -p1 -R < %{PATCH33} + +# This is a bit of a hack, but the test scripts look for 'openssl' +# by name. +pushd build_win32/apps +ln -s openssl.exe openssl +popd + +# This is useful for diagnosing Wine problems. +WINEDEBUG=+loaddll +export WINEDEBUG + +# Make sure we can find the installed DLLs. +WINEDLLPATH=%{mingw32_bindir} +export WINEDLLPATH + +# The tests run Wine and require an X server (but don't really use +# it). Therefore we create a virtual framebuffer for the duration of +# the tests. +# XXX There is no good way to choose a random, unused display. +# XXX Setting depth to 24 bits avoids bug 458219. +unset DISPLAY +display=:21 +Xvfb $display -screen 0 1024x768x24 -ac -noreset & xpid=$! +trap "kill -TERM $xpid ||:" EXIT +sleep 3 +DISPLAY=$display +export DISPLAY + +make LDCMD=%{mingw32_cc} -C build_win32/test apps tests + +# Disable this thread test, because we don't have pthread on Windows. +%{mingw32_cc} -o openssl-thread-test \ + -I./build_win32/include \ + %-{_mingw32_cflags} \ + %-{SOURCE8} \ + -L./build_win32 \ + -lssl -lcrypto \ + -lpthread -lz -ldl + +## `krb5-config --cflags` +## `krb5-config --libs` +# +./openssl-thread-test --threads %{thread_test_threads} + +#---------------------------------------------------------------------- +%endif + +# Add generation of HMAC checksum of the final stripped library +##define __spec_install_post \ +# #{?__debug_package:#{__debug_install_post}} \ +# #{__arch_install_post} \ +# #{__os_install_post} \ +# fips/fips_standalone_sha1 $RPM_BUILD_ROOT/#{_lib}/libcrypto.so.#{version} >$RPM_BUILD_ROOT/#{_lib}/.libcrypto.so.#{version}.hmac \ +# ln -sf .libcrypto.so.#{version}.hmac $RPM_BUILD_ROOT/#{_lib}/.libcrypto.so.#{soversion}.hmac \ +##{nil} + + +%install +mkdir -p $RPM_BUILD_ROOT%{mingw32_libdir}/openssl +mkdir -p $RPM_BUILD_ROOT%{mingw32_bindir} +mkdir -p $RPM_BUILD_ROOT%{mingw32_includedir} +mkdir -p $RPM_BUILD_ROOT%{mingw32_mandir} + +mkdir -p $RPM_BUILD_ROOT%{mingw64_libdir}/openssl +mkdir -p $RPM_BUILD_ROOT%{mingw64_bindir} +mkdir -p $RPM_BUILD_ROOT%{mingw64_includedir} +mkdir -p $RPM_BUILD_ROOT%{mingw64_mandir} + +%mingw_make_install INSTALL_PREFIX=$RPM_BUILD_ROOT build-shared + +# Install the file applink.c (#499934) +install -m644 build_win32/ms/applink.c $RPM_BUILD_ROOT%{mingw32_includedir}/openssl/applink.c +install -m644 build_win64/ms/applink.c $RPM_BUILD_ROOT%{mingw64_includedir}/openssl/applink.c + +# I have no idea why it installs the manpages in /etc, but +# we remove them anyway. +rm -r $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/tls/man +rm -r $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/tls/man + +# Set permissions on lib*.dll.a so that strip works. +chmod 0755 $RPM_BUILD_ROOT%{mingw32_libdir}/libcrypto.dll.a +chmod 0755 $RPM_BUILD_ROOT%{mingw32_libdir}/libssl.dll.a +chmod 0755 $RPM_BUILD_ROOT%{mingw64_libdir}/libcrypto.dll.a +chmod 0755 $RPM_BUILD_ROOT%{mingw64_libdir}/libssl.dll.a + +# Install a makefile for generating keys and self-signed certs, and a script +# for generating them on the fly. +mkdir -p $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/tls/certs +install -m644 %{SOURCE2} $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/tls/certs/Makefile +install -m755 %{SOURCE6} $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/tls/certs/make-dummy-cert +install -m755 %{SOURCE7} $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/tls/certs/renew-dummy-cert + +mkdir -p $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/tls/certs +install -m644 %{SOURCE2} $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/tls/certs/Makefile +install -m755 %{SOURCE6} $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/tls/certs/make-dummy-cert +install -m755 %{SOURCE7} $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/tls/certs/renew-dummy-cert + +# Pick a CA script. +pushd $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/tls/misc +mv CA.sh CA +popd + +pushd $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/tls/misc +mv CA.sh CA +popd + +mkdir -m700 $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/CA +mkdir -m700 $RPM_BUILD_ROOT%{mingw32_sysconfdir}/pki/CA/private + +mkdir -m700 $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/CA +mkdir -m700 $RPM_BUILD_ROOT%{mingw64_sysconfdir}/pki/CA/private + +# Exclude debug files from the main files (note: the debug files are only created after %%install, so we can't search for them directly) +find %{buildroot}%{mingw32_prefix} | grep -E '.(exe|dll|pyd)$' | sed 's|^%{buildroot}\(.*\)$|%%exclude \1.debug|' > mingw32-openssl.debugfiles +find %{buildroot}%{mingw64_prefix} | grep -E '.(exe|dll|pyd)$' | sed 's|^%{buildroot}\(.*\)$|%%exclude \1.debug|' > mingw64-openssl.debugfiles + + +# Win32 +%files -n mingw32-openssl -f mingw32-openssl.debugfiles +%doc build_win32/LICENSE +%{mingw32_bindir}/openssl.exe +%{mingw32_bindir}/c_rehash +%{mingw32_bindir}/libcrypto-%{soversion}.dll +%{mingw32_bindir}/libssl-%{soversion}.dll +%{mingw32_libdir}/libcrypto.dll.a +%{mingw32_libdir}/libssl.dll.a +%{mingw32_libdir}/engines +%{mingw32_libdir}/pkgconfig/*.pc +%{mingw32_includedir}/openssl +%config(noreplace) %{mingw32_sysconfdir}/pki + +%files -n mingw32-openssl-static +%{mingw32_libdir}/libcrypto.a +%{mingw32_libdir}/libssl.a + +# Win64 +%files -n mingw64-openssl -f mingw64-openssl.debugfiles +%doc build_win64/LICENSE +%{mingw64_bindir}/openssl.exe +%{mingw64_bindir}/c_rehash +%{mingw64_bindir}/libcrypto-%{soversion}.dll +%{mingw64_bindir}/libssl-%{soversion}.dll +%{mingw64_libdir}/libcrypto.dll.a +%{mingw64_libdir}/libssl.dll.a +%{mingw64_libdir}/engines +%{mingw64_libdir}/pkgconfig/*.pc +%{mingw64_includedir}/openssl +%config(noreplace) %{mingw64_sysconfdir}/pki + +%files -n mingw64-openssl-static +%{mingw64_libdir}/libcrypto.a +%{mingw64_libdir}/libssl.a + + +%changelog +* Thu Jun 11 2020 Uri Lublin - 1.0.2k-3 +- Rebuilt + Related: rhbz#1846152 + +* Mon Aug 19 2019 Victor Toso - 1.0.2k-2 +- Remove not applied patchs from the source list + Related: rhbz#1704077 + +* Fri Aug 24 2018 Christophe Fergeau - 1.0.2k-1 +- Sync with rhel 7.6 OpenSSL 1.0.2k+patches in order to get the latest security + fixes +- Related: rhbz#1615874 + +* Tue Aug 14 2018 Victor Toso - 1.0.2h-7 +- ExclusiveArch: i686, x86_64 +- Related: rhbz#1615874 + +* Thu May 31 2018 Richard W.M. Jones - 1.0.2h-6 +- Remove mktemp build dependency, part of coreutils. + +* Thu Feb 08 2018 Fedora Release Engineering - 1.0.2h-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Sep 09 2017 Sandro Mani - 1.0.2h-4 +- Exclude *.debug files from non-debug packages + +* Wed Jul 26 2017 Fedora Release Engineering - 1.0.2h-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 1.0.2h-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Sat May 7 2016 Erik van Pienbroek - 1.0.2h-1 +- Synced with native openssl-1.0.2h-1 +- Fixes RHBZ #1332591 #1332589 #1330104 #1312861 #1312857 #1307773 #1302768 + +* Sat Feb 6 2016 Erik van Pienbroek - 1.0.2f-1 +- Synced with native openssl-1.0.2f-2 +- Fixes RHBZ #1239685 #1290334 #1302768 + +* Thu Feb 04 2016 Fedora Release Engineering - 1.0.2a-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 1.0.2a-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Apr 24 2015 Erik van Pienbroek - 1.0.2a-1 +- Synced with native openssl-1.0.2a-1.fc23 +- Fixes various CVE's (RHBZ #1203855 #1203856) + +* Mon Dec 22 2014 Erik van Pienbroek - 1.0.1j-1 +- Synced with native openssl-1.0.1j-3.fc22 +- Add support for RFC 5649 +- Prevent compiler warning "Please include winsock2.h before windows.h" + when using the OpenSSL headers +- Fixes various CVE's (RHBZ #1127889 #1127709 #1152851) + +* Thu Aug 21 2014 Marc-André Lureau - 1.0.1i-1 +- Synced with native openssl-1.0.1i-3.fc21 +- Fixes various flaws (RHBZ#1096234 and RHBZ#1127705) + CVE-2014-3505 CVE-2014-3506 CVE-2014-3507 CVE-2014-3511 + CVE-2014-3510 CVE-2014-3508 CVE-2014-3509 CVE-2014-0221 + CVE-2014-0198 CVE-2014-0224 CVE-2014-0195 CVE-2010-5298 + CVE-2014-3470 + +* Sat Jun 07 2014 Fedora Release Engineering - 1.0.1e-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed Apr 9 2014 Erik van Pienbroek - 1.0.1e-6 +- Synced patches with native openssl-1.0.1e-44.fc21 +- Fixes CVE-2014-0160 (RHBZ #1085066) + +* Sat Jan 25 2014 Erik van Pienbroek - 1.0.1e-5 +- Synced patches with native openssl-1.0.1e-38.fc21 +- Enable ECC support (RHBZ #1037919) +- Fixes CVE-2013-6450 (RHBZ #1047844) +- Fixes CVE-2013-4353 (RHBZ #1049062) +- Fixes CVE-2013-6449 (RHBZ #1045444) + +* Sat Aug 03 2013 Fedora Release Engineering - 1.0.1e-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jul 10 2013 Erik van Pienbroek - 1.0.1e-3 +- Rebuild to resolve InterlockedCompareExchange regression in mingw32 libraries + +* Fri May 10 2013 Erik van Pienbroek - 1.0.1e-2 +- Fix build of manual pages with current pod2man (#959439) + +* Sun Mar 24 2013 Erik van Pienbroek - 1.0.1e-1 +- Update to 1.0.1e (RHBZ #920868) +- Synced patches with native openssl-1.0.1e-4.fc19 + +* Thu Feb 14 2013 Fedora Release Engineering - 1.0.1c-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Jan 11 2013 Erik van Pienbroek - 1.0.1c-2 +- Fix FTBFS against latest pod2man + +* Fri Nov 9 2012 Erik van Pienbroek - 1.0.1c-1 +- Update to 1.0.1c +- Synced patches with native openssl-1.0.1c-7.fc19 + +* Fri Jul 20 2012 Fedora Release Engineering - 1.0.0d-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sat Mar 10 2012 Erik van Pienbroek - 1.0.0d-6 +- Added win64 support + +* Wed Mar 07 2012 Kalev Lember - 1.0.0d-5 +- Pass the path to perl interpreter to Configure + +* Tue Mar 06 2012 Kalev Lember - 1.0.0d-4 +- Renamed the source package to mingw-openssl (#800443) +- Modernize the spec file +- Use mingw macros without leading underscore + +* Mon Feb 27 2012 Erik van Pienbroek - 1.0.0d-3 +- Rebuild against the mingw-w64 toolchain + +* Fri Jan 13 2012 Fedora Release Engineering - 1.0.0d-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Sat Apr 23 2011 Kalev Lember - 1.0.0d-1 +- Update to 1.0.0d +- Synced patches with Fedora native openssl-1.0.0d-2 + +* Fri Mar 04 2011 Kai Tietz +- Fixes for CVE-2011-0014 openssl: OCSP stapling vulnerability + +* Thu Mar 3 2011 Kai Tietz - 1.0.0a-3 +- Bump and rebuild. + +* Tue Feb 08 2011 Fedora Release Engineering - 1.0.0a-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Sat Jun 19 2010 Kalev Lember - 1.0.0a-1 +- Updated to openssl 1.0.0a +- Synced patches with Fedora native openssl-1.0.0a-1 +- Use sed to fix up cflags instead of unmaintainable patch +- Rebased mingw32 specific patches +- Disabled capieng to fix build +- Properly regenerate def files with mkdef.pl and drop linker-fix.patch + +* Thu Nov 26 2009 Kalev Lember - 1.0.0-0.6.beta4 +- Merged patches from native Fedora openssl (up to 1.0.0-0.16.beta4) +- Dropped the patch to fix non-fips mingw build, + as it's now merged into fips patch from native openssl + +* Sun Nov 22 2009 Kalev Lember - 1.0.0-0.5.beta4 +- Updated to version 1.0.0 beta 4 +- Merged patches from native Fedora openssl (up to 1.0.0-0.15.beta4) +- Added patch to fix build with fips disabled + +* Fri Sep 18 2009 Kalev Lember - 1.0.0-0.4.beta3 +- Rebuilt to fix debuginfo + +* Sun Aug 30 2009 Kalev Lember - 1.0.0-0.3.beta3 +- Simplified the lib renaming patch + +* Sun Aug 30 2009 Erik van Pienbroek - 1.0.0-0.2.beta3 +- Fixed invalid RPM Provides + +* Fri Aug 28 2009 Erik van Pienbroek - 1.0.0-0.1.beta3 +- Update to version 1.0.0 beta 3 +- Use %%global instead of %%define +- Automatically generate debuginfo subpackage +- Merged various changes from the native Fedora package (up to 1.0.0-0.5.beta3) +- Don't use the %%{_mingw32_make} macro anymore as it's ugly and causes side-effects +- Added missing BuildRequires mingw32-dlfcn (Kalev Lember) +- Reworked patches to rename *eay32.dll to lib*.dll (Kalev Lember) +- Patch Configure script to use %%{_mingw32_cflags} (Kalev Lember) + +* Sat Jul 25 2009 Fedora Release Engineering - 0.9.8j-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Sat May 9 2009 Erik van Pienbroek - 0.9.8j-6 +- Add the file include/openssl/applink.c to the package (BZ #499934) + +* Tue Apr 14 2009 Erik van Pienbroek - 0.9.8j-5 +- Fixed %%defattr line +- Added -static subpackage + +* Wed Feb 25 2009 Fedora Release Engineering - 0.9.8j-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Feb 20 2009 Richard W.M. Jones - 0.9.8j-3 +- Rebuild for mingw32-gcc 4.4 + +* Mon Feb 2 2009 Levente Farkas - 0.9.8j-2 +- Various build fixes. + +* Wed Jan 28 2009 Levente Farkas - 0.9.8j-1 +- update to new upstream version. + +* Mon Dec 29 2008 Levente Farkas - 0.9.8g-2 +- minor cleanup. + +* Tue Sep 30 2008 Richard W.M. Jones - 0.9.8g-1 +- Initial RPM release. diff --git a/mingw32-openssl-1.0.0-beta3-libversion.patch b/mingw32-openssl-1.0.0-beta3-libversion.patch new file mode 100644 index 0000000..d4d9996 --- /dev/null +++ b/mingw32-openssl-1.0.0-beta3-libversion.patch @@ -0,0 +1,50 @@ +diff -up openssl-1.0.0-beta3/Makefile.org.mingw-libversion openssl-1.0.0-beta3/Makefile.org +--- openssl-1.0.0-beta3/Makefile.org.mingw-libversion 2009-08-29 22:44:10.000000000 +0300 ++++ openssl-1.0.0-beta3/Makefile.org 2009-08-29 22:45:42.000000000 +0300 +@@ -542,8 +542,8 @@ install_sw: + fi ); \ + if expr $(PLATFORM) : 'mingw' > /dev/null; then \ + ( case $$i in \ +- *crypto*) i=libeay32.dll;; \ +- *ssl*) i=ssleay32.dll;; \ ++ *crypto*) i=libcrypto-$(SHLIB_SONAMEVER).dll;; \ ++ *ssl*) i=libssl-$(SHLIB_SONAMEVER).dll;; \ + esac; \ + echo installing $$i; \ + cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \ +diff -up openssl-1.0.0-beta3/Makefile.shared.mingw-libversion openssl-1.0.0-beta3/Makefile.shared +--- openssl-1.0.0-beta3/Makefile.shared.mingw-libversion 2009-08-29 22:33:22.000000000 +0300 ++++ openssl-1.0.0-beta3/Makefile.shared 2009-08-29 22:33:22.000000000 +0300 +@@ -47,7 +47,7 @@ LIBEXTRAS= + # LIBVERSION contains the current version of the library. + # For example, to build libfoo.so.1.2, you need to do the following: + #LIBVERSION=1.2 +-LIBVERSION= ++LIBVERSION=10 + + # LIBCOMPATVERSIONS contains the compatibility versions (a list) of + # the library. They MUST be in decreasing order. +@@ -250,7 +250,7 @@ link_o.cygwin: + base=-Wl,--enable-auto-image-base; \ + deffile=; \ + if expr $(PLATFORM) : 'mingw' > /dev/null; then \ +- SHLIB=$(LIBNAME)eay32; base=; \ ++ SHLIB=lib$(LIBNAME); base=; \ + if test -f $(LIBNAME)eay32.def; then \ + deffile=$(LIBNAME)eay32.def; \ + fi; \ +@@ -282,13 +282,7 @@ + dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; extras=; \ + base=-Wl,--enable-auto-image-base; \ + if expr $(PLATFORM) : 'mingw' > /dev/null; then \ +- case $(LIBNAME) in \ +- crypto) SHLIB=libeay;; \ +- ssl) SHLIB=ssleay;; \ +- esac; \ +- SHLIB_SOVER=32; \ +- extras="$(LIBNAME).def"; \ +- $(PERL) util/mkdef.pl 32 $$SHLIB > $$extras; \ ++ SHLIB=lib$(LIBNAME); \ + base=; [ $(LIBNAME) = "crypto" -a -n "$(FIPSCANLIB)" ] && base=-Wl,--image-base,0x63000000; \ + fi; \ + dll_name=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \ diff --git a/mingw32-openssl-1.0.2a-sfx.patch b/mingw32-openssl-1.0.2a-sfx.patch new file mode 100644 index 0000000..8020d57 --- /dev/null +++ b/mingw32-openssl-1.0.2a-sfx.patch @@ -0,0 +1,14 @@ +--- openssl-1.0.2a/engines/Makefile.enginesdir 2015-03-19 14:31:14.000000000 +0100 ++++ openssl-1.0.2a/engines/Makefile 2015-04-24 18:27:12.875788913 +0200 +@@ -111,7 +111,10 @@ + for l in $(LIBNAMES); do \ + ( echo installing $$l; \ + pfx=lib; \ +- if expr "$(PLATFORM)" : "Cygwin" >/dev/null; then \ ++ if [ "$(PLATFORM)" = "mingw" ]; then \ ++ sfx=.dll; \ ++ cp $$pfx$$l$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/$$pfx$$l$$sfx.new; \ ++ elif expr "$(PLATFORM)" : "Cygwin" >/dev/null; then \ + sfx=".so"; \ + cp cyg$$l.dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \ + else \ diff --git a/openssl-1.0.0-beta4-ca-dir.patch b/openssl-1.0.0-beta4-ca-dir.patch new file mode 100644 index 0000000..751cabd --- /dev/null +++ b/openssl-1.0.0-beta4-ca-dir.patch @@ -0,0 +1,36 @@ +diff -up openssl-1.0.0-beta4/apps/CA.pl.in.ca-dir openssl-1.0.0-beta4/apps/CA.pl.in +--- openssl-1.0.0-beta4/apps/CA.pl.in.ca-dir 2006-04-28 02:30:49.000000000 +0200 ++++ openssl-1.0.0-beta4/apps/CA.pl.in 2009-11-12 12:33:13.000000000 +0100 +@@ -53,7 +53,7 @@ $VERIFY="$openssl verify"; + $X509="$openssl x509"; + $PKCS12="$openssl pkcs12"; + +-$CATOP="./demoCA"; ++$CATOP="/etc/pki/CA"; + $CAKEY="cakey.pem"; + $CAREQ="careq.pem"; + $CACERT="cacert.pem"; +diff -up openssl-1.0.0-beta4/apps/CA.sh.ca-dir openssl-1.0.0-beta4/apps/CA.sh +--- openssl-1.0.0-beta4/apps/CA.sh.ca-dir 2009-10-15 19:27:47.000000000 +0200 ++++ openssl-1.0.0-beta4/apps/CA.sh 2009-11-12 12:35:14.000000000 +0100 +@@ -68,7 +68,7 @@ VERIFY="$OPENSSL verify" + X509="$OPENSSL x509" + PKCS12="openssl pkcs12" + +-if [ -z "$CATOP" ] ; then CATOP=./demoCA ; fi ++if [ -z "$CATOP" ] ; then CATOP=/etc/pki/CA ; fi + CAKEY=./cakey.pem + CAREQ=./careq.pem + CACERT=./cacert.pem +diff -up openssl-1.0.0-beta4/apps/openssl.cnf.ca-dir openssl-1.0.0-beta4/apps/openssl.cnf +--- openssl-1.0.0-beta4/apps/openssl.cnf.ca-dir 2009-11-12 12:33:13.000000000 +0100 ++++ openssl-1.0.0-beta4/apps/openssl.cnf 2009-11-12 12:33:13.000000000 +0100 +@@ -39,7 +39,7 @@ default_ca = CA_default # The default c + #################################################################### + [ CA_default ] + +-dir = ./demoCA # Where everything is kept ++dir = /etc/pki/CA # Where everything is kept + certs = $dir/certs # Where the issued certs are kept + crl_dir = $dir/crl # Where the issued crl are kept + database = $dir/index.txt # database index file. diff --git a/openssl-1.0.0-timezone.patch b/openssl-1.0.0-timezone.patch new file mode 100644 index 0000000..b1d6682 --- /dev/null +++ b/openssl-1.0.0-timezone.patch @@ -0,0 +1,21 @@ +diff -up openssl-1.0.0/Makefile.org.timezone openssl-1.0.0/Makefile.org +--- openssl-1.0.0/Makefile.org.timezone 2010-03-30 11:08:40.000000000 +0200 ++++ openssl-1.0.0/Makefile.org 2010-04-06 12:49:21.000000000 +0200 +@@ -609,7 +609,7 @@ install_docs: + sec=`$(PERL) util/extract-section.pl 1 < $$i`; \ + echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \ + (cd `$(PERL) util/dirname.pl $$i`; \ +- sh -c "$$pod2man \ ++ sh -c "TZ=UTC $$pod2man \ + --section=$$sec --center=OpenSSL \ + --release=$(VERSION) `basename $$i`") \ + > $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \ +@@ -626,7 +626,7 @@ install_docs: + sec=`$(PERL) util/extract-section.pl 3 < $$i`; \ + echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \ + (cd `$(PERL) util/dirname.pl $$i`; \ +- sh -c "$$pod2man \ ++ sh -c "TZ=UTC $$pod2man \ + --section=$$sec --center=OpenSSL \ + --release=$(VERSION) `basename $$i`") \ + > $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \ diff --git a/openssl-1.0.1c-aliasing.patch b/openssl-1.0.1c-aliasing.patch new file mode 100644 index 0000000..582418c --- /dev/null +++ b/openssl-1.0.1c-aliasing.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1c/crypto/modes/Makefile.aliasing openssl-1.0.1c/crypto/modes/Makefile +--- openssl-1.0.1c/crypto/modes/Makefile.aliasing 2011-08-12 00:36:17.000000000 +0200 ++++ openssl-1.0.1c/crypto/modes/Makefile 2012-07-13 11:32:10.767829077 +0200 +@@ -12,7 +12,7 @@ AR= ar r + + MODES_ASM_OBJ= + +-CFLAGS= $(INCLUDES) $(CFLAG) ++CFLAGS= $(INCLUDES) $(CFLAG) -fno-strict-aliasing + ASFLAGS= $(INCLUDES) $(ASFLAG) + AFLAGS= $(ASFLAGS) + diff --git a/openssl-1.0.1c-perlfind.patch b/openssl-1.0.1c-perlfind.patch new file mode 100644 index 0000000..956afd6 --- /dev/null +++ b/openssl-1.0.1c-perlfind.patch @@ -0,0 +1,16 @@ +diff -up openssl-1.0.1c/util/perlpath.pl.perlfind openssl-1.0.1c/util/perlpath.pl +--- openssl-1.0.1c/util/perlpath.pl.perlfind 2012-07-11 22:57:33.000000000 +0200 ++++ openssl-1.0.1c/util/perlpath.pl 2012-07-12 00:31:12.102156275 +0200 +@@ -4,10 +4,10 @@ + # line in all scripts that rely on perl. + # + +-require "find.pl"; ++use File::Find; + + $#ARGV == 0 || print STDERR "usage: perlpath newpath (eg /usr/bin)\n"; +-&find("."); ++find(\&wanted, "."); + + sub wanted + { diff --git a/openssl-1.0.1i-algo-doc.patch b/openssl-1.0.1i-algo-doc.patch new file mode 100644 index 0000000..a19877d --- /dev/null +++ b/openssl-1.0.1i-algo-doc.patch @@ -0,0 +1,77 @@ +diff -up openssl-1.0.1i/doc/crypto/EVP_DigestInit.pod.algo-doc openssl-1.0.1i/doc/crypto/EVP_DigestInit.pod +--- openssl-1.0.1i/doc/crypto/EVP_DigestInit.pod.algo-doc 2014-08-06 23:10:56.000000000 +0200 ++++ openssl-1.0.1i/doc/crypto/EVP_DigestInit.pod 2014-08-07 11:18:01.290773970 +0200 +@@ -75,7 +75,7 @@ EVP_MD_CTX_create() allocates, initializ + + EVP_DigestInit_ex() sets up digest context B to use a digest + B from ENGINE B. B must be initialized before calling this +-function. B will typically be supplied by a functionsuch as EVP_sha1(). ++function. B will typically be supplied by a function such as EVP_sha1(). + If B is NULL then the default implementation of digest B is used. + + EVP_DigestUpdate() hashes B bytes of data at B into the +@@ -164,7 +164,8 @@ corresponding OBJECT IDENTIFIER or NID_u + EVP_MD_size(), EVP_MD_block_size(), EVP_MD_CTX_size() and + EVP_MD_CTX_block_size() return the digest or block size in bytes. + +-EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_dss(), ++EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), ++EVP_sha224(), EVP_sha256(), EVP_sha384(), EVP_sha512(), EVP_dss(), + EVP_dss1(), EVP_mdc2() and EVP_ripemd160() return pointers to the + corresponding EVP_MD structures. + +diff -up openssl-1.0.1i/doc/crypto/EVP_EncryptInit.pod.algo-doc openssl-1.0.1i/doc/crypto/EVP_EncryptInit.pod +--- openssl-1.0.1i/doc/crypto/EVP_EncryptInit.pod.algo-doc 2014-08-06 23:10:56.000000000 +0200 ++++ openssl-1.0.1i/doc/crypto/EVP_EncryptInit.pod 2014-08-07 10:55:25.100638252 +0200 +@@ -91,6 +91,32 @@ EVP_CIPHER_CTX_set_padding - EVP cipher + int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + ++ const EVP_CIPHER *EVP_des_ede3(void); ++ const EVP_CIPHER *EVP_des_ede3_ecb(void); ++ const EVP_CIPHER *EVP_des_ede3_cfb64(void); ++ const EVP_CIPHER *EVP_des_ede3_cfb1(void); ++ const EVP_CIPHER *EVP_des_ede3_cfb8(void); ++ const EVP_CIPHER *EVP_des_ede3_ofb(void); ++ const EVP_CIPHER *EVP_des_ede3_cbc(void); ++ const EVP_CIPHER *EVP_aes_128_ecb(void); ++ const EVP_CIPHER *EVP_aes_128_cbc(void); ++ const EVP_CIPHER *EVP_aes_128_cfb1(void); ++ const EVP_CIPHER *EVP_aes_128_cfb8(void); ++ const EVP_CIPHER *EVP_aes_128_cfb128(void); ++ const EVP_CIPHER *EVP_aes_128_ofb(void); ++ const EVP_CIPHER *EVP_aes_192_ecb(void); ++ const EVP_CIPHER *EVP_aes_192_cbc(void); ++ const EVP_CIPHER *EVP_aes_192_cfb1(void); ++ const EVP_CIPHER *EVP_aes_192_cfb8(void); ++ const EVP_CIPHER *EVP_aes_192_cfb128(void); ++ const EVP_CIPHER *EVP_aes_192_ofb(void); ++ const EVP_CIPHER *EVP_aes_256_ecb(void); ++ const EVP_CIPHER *EVP_aes_256_cbc(void); ++ const EVP_CIPHER *EVP_aes_256_cfb1(void); ++ const EVP_CIPHER *EVP_aes_256_cfb8(void); ++ const EVP_CIPHER *EVP_aes_256_cfb128(void); ++ const EVP_CIPHER *EVP_aes_256_ofb(void); ++ + =head1 DESCRIPTION + + The EVP cipher routines are a high level interface to certain +@@ -297,6 +323,18 @@ Three key triple DES in CBC, ECB, CFB an + + DESX algorithm in CBC mode. + ++=item EVP_aes_128_cbc(void), EVP_aes_128_ecb(), EVP_aes_128_ofb(void), EVP_aes_128_cfb1(void), EVP_aes_128_cfb8(void), EVP_aes_128_cfb128(void) ++ ++AES with 128 bit key length in CBC, ECB, OFB and CFB modes respectively. ++ ++=item EVP_aes_192_cbc(void), EVP_aes_192_ecb(), EVP_aes_192_ofb(void), EVP_aes_192_cfb1(void), EVP_aes_192_cfb8(void), EVP_aes_192_cfb128(void) ++ ++AES with 192 bit key length in CBC, ECB, OFB and CFB modes respectively. ++ ++=item EVP_aes_256_cbc(void), EVP_aes_256_ecb(), EVP_aes_256_ofb(void), EVP_aes_256_cfb1(void), EVP_aes_256_cfb8(void), EVP_aes_256_cfb128(void) ++ ++AES with 256 bit key length in CBC, ECB, OFB and CFB modes respectively. ++ + =item EVP_rc4(void) + + RC4 stream cipher. This is a variable key length cipher with default key length 128 bits. diff --git a/openssl-1.0.2a-apps-dgst.patch b/openssl-1.0.2a-apps-dgst.patch new file mode 100644 index 0000000..2bb8327 --- /dev/null +++ b/openssl-1.0.2a-apps-dgst.patch @@ -0,0 +1,110 @@ +diff -up openssl-1.0.2a/apps/ca.c.dgst openssl-1.0.2a/apps/ca.c +--- openssl-1.0.2a/apps/ca.c.dgst 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/apps/ca.c 2015-04-21 17:01:38.841551616 +0200 +@@ -157,7 +157,7 @@ static const char *ca_usage[] = { + " -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n", + " -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n", + " -days arg - number of days to certify the certificate for\n", +- " -md arg - md to use, one of md2, md5, sha or sha1\n", ++ " -md arg - md to use, see openssl dgst -h for list\n", + " -policy arg - The CA 'policy' to support\n", + " -keyfile arg - private key file\n", + " -keyform arg - private key file format (PEM or ENGINE)\n", +diff -up openssl-1.0.2a/apps/enc.c.dgst openssl-1.0.2a/apps/enc.c +--- openssl-1.0.2a/apps/enc.c.dgst 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/apps/enc.c 2015-04-21 17:01:38.841551616 +0200 +@@ -294,7 +294,7 @@ int MAIN(int argc, char **argv) + "%-14s the next argument is the md to use to create a key\n", + "-md"); + BIO_printf(bio_err, +- "%-14s from a passphrase. One of md2, md5, sha or sha1\n", ++ "%-14s from a passphrase. See openssl dgst -h for list.\n", + ""); + BIO_printf(bio_err, "%-14s salt in hex is the next argument\n", + "-S"); +diff -up openssl-1.0.2a/apps/req.c.dgst openssl-1.0.2a/apps/req.c +--- openssl-1.0.2a/apps/req.c.dgst 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/apps/req.c 2015-04-21 17:01:38.842551640 +0200 +@@ -414,7 +414,7 @@ int MAIN(int argc, char **argv) + " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n"); + #endif + BIO_printf(bio_err, +- " -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n"); ++ " -[digest] Digest to sign with (see openssl dgst -h for list)\n"); + BIO_printf(bio_err, " -config file request template file.\n"); + BIO_printf(bio_err, + " -subj arg set or modify request subject\n"); +diff -up openssl-1.0.2a/apps/ts.c.dgst openssl-1.0.2a/apps/ts.c +--- openssl-1.0.2a/apps/ts.c.dgst 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/apps/ts.c 2015-04-21 17:01:38.842551640 +0200 +@@ -337,7 +337,7 @@ int MAIN(int argc, char **argv) + BIO_printf(bio_err, "usage:\n" + "ts -query [-rand file%cfile%c...] [-config configfile] " + "[-data file_to_hash] [-digest digest_bytes]" +- "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] " ++ "[-] " + "[-policy object_id] [-no_nonce] [-cert] " + "[-in request.tsq] [-out request.tsq] [-text]\n", + LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); +diff -up openssl-1.0.2a/apps/x509.c.dgst openssl-1.0.2a/apps/x509.c +--- openssl-1.0.2a/apps/x509.c.dgst 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/apps/x509.c 2015-04-21 17:01:38.842551640 +0200 +@@ -141,7 +141,7 @@ static const char *x509_usage[] = { + " -set_serial - serial number to use\n", + " -text - print the certificate in text form\n", + " -C - print out C code forms\n", +- " -md2/-md5/-sha1/-mdc2 - digest to use\n", ++ " - - digest to use, see openssl dgst -h output for list\n", + " -extfile - configuration file with X509V3 extensions to add\n", + " -extensions - section from config file with X509V3 extensions to add\n", + " -clrext - delete extensions before signing and input certificate\n", +diff -up openssl-1.0.2a/doc/apps/ca.pod.dgst openssl-1.0.2a/doc/apps/ca.pod +--- openssl-1.0.2a/doc/apps/ca.pod.dgst 2015-01-20 13:33:36.000000000 +0100 ++++ openssl-1.0.2a/doc/apps/ca.pod 2015-04-21 17:01:38.842551640 +0200 +@@ -168,7 +168,8 @@ the number of days to certify the certif + =item B<-md alg> + + the message digest to use. Possible values include md5, sha1 and mdc2. +-This option also applies to CRLs. ++For full list of digests see openssl dgst -h output. This option also ++applies to CRLs. + + =item B<-policy arg> + +diff -up openssl-1.0.2a/doc/apps/ocsp.pod.dgst openssl-1.0.2a/doc/apps/ocsp.pod +--- openssl-1.0.2a/doc/apps/ocsp.pod.dgst 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/doc/apps/ocsp.pod 2015-04-21 17:01:38.842551640 +0200 +@@ -219,7 +219,8 @@ check is not performed. + =item B<-md5|-sha1|-sha256|-ripemod160|...> + + this option sets digest algorithm to use for certificate identification +-in the OCSP request. By default SHA-1 is used. ++in the OCSP request. By default SHA-1 is used. See openssl dgst -h output for ++the list of available algorithms. + + =back + +diff -up openssl-1.0.2a/doc/apps/req.pod.dgst openssl-1.0.2a/doc/apps/req.pod +--- openssl-1.0.2a/doc/apps/req.pod.dgst 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/doc/apps/req.pod 2015-04-21 17:01:38.843551664 +0200 +@@ -201,7 +201,8 @@ will not be encrypted. + + this specifies the message digest to sign the request with (such as + B<-md5>, B<-sha1>). This overrides the digest algorithm specified in +-the configuration file. ++the configuration file. For full list of possible digests see openssl ++dgst -h output. + + Some public key algorithms may override this choice. For instance, DSA + signatures always use SHA1, GOST R 34.10 signatures always use +diff -up openssl-1.0.2a/doc/apps/x509.pod.dgst openssl-1.0.2a/doc/apps/x509.pod +--- openssl-1.0.2a/doc/apps/x509.pod.dgst 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/doc/apps/x509.pod 2015-04-21 17:01:38.843551664 +0200 +@@ -107,6 +107,7 @@ the digest to use. This affects any sign + digest, such as the B<-fingerprint>, B<-signkey> and B<-CA> options. If not + specified then SHA1 is used. If the key being used to sign with is a DSA key + then this option has no effect: SHA1 is always used with DSA keys. ++For full list of digests see openssl dgst -h output. + + =item B<-engine id> + diff --git a/openssl-1.0.2a-compat-symbols.patch b/openssl-1.0.2a-compat-symbols.patch new file mode 100644 index 0000000..1e0993e --- /dev/null +++ b/openssl-1.0.2a-compat-symbols.patch @@ -0,0 +1,46 @@ +diff -up openssl-1.0.2a/crypto/dsa/dsa_key.c.compat openssl-1.0.2a/crypto/dsa/dsa_key.c +--- openssl-1.0.2a/crypto/dsa/dsa_key.c.compat 2015-04-09 18:21:11.687977858 +0200 ++++ openssl-1.0.2a/crypto/dsa/dsa_key.c 2015-04-09 18:21:07.869889659 +0200 +@@ -68,6 +68,11 @@ + # include + # include + ++/* just a compatibility symbol - no-op */ ++void FIPS_corrupt_dsa_keygen(void) ++{ ++} ++ + static int fips_check_dsa(DSA *dsa) + { + EVP_PKEY *pk; +diff -up openssl-1.0.2a/crypto/engine/eng_all.c.compat openssl-1.0.2a/crypto/engine/eng_all.c +--- openssl-1.0.2a/crypto/engine/eng_all.c.compat 2015-04-09 18:21:11.688977881 +0200 ++++ openssl-1.0.2a/crypto/engine/eng_all.c 2015-04-09 18:21:09.159919459 +0200 +@@ -63,6 +63,11 @@ + # include + #endif + ++/* just backwards compatibility symbol - no-op */ ++void ENGINE_load_aesni(void) ++{ ++} ++ + void ENGINE_load_builtin_engines(void) + { + /* Some ENGINEs need this */ +diff -up openssl-1.0.2a/crypto/fips/fips.c.compat openssl-1.0.2a/crypto/fips/fips.c +--- openssl-1.0.2a/crypto/fips/fips.c.compat 2015-04-09 18:21:11.689977904 +0200 ++++ openssl-1.0.2a/crypto/fips/fips.c 2015-04-09 18:21:09.925937154 +0200 +@@ -113,6 +113,12 @@ int FIPS_module_mode(void) + return ret; + } + ++/* just a compat symbol - return NULL */ ++const void *FIPS_rand_check(void) ++{ ++ return NULL; ++} ++ + int FIPS_selftest_failed(void) + { + int ret = 0; diff --git a/openssl-1.0.2a-defaults.patch b/openssl-1.0.2a-defaults.patch new file mode 100644 index 0000000..315a9b0 --- /dev/null +++ b/openssl-1.0.2a-defaults.patch @@ -0,0 +1,60 @@ +diff -up openssl-1.0.2a/apps/openssl.cnf.defaults openssl-1.0.2a/apps/openssl.cnf +--- openssl-1.0.2a/apps/openssl.cnf.defaults 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/apps/openssl.cnf 2015-04-20 14:37:10.112271850 +0200 +@@ -72,7 +72,7 @@ cert_opt = ca_default # Certificate fi + + default_days = 365 # how long to certify for + default_crl_days= 30 # how long before next CRL +-default_md = default # use public key default MD ++default_md = sha256 # use SHA-256 by default + preserve = no # keep passed DN ordering + + # A few difference way of specifying how similar the request should look +@@ -104,6 +104,7 @@ emailAddress = optional + #################################################################### + [ req ] + default_bits = 2048 ++default_md = sha256 + default_keyfile = privkey.pem + distinguished_name = req_distinguished_name + attributes = req_attributes +@@ -126,17 +127,18 @@ string_mask = utf8only + + [ req_distinguished_name ] + countryName = Country Name (2 letter code) +-countryName_default = AU ++countryName_default = XX + countryName_min = 2 + countryName_max = 2 + + stateOrProvinceName = State or Province Name (full name) +-stateOrProvinceName_default = Some-State ++#stateOrProvinceName_default = Default Province + + localityName = Locality Name (eg, city) ++localityName_default = Default City + + 0.organizationName = Organization Name (eg, company) +-0.organizationName_default = Internet Widgits Pty Ltd ++0.organizationName_default = Default Company Ltd + + # we can do this but it is not needed normally :-) + #1.organizationName = Second Organization Name (eg, company) +@@ -145,7 +147,7 @@ localityName = Locality Name (eg, city + organizationalUnitName = Organizational Unit Name (eg, section) + #organizationalUnitName_default = + +-commonName = Common Name (e.g. server FQDN or YOUR name) ++commonName = Common Name (eg, your name or your server\'s hostname) + commonName_max = 64 + + emailAddress = Email Address +@@ -339,7 +341,7 @@ signer_key = $dir/private/tsakey.pem # T + default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) + other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +-digests = md5, sha1 # Acceptable message digests (mandatory) ++digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) + accuracy = secs:1, millisecs:500, microsecs:100 # (optional) + clock_precision_digits = 0 # number of digits after dot. (optional) + ordering = yes # Is ordering defined for timestamps? diff --git a/openssl-1.0.2a-dtls1-abi.patch b/openssl-1.0.2a-dtls1-abi.patch new file mode 100644 index 0000000..a6a79d7 --- /dev/null +++ b/openssl-1.0.2a-dtls1-abi.patch @@ -0,0 +1,23 @@ +diff -up openssl-1.0.2a/ssl/dtls1.h.dtls1-abi openssl-1.0.2a/ssl/dtls1.h +--- openssl-1.0.2a/ssl/dtls1.h.dtls1-abi 2015-04-21 10:49:57.984781143 +0200 ++++ openssl-1.0.2a/ssl/dtls1.h 2015-04-21 16:41:37.835164264 +0200 +@@ -214,9 +214,6 @@ typedef struct dtls1_state_st { + * loss. + */ + record_pqueue buffered_app_data; +- /* Is set when listening for new connections with dtls1_listen() */ +- unsigned int listen; +- unsigned int link_mtu; /* max on-the-wire DTLS packet size */ + unsigned int mtu; /* max DTLS packet size */ + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; +@@ -241,6 +238,9 @@ typedef struct dtls1_state_st { + * Cleared after the message has been processed. + */ + unsigned int change_cipher_spec_ok; ++ /* Is set when listening for new connections with dtls1_listen() */ ++ unsigned int listen; ++ unsigned int link_mtu; /* max on-the-wire DTLS packet size */ + # ifndef OPENSSL_NO_SCTP + /* used when SSL_ST_XX_FLUSH is entered */ + int next_state; diff --git a/openssl-1.0.2a-env-zlib.patch b/openssl-1.0.2a-env-zlib.patch new file mode 100644 index 0000000..328079b --- /dev/null +++ b/openssl-1.0.2a-env-zlib.patch @@ -0,0 +1,39 @@ +diff -up openssl-1.0.2a/doc/ssl/SSL_COMP_add_compression_method.pod.env-zlib openssl-1.0.2a/doc/ssl/SSL_COMP_add_compression_method.pod +--- openssl-1.0.2a/doc/ssl/SSL_COMP_add_compression_method.pod.env-zlib 2015-04-09 18:17:20.509637597 +0200 ++++ openssl-1.0.2a/doc/ssl/SSL_COMP_add_compression_method.pod 2015-04-09 18:17:14.767504953 +0200 +@@ -47,6 +47,13 @@ Once the identities of the compression m + been standardized, the compression API will most likely be changed. Using + it in the current state is not recommended. + ++It is also not recommended to use compression if data transfered contain ++untrusted parts that can be manipulated by an attacker as he could then ++get information about the encrypted data. See the CRIME attack. For ++that reason the default loading of the zlib compression method is ++disabled and enabled only if the environment variable B ++is present during the library initialization. ++ + =head1 RETURN VALUES + + SSL_COMP_add_compression_method() may return the following values: +diff -up openssl-1.0.2a/ssl/ssl_ciph.c.env-zlib openssl-1.0.2a/ssl/ssl_ciph.c +--- openssl-1.0.2a/ssl/ssl_ciph.c.env-zlib 2015-04-09 18:17:20.510637620 +0200 ++++ openssl-1.0.2a/ssl/ssl_ciph.c 2015-04-09 18:17:20.264631937 +0200 +@@ -140,6 +140,8 @@ + * OTHERWISE. + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #ifndef OPENSSL_NO_COMP +@@ -450,7 +452,8 @@ static void load_builtin_compressions(vo + + MemCheck_off(); + ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp); +- if (ssl_comp_methods != NULL) { ++ if (ssl_comp_methods != NULL ++ && secure_getenv("OPENSSL_DEFAULT_ZLIB") != NULL) { + comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp != NULL) { + comp->method = COMP_zlib(); diff --git a/openssl-1.0.2a-fips-md5-allow.patch b/openssl-1.0.2a-fips-md5-allow.patch new file mode 100644 index 0000000..825417f --- /dev/null +++ b/openssl-1.0.2a-fips-md5-allow.patch @@ -0,0 +1,21 @@ +diff -up openssl-1.0.2a/crypto/md5/md5_dgst.c.md5-allow openssl-1.0.2a/crypto/md5/md5_dgst.c +--- openssl-1.0.2a/crypto/md5/md5_dgst.c.md5-allow 2015-04-09 18:18:36.505393113 +0200 ++++ openssl-1.0.2a/crypto/md5/md5_dgst.c 2015-04-09 18:18:32.408298469 +0200 +@@ -72,7 +72,16 @@ const char MD5_version[] = "MD5" OPENSSL + #define INIT_DATA_C (unsigned long)0x98badcfeL + #define INIT_DATA_D (unsigned long)0x10325476L + +-nonfips_md_init(MD5) ++int MD5_Init(MD5_CTX *c) ++#ifdef OPENSSL_FIPS ++{ ++ if (FIPS_mode() && getenv("OPENSSL_FIPS_NON_APPROVED_MD5_ALLOW") == NULL) ++ OpenSSLDie(__FILE__, __LINE__, "Digest MD5 forbidden in FIPS mode!"); ++ return private_MD5_Init(c); ++} ++ ++int private_MD5_Init(MD5_CTX *c) ++#endif + { + memset(c, 0, sizeof(*c)); + c->A = INIT_DATA_A; diff --git a/openssl-1.0.2a-issuer-hash.patch b/openssl-1.0.2a-issuer-hash.patch new file mode 100644 index 0000000..a439d14 --- /dev/null +++ b/openssl-1.0.2a-issuer-hash.patch @@ -0,0 +1,11 @@ +diff -up openssl-1.0.1k/crypto/x509/x509_cmp.c.issuer-hash openssl-1.0.1k/crypto/x509/x509_cmp.c +--- openssl-1.0.1k/crypto/x509/x509_cmp.c.issuer-hash 2015-04-09 18:16:03.349855193 +0200 ++++ openssl-1.0.1k/crypto/x509/x509_cmp.c 2015-04-09 18:16:00.616792058 +0200 +@@ -86,6 +86,7 @@ unsigned long X509_issuer_and_serial_has + char *f; + + EVP_MD_CTX_init(&ctx); ++ EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0); + if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) + goto err; diff --git a/openssl-1.0.2a-no-rpath.patch b/openssl-1.0.2a-no-rpath.patch new file mode 100644 index 0000000..4aafefd --- /dev/null +++ b/openssl-1.0.2a-no-rpath.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.2a/Makefile.shared.no-rpath openssl-1.0.2a/Makefile.shared +--- openssl-1.0.2a/Makefile.shared.no-rpath 2015-04-09 18:14:39.647921663 +0200 ++++ openssl-1.0.2a/Makefile.shared 2015-04-09 18:14:34.423800985 +0200 +@@ -153,7 +153,7 @@ DO_GNU_SO=$(CALC_VERSIONS); \ + NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ + SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX" + +-DO_GNU_APP=LDFLAGS="$(CFLAGS) -Wl,-rpath,$(LIBRPATH)" ++DO_GNU_APP=LDFLAGS="$(CFLAGS)" + + #This is rather special. It's a special target with which one can link + #applications without bothering with any features that have anything to diff --git a/openssl-1.0.2a-padlock64.patch b/openssl-1.0.2a-padlock64.patch new file mode 100644 index 0000000..19d3958 --- /dev/null +++ b/openssl-1.0.2a-padlock64.patch @@ -0,0 +1,198 @@ +diff -up openssl-1.0.2a/engines/e_padlock.c.padlock64 openssl-1.0.2a/engines/e_padlock.c +--- openssl-1.0.2a/engines/e_padlock.c.padlock64 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/engines/e_padlock.c 2015-04-22 16:23:44.105617468 +0200 +@@ -101,7 +101,10 @@ + */ + # undef COMPILE_HW_PADLOCK + # if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM) +-# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \ ++# if (defined(__GNUC__) && __GNUC__>=2 && \ ++ (defined(__i386__) || defined(__i386) || \ ++ defined(__x86_64__) || defined(__x86_64)) \ ++ ) || \ + (defined(_MSC_VER) && defined(_M_IX86)) + # define COMPILE_HW_PADLOCK + # endif +@@ -140,7 +143,7 @@ void ENGINE_load_padlock(void) + # endif + # elif defined(__GNUC__) + # ifndef alloca +-# define alloca(s) __builtin_alloca(s) ++# define alloca(s) __builtin_alloca((s)) + # endif + # endif + +@@ -303,6 +306,7 @@ static volatile struct padlock_cipher_da + * ======================================================= + */ + # if defined(__GNUC__) && __GNUC__>=2 ++# if defined(__i386__) || defined(__i386) + /* + * As for excessive "push %ebx"/"pop %ebx" found all over. + * When generating position-independent code GCC won't let +@@ -379,22 +383,6 @@ static int padlock_available(void) + return padlock_use_ace + padlock_use_rng; + } + +-# ifndef OPENSSL_NO_AES +-# ifndef AES_ASM +-/* Our own htonl()/ntohl() */ +-static inline void padlock_bswapl(AES_KEY *ks) +-{ +- size_t i = sizeof(ks->rd_key) / sizeof(ks->rd_key[0]); +- unsigned int *key = ks->rd_key; +- +- while (i--) { +- asm volatile ("bswapl %0":"+r" (*key)); +- key++; +- } +-} +-# endif +-# endif +- + /* + * Force key reload from memory to the CPU microcode. Loading EFLAGS from the + * stack clears EFLAGS[30] which does the trick. +@@ -404,7 +392,7 @@ static inline void padlock_reload_key(vo + asm volatile ("pushfl; popfl"); + } + +-# ifndef OPENSSL_NO_AES ++# ifndef OPENSSL_NO_AES + /* + * This is heuristic key context tracing. At first one + * believes that one should use atomic swap instructions, +@@ -448,6 +436,101 @@ static inline void *name(size_t cnt, + : "edx", "cc", "memory"); \ + return iv; \ + } ++# endif ++ ++# elif defined(__x86_64__) || defined(__x86_64) ++ ++/* Load supported features of the CPU to see if ++ the PadLock is available. */ ++static int padlock_available(void) ++{ ++ char vendor_string[16]; ++ unsigned int eax, edx; ++ ++ /* Are we running on the Centaur (VIA) CPU? */ ++ eax = 0x00000000; ++ vendor_string[12] = 0; ++ asm volatile ("cpuid\n" ++ "movl %%ebx,(%1)\n" ++ "movl %%edx,4(%1)\n" ++ "movl %%ecx,8(%1)\n":"+a" (eax):"r"(vendor_string):"rbx", ++ "rcx", "rdx"); ++ if (strcmp(vendor_string, "CentaurHauls") != 0) ++ return 0; ++ ++ /* Check for Centaur Extended Feature Flags presence */ ++ eax = 0xC0000000; ++ asm volatile ("cpuid":"+a" (eax)::"rbx", "rcx", "rdx"); ++ if (eax < 0xC0000001) ++ return 0; ++ ++ /* Read the Centaur Extended Feature Flags */ ++ eax = 0xC0000001; ++ asm volatile ("cpuid":"+a" (eax), "=d"(edx)::"rbx", "rcx"); ++ ++ /* Fill up some flags */ ++ padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6)); ++ padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2)); ++ ++ return padlock_use_ace + padlock_use_rng; ++} ++ ++/* Force key reload from memory to the CPU microcode. ++ Loading EFLAGS from the stack clears EFLAGS[30] ++ which does the trick. */ ++static inline void padlock_reload_key(void) ++{ ++ asm volatile ("pushfq; popfq"); ++} ++ ++# ifndef OPENSSL_NO_AES ++/* ++ * This is heuristic key context tracing. At first one ++ * believes that one should use atomic swap instructions, ++ * but it's not actually necessary. Point is that if ++ * padlock_saved_context was changed by another thread ++ * after we've read it and before we compare it with cdata, ++ * our key *shall* be reloaded upon thread context switch ++ * and we are therefore set in either case... ++ */ ++static inline void padlock_verify_context(struct padlock_cipher_data *cdata) ++{ ++ asm volatile ("pushfq\n" ++ " btl $30,(%%rsp)\n" ++ " jnc 1f\n" ++ " cmpq %2,%1\n" ++ " je 1f\n" ++ " popfq\n" ++ " subq $8,%%rsp\n" ++ "1: addq $8,%%rsp\n" ++ " movq %2,%0":"+m" (padlock_saved_context) ++ :"r"(padlock_saved_context), "r"(cdata):"cc"); ++} ++ ++/* Template for padlock_xcrypt_* modes */ ++/* BIG FAT WARNING: ++ * The offsets used with 'leal' instructions ++ * describe items of the 'padlock_cipher_data' ++ * structure. ++ */ ++# define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \ ++static inline void *name(size_t cnt, \ ++ struct padlock_cipher_data *cdata, \ ++ void *out, const void *inp) \ ++{ void *iv; \ ++ asm volatile ( "leaq 16(%0),%%rdx\n" \ ++ " leaq 32(%0),%%rbx\n" \ ++ rep_xcrypt "\n" \ ++ : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \ ++ : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \ ++ : "rbx", "rdx", "cc", "memory"); \ ++ return iv; \ ++} ++# endif ++ ++# endif /* cpu */ ++ ++# ifndef OPENSSL_NO_AES + + /* Generate all functions with appropriate opcodes */ + /* rep xcryptecb */ +@@ -458,6 +541,20 @@ PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, " + PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") + /* rep xcryptofb */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") ++ ++# ifndef AES_ASM ++/* Our own htonl()/ntohl() */ ++static inline void padlock_bswapl(AES_KEY *ks) ++{ ++ size_t i = sizeof(ks->rd_key) / sizeof(ks->rd_key[0]); ++ unsigned int *key = ks->rd_key; ++ ++ while (i--) { ++ asm volatile ("bswapl %0":"+r" (*key)); ++ key++; ++ } ++} ++# endif + # endif + /* The RNG call itself */ + static inline unsigned int padlock_xstore(void *addr, unsigned int edx_in) +@@ -485,8 +582,8 @@ static inline unsigned int padlock_xstor + static inline unsigned char *padlock_memcpy(void *dst, const void *src, + size_t n) + { +- long *d = dst; +- const long *s = src; ++ size_t *d = dst; ++ const size_t *s = src; + + n /= sizeof(*d); + do { diff --git a/openssl-1.0.2a-readme-warning.patch b/openssl-1.0.2a-readme-warning.patch new file mode 100644 index 0000000..7069989 --- /dev/null +++ b/openssl-1.0.2a-readme-warning.patch @@ -0,0 +1,50 @@ +diff -up openssl-1.0.2a/README.warning openssl-1.0.2a/README +--- openssl-1.0.2a/README.warning 2015-03-20 16:00:47.000000000 +0100 ++++ openssl-1.0.2a/README 2015-03-21 09:06:11.000000000 +0100 +@@ -5,6 +5,46 @@ + Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson + All rights reserved. + ++ WARNING ++ ------- ++ ++ This version of OpenSSL is built in a way that supports operation in ++ the so called FIPS mode. Note though that the library as we build it ++ is not FIPS 140-2 validated and the FIPS mode is present for testing ++ purposes only. ++ ++ This version also contains a few differences from the upstream code ++ some of which are: ++ * The FIPS validation support is significantly different from the ++ upstream FIPS support. For example the FIPS integrity verification ++ check is implemented differently as the FIPS module is built inside ++ the shared library. The HMAC-SHA256 checksums of the whole shared ++ libraries are verified. Also note that the FIPS integrity ++ verification check requires that the libcrypto and libssl shared ++ library files are unmodified which means that it will fail if these ++ files are changed for example by prelink. ++ * If the file /etc/system-fips is present the integrity verification ++ and selftests of the crypto algorithms are run inside the library ++ constructor code. ++ * With the /etc/system-fips present the module respects the kernel ++ FIPS flag /proc/sys/crypto/fips and tries to initialize the FIPS mode ++ if it is set to 1 aborting if the FIPS mode could not be initialized. ++ With the /etc/system-fips present it is also possible to force the ++ OpenSSL library to FIPS mode especially for debugging purposes by ++ setting the environment variable OPENSSL_FORCE_FIPS_MODE. ++ * If the environment variable OPENSSL_NO_DEFAULT_ZLIB is set the module ++ will not automatically load the built in compression method ZLIB ++ when initialized. Applications can still explicitely ask for ZLIB ++ compression method. ++ * The library was patched so the certificates, CRLs and other objects ++ signed with use of MD5 fail verification as the MD5 is too insecure ++ to be used for signatures. If the environment variable ++ OPENSSL_ENABLE_MD5_VERIFY is set, the verification can proceed ++ normally. ++ * If the OPENSSL_ENFORCE_MODULUS_BITS environment variable is set, ++ the library will not allow generation of DSA and RSA keys with ++ other lengths than specified in the FIPS 186-4 standard. ++ + DESCRIPTION + ----------- + diff --git a/openssl-1.0.2a-test-use-localhost.patch b/openssl-1.0.2a-test-use-localhost.patch new file mode 100644 index 0000000..4510e6e --- /dev/null +++ b/openssl-1.0.2a-test-use-localhost.patch @@ -0,0 +1,21 @@ +diff -up openssl-1.0.2a/ssl/ssltest.c.use-localhost openssl-1.0.2a/ssl/ssltest.c +--- openssl-1.0.2a/ssl/ssltest.c.use-localhost 2015-04-20 14:43:07.172601663 +0200 ++++ openssl-1.0.2a/ssl/ssltest.c 2015-04-20 14:45:02.831299849 +0200 +@@ -1516,16 +1516,7 @@ int main(int argc, char *argv[]) + + #ifndef OPENSSL_NO_KRB5 + if (c_ssl && c_ssl->kssl_ctx) { +- char localhost[MAXHOSTNAMELEN + 2]; +- +- if (gethostname(localhost, sizeof localhost - 1) == 0) { +- localhost[sizeof localhost - 1] = '\0'; +- if (strlen(localhost) == sizeof localhost - 1) { +- BIO_printf(bio_err, "localhost name too long\n"); +- goto end; +- } +- kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, localhost); +- } ++ kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER, "localhost"); + } + #endif /* OPENSSL_NO_KRB5 */ + diff --git a/openssl-1.0.2a-version-add-engines.patch b/openssl-1.0.2a-version-add-engines.patch new file mode 100644 index 0000000..b7936b3 --- /dev/null +++ b/openssl-1.0.2a-version-add-engines.patch @@ -0,0 +1,47 @@ +diff -up openssl-1.0.2a/apps/version.c.version-add-engines openssl-1.0.2a/apps/version.c +--- openssl-1.0.2a/apps/version.c.version-add-engines 2015-04-09 18:16:42.345756005 +0200 ++++ openssl-1.0.2a/apps/version.c 2015-04-09 18:16:36.573622667 +0200 +@@ -131,6 +131,7 @@ + #ifndef OPENSSL_NO_BF + # include + #endif ++#include + + #undef PROG + #define PROG version_main +@@ -140,7 +141,8 @@ int MAIN(int, char **); + int MAIN(int argc, char **argv) + { + int i, ret = 0; +- int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0; ++ int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = ++ 0, engines = 0; + + apps_startup(); + +@@ -164,7 +166,7 @@ int MAIN(int argc, char **argv) + else if (strcmp(argv[i], "-d") == 0) + dir = 1; + else if (strcmp(argv[i], "-a") == 0) +- date = version = cflags = options = platform = dir = 1; ++ date = version = cflags = options = platform = dir = engines = 1; + else { + BIO_printf(bio_err, "usage:version -[avbofpd]\n"); + ret = 1; +@@ -208,6 +210,16 @@ int MAIN(int argc, char **argv) + printf("%s\n", SSLeay_version(SSLEAY_CFLAGS)); + if (dir) + printf("%s\n", SSLeay_version(SSLEAY_DIR)); ++ if (engines) { ++ ENGINE *e; ++ printf("engines: "); ++ e = ENGINE_get_first(); ++ while (e) { ++ printf("%s ", ENGINE_get_id(e)); ++ e = ENGINE_get_next(e); ++ } ++ printf("\n"); ++ } + end: + apps_shutdown(); + OPENSSL_EXIT(ret); diff --git a/openssl-1.0.2a-x509.patch b/openssl-1.0.2a-x509.patch new file mode 100644 index 0000000..7c96a57 --- /dev/null +++ b/openssl-1.0.2a-x509.patch @@ -0,0 +1,28 @@ +diff -up openssl-1.0.2a/crypto/x509/by_file.c.x509 openssl-1.0.2a/crypto/x509/by_file.c +--- openssl-1.0.2a/crypto/x509/by_file.c.x509 2015-04-09 18:16:29.365456157 +0200 ++++ openssl-1.0.2a/crypto/x509/by_file.c 2015-04-09 18:16:26.398387618 +0200 +@@ -152,9 +152,12 @@ int X509_load_cert_file(X509_LOOKUP *ctx + } + } + i = X509_STORE_add_cert(ctx->store_ctx, x); +- if (!i) +- goto err; +- count++; ++ /* ignore any problems with current certificate ++ and continue with the next one */ ++ if (i) ++ count++; ++ else ++ ERR_clear_error(); + X509_free(x); + x = NULL; + } +@@ -167,7 +170,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) +- goto err; ++ ERR_clear_error(); + ret = i; + } else { + X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); diff --git a/openssl-1.0.2c-default-paths.patch b/openssl-1.0.2c-default-paths.patch new file mode 100644 index 0000000..aa607be --- /dev/null +++ b/openssl-1.0.2c-default-paths.patch @@ -0,0 +1,63 @@ +diff -up openssl-1.0.2c/apps/s_server.c.default-paths openssl-1.0.2c/apps/s_server.c +--- openssl-1.0.2c/apps/s_server.c.default-paths 2015-06-12 16:51:21.000000000 +0200 ++++ openssl-1.0.2c/apps/s_server.c 2015-06-15 17:24:17.747446515 +0200 +@@ -1788,12 +1788,16 @@ int MAIN(int argc, char *argv[]) + } + #endif + +- if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) || +- (!SSL_CTX_set_default_verify_paths(ctx))) { +- /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ +- ERR_print_errors(bio_err); +- /* goto end; */ ++ if (CAfile == NULL && CApath == NULL) { ++ if (!SSL_CTX_set_default_verify_paths(ctx)) { ++ ERR_print_errors(bio_err); ++ } ++ } else { ++ if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) { ++ ERR_print_errors(bio_err); ++ } + } ++ + if (vpm) + SSL_CTX_set1_param(ctx, vpm); + +@@ -1850,8 +1854,10 @@ int MAIN(int argc, char *argv[]) + else + SSL_CTX_sess_set_cache_size(ctx2, 128); + +- if ((!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) || +- (!SSL_CTX_set_default_verify_paths(ctx2))) { ++ if (!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) { ++ ERR_print_errors(bio_err); ++ } ++ if (!SSL_CTX_set_default_verify_paths(ctx2)) { + ERR_print_errors(bio_err); + } + if (vpm) +diff -up openssl-1.0.2c/apps/s_time.c.default-paths openssl-1.0.2c/apps/s_time.c +--- openssl-1.0.2c/apps/s_time.c.default-paths 2015-06-12 16:51:21.000000000 +0200 ++++ openssl-1.0.2c/apps/s_time.c 2015-06-15 17:24:17.747446515 +0200 +@@ -381,13 +381,14 @@ int MAIN(int argc, char **argv) + + SSL_load_error_strings(); + +- if ((!SSL_CTX_load_verify_locations(tm_ctx, CAfile, CApath)) || +- (!SSL_CTX_set_default_verify_paths(tm_ctx))) { +- /* +- * BIO_printf(bio_err,"error setting default verify locations\n"); +- */ +- ERR_print_errors(bio_err); +- /* goto end; */ ++ if (CAfile == NULL && CApath == NULL) { ++ if (!SSL_CTX_set_default_verify_paths(tm_ctx)) { ++ ERR_print_errors(bio_err); ++ } ++ } else { ++ if (!SSL_CTX_load_verify_locations(tm_ctx, CAfile, CApath)) { ++ ERR_print_errors(bio_err); ++ } + } + + if (tm_cipher == NULL) diff --git a/openssl-1.0.2c-ecc-suiteb.patch b/openssl-1.0.2c-ecc-suiteb.patch new file mode 100644 index 0000000..dfcae76 --- /dev/null +++ b/openssl-1.0.2c-ecc-suiteb.patch @@ -0,0 +1,195 @@ +diff -up openssl-1.0.2c/apps/speed.c.suiteb openssl-1.0.2c/apps/speed.c +--- openssl-1.0.2c/apps/speed.c.suiteb 2015-06-15 17:37:06.285083685 +0200 ++++ openssl-1.0.2c/apps/speed.c 2015-06-15 17:37:06.335084836 +0200 +@@ -996,78 +996,26 @@ int MAIN(int argc, char **argv) + } else + # endif + # ifndef OPENSSL_NO_ECDSA +- if (strcmp(*argv, "ecdsap160") == 0) +- ecdsa_doit[R_EC_P160] = 2; +- else if (strcmp(*argv, "ecdsap192") == 0) +- ecdsa_doit[R_EC_P192] = 2; +- else if (strcmp(*argv, "ecdsap224") == 0) +- ecdsa_doit[R_EC_P224] = 2; +- else if (strcmp(*argv, "ecdsap256") == 0) ++ if (strcmp(*argv, "ecdsap256") == 0) + ecdsa_doit[R_EC_P256] = 2; + else if (strcmp(*argv, "ecdsap384") == 0) + ecdsa_doit[R_EC_P384] = 2; + else if (strcmp(*argv, "ecdsap521") == 0) + ecdsa_doit[R_EC_P521] = 2; +- else if (strcmp(*argv, "ecdsak163") == 0) +- ecdsa_doit[R_EC_K163] = 2; +- else if (strcmp(*argv, "ecdsak233") == 0) +- ecdsa_doit[R_EC_K233] = 2; +- else if (strcmp(*argv, "ecdsak283") == 0) +- ecdsa_doit[R_EC_K283] = 2; +- else if (strcmp(*argv, "ecdsak409") == 0) +- ecdsa_doit[R_EC_K409] = 2; +- else if (strcmp(*argv, "ecdsak571") == 0) +- ecdsa_doit[R_EC_K571] = 2; +- else if (strcmp(*argv, "ecdsab163") == 0) +- ecdsa_doit[R_EC_B163] = 2; +- else if (strcmp(*argv, "ecdsab233") == 0) +- ecdsa_doit[R_EC_B233] = 2; +- else if (strcmp(*argv, "ecdsab283") == 0) +- ecdsa_doit[R_EC_B283] = 2; +- else if (strcmp(*argv, "ecdsab409") == 0) +- ecdsa_doit[R_EC_B409] = 2; +- else if (strcmp(*argv, "ecdsab571") == 0) +- ecdsa_doit[R_EC_B571] = 2; + else if (strcmp(*argv, "ecdsa") == 0) { +- for (i = 0; i < EC_NUM; i++) ++ for (i = R_EC_P256; i <= R_EC_P521; i++) + ecdsa_doit[i] = 1; + } else + # endif + # ifndef OPENSSL_NO_ECDH +- if (strcmp(*argv, "ecdhp160") == 0) +- ecdh_doit[R_EC_P160] = 2; +- else if (strcmp(*argv, "ecdhp192") == 0) +- ecdh_doit[R_EC_P192] = 2; +- else if (strcmp(*argv, "ecdhp224") == 0) +- ecdh_doit[R_EC_P224] = 2; +- else if (strcmp(*argv, "ecdhp256") == 0) ++ if (strcmp(*argv, "ecdhp256") == 0) + ecdh_doit[R_EC_P256] = 2; + else if (strcmp(*argv, "ecdhp384") == 0) + ecdh_doit[R_EC_P384] = 2; + else if (strcmp(*argv, "ecdhp521") == 0) + ecdh_doit[R_EC_P521] = 2; +- else if (strcmp(*argv, "ecdhk163") == 0) +- ecdh_doit[R_EC_K163] = 2; +- else if (strcmp(*argv, "ecdhk233") == 0) +- ecdh_doit[R_EC_K233] = 2; +- else if (strcmp(*argv, "ecdhk283") == 0) +- ecdh_doit[R_EC_K283] = 2; +- else if (strcmp(*argv, "ecdhk409") == 0) +- ecdh_doit[R_EC_K409] = 2; +- else if (strcmp(*argv, "ecdhk571") == 0) +- ecdh_doit[R_EC_K571] = 2; +- else if (strcmp(*argv, "ecdhb163") == 0) +- ecdh_doit[R_EC_B163] = 2; +- else if (strcmp(*argv, "ecdhb233") == 0) +- ecdh_doit[R_EC_B233] = 2; +- else if (strcmp(*argv, "ecdhb283") == 0) +- ecdh_doit[R_EC_B283] = 2; +- else if (strcmp(*argv, "ecdhb409") == 0) +- ecdh_doit[R_EC_B409] = 2; +- else if (strcmp(*argv, "ecdhb571") == 0) +- ecdh_doit[R_EC_B571] = 2; + else if (strcmp(*argv, "ecdh") == 0) { +- for (i = 0; i < EC_NUM; i++) ++ for (i = R_EC_P256; i <= R_EC_P521; i++) + ecdh_doit[i] = 1; + } else + # endif +@@ -1156,21 +1104,11 @@ int MAIN(int argc, char **argv) + BIO_printf(bio_err, "dsa512 dsa1024 dsa2048\n"); + # endif + # ifndef OPENSSL_NO_ECDSA +- BIO_printf(bio_err, "ecdsap160 ecdsap192 ecdsap224 " +- "ecdsap256 ecdsap384 ecdsap521\n"); +- BIO_printf(bio_err, +- "ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n"); +- BIO_printf(bio_err, +- "ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571\n"); ++ BIO_printf(bio_err, "ecdsap256 ecdsap384 ecdsap521\n"); + BIO_printf(bio_err, "ecdsa\n"); + # endif + # ifndef OPENSSL_NO_ECDH +- BIO_printf(bio_err, "ecdhp160 ecdhp192 ecdhp224 " +- "ecdhp256 ecdhp384 ecdhp521\n"); +- BIO_printf(bio_err, +- "ecdhk163 ecdhk233 ecdhk283 ecdhk409 ecdhk571\n"); +- BIO_printf(bio_err, +- "ecdhb163 ecdhb233 ecdhb283 ecdhb409 ecdhb571\n"); ++ BIO_printf(bio_err, "ecdhp256 ecdhp384 ecdhp521\n"); + BIO_printf(bio_err, "ecdh\n"); + # endif + +@@ -1255,11 +1193,11 @@ int MAIN(int argc, char **argv) + if (!FIPS_mode() || i != R_DSA_512) + dsa_doit[i] = 1; + # ifndef OPENSSL_NO_ECDSA +- for (i = 0; i < EC_NUM; i++) ++ for (i = R_EC_P256; i <= R_EC_P521; i++) + ecdsa_doit[i] = 1; + # endif + # ifndef OPENSSL_NO_ECDH +- for (i = 0; i < EC_NUM; i++) ++ for (i = R_EC_P256; i <= R_EC_P521; i++) + ecdh_doit[i] = 1; + # endif + } +diff -up openssl-1.0.2c/ssl/t1_lib.c.suiteb openssl-1.0.2c/ssl/t1_lib.c +--- openssl-1.0.2c/ssl/t1_lib.c.suiteb 2015-06-12 16:51:27.000000000 +0200 ++++ openssl-1.0.2c/ssl/t1_lib.c 2015-06-15 17:44:03.578681271 +0200 +@@ -268,11 +268,7 @@ static const unsigned char eccurves_auto + 0, 23, /* secp256r1 (23) */ + /* Other >= 256-bit prime curves. */ + 0, 25, /* secp521r1 (25) */ +- 0, 28, /* brainpool512r1 (28) */ +- 0, 27, /* brainpoolP384r1 (27) */ + 0, 24, /* secp384r1 (24) */ +- 0, 26, /* brainpoolP256r1 (26) */ +- 0, 22, /* secp256k1 (22) */ + # ifndef OPENSSL_NO_EC2M + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ +@@ -289,11 +285,7 @@ static const unsigned char eccurves_all[ + 0, 23, /* secp256r1 (23) */ + /* Other >= 256-bit prime curves. */ + 0, 25, /* secp521r1 (25) */ +- 0, 28, /* brainpool512r1 (28) */ +- 0, 27, /* brainpoolP384r1 (27) */ + 0, 24, /* secp384r1 (24) */ +- 0, 26, /* brainpoolP256r1 (26) */ +- 0, 22, /* secp256k1 (22) */ + # ifndef OPENSSL_NO_EC2M + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ +@@ -307,13 +299,6 @@ static const unsigned char eccurves_all[ + * Remaining curves disabled by default but still permitted if set + * via an explicit callback or parameters. + */ +- 0, 20, /* secp224k1 (20) */ +- 0, 21, /* secp224r1 (21) */ +- 0, 18, /* secp192k1 (18) */ +- 0, 19, /* secp192r1 (19) */ +- 0, 15, /* secp160k1 (15) */ +- 0, 16, /* secp160r1 (16) */ +- 0, 17, /* secp160r2 (17) */ + # ifndef OPENSSL_NO_EC2M + 0, 8, /* sect239k1 (8) */ + 0, 6, /* sect233k1 (6) */ +@@ -348,29 +333,21 @@ static const unsigned char fips_curves_d + 0, 9, /* sect283k1 (9) */ + 0, 10, /* sect283r1 (10) */ + # endif +- 0, 22, /* secp256k1 (22) */ + 0, 23, /* secp256r1 (23) */ + # ifndef OPENSSL_NO_EC2M + 0, 8, /* sect239k1 (8) */ + 0, 6, /* sect233k1 (6) */ + 0, 7, /* sect233r1 (7) */ + # endif +- 0, 20, /* secp224k1 (20) */ +- 0, 21, /* secp224r1 (21) */ + # ifndef OPENSSL_NO_EC2M + 0, 4, /* sect193r1 (4) */ + 0, 5, /* sect193r2 (5) */ + # endif +- 0, 18, /* secp192k1 (18) */ +- 0, 19, /* secp192r1 (19) */ + # ifndef OPENSSL_NO_EC2M + 0, 1, /* sect163k1 (1) */ + 0, 2, /* sect163r1 (2) */ + 0, 3, /* sect163r2 (3) */ + # endif +- 0, 15, /* secp160k1 (15) */ +- 0, 16, /* secp160r1 (16) */ +- 0, 17, /* secp160r2 (17) */ + }; + # endif + diff --git a/openssl-1.0.2d-secp256k1.patch b/openssl-1.0.2d-secp256k1.patch new file mode 100644 index 0000000..4c94133 --- /dev/null +++ b/openssl-1.0.2d-secp256k1.patch @@ -0,0 +1,82 @@ +diff -up openssl-1.0.2d/crypto/ec/ec_curve.c.secp256k1 openssl-1.0.2d/crypto/ec/ec_curve.c +--- openssl-1.0.2d/crypto/ec/ec_curve.c.secp256k1 2015-08-12 14:55:15.203415420 -0400 ++++ openssl-1.0.2d/crypto/ec/ec_curve.c 2015-08-12 15:07:12.659113262 -0400 +@@ -86,6 +86,42 @@ typedef struct { + unsigned int cofactor; /* promoted to BN_ULONG */ + } EC_CURVE_DATA; + ++static const struct { ++ EC_CURVE_DATA h; ++ unsigned char data[0 + 32 * 6]; ++} _EC_SECG_PRIME_256K1 = { ++ { ++ NID_X9_62_prime_field, 0, 32, 1 ++ }, ++ { ++ /* no seed */ ++ /* p */ ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, ++ /* a */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ /* b */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, ++ /* x */ ++ 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, ++ 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, ++ 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, ++ /* y */ ++ 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, ++ 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, ++ 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8, ++ /* order */ ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, ++ 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 ++ } ++}; ++ + /* the nist prime curves */ + static const struct { + EC_CURVE_DATA h; +@@ -235,6 +271,8 @@ typedef struct _ec_list_element_st { + static const ec_list_element curve_list[] = { + /* prime field curves */ + /* secg curves */ ++ {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, ++ "SECG curve over a 256 bit prime field"}, + /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ + {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, + "NIST/SECG curve over a 384 bit prime field"}, +diff -up openssl-1.0.2d/ssl/t1_lib.c.secp256k1 openssl-1.0.2d/ssl/t1_lib.c +--- openssl-1.0.2d/ssl/t1_lib.c.secp256k1 2015-08-12 15:04:42.876925441 -0400 ++++ openssl-1.0.2d/ssl/t1_lib.c 2015-08-12 15:04:47.837699822 -0400 +@@ -269,6 +269,7 @@ static const unsigned char eccurves_auto + /* Other >= 256-bit prime curves. */ + 0, 25, /* secp521r1 (25) */ + 0, 24, /* secp384r1 (24) */ ++ 0, 22, /* secp256k1 (22) */ + # ifndef OPENSSL_NO_EC2M + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ +@@ -286,6 +287,7 @@ static const unsigned char eccurves_all[ + /* Other >= 256-bit prime curves. */ + 0, 25, /* secp521r1 (25) */ + 0, 24, /* secp384r1 (24) */ ++ 0, 22, /* secp256k1 (22) */ + # ifndef OPENSSL_NO_EC2M + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ +@@ -333,6 +335,7 @@ static const unsigned char fips_curves_d + 0, 9, /* sect283k1 (9) */ + 0, 10, /* sect283r1 (10) */ + # endif ++ 0, 22, /* secp256k1 (22) */ + 0, 23, /* secp256r1 (23) */ + # ifndef OPENSSL_NO_EC2M + 0, 8, /* sect239k1 (8) */ diff --git a/openssl-1.0.2e-remove-nistp224.patch b/openssl-1.0.2e-remove-nistp224.patch new file mode 100644 index 0000000..22b99c1 --- /dev/null +++ b/openssl-1.0.2e-remove-nistp224.patch @@ -0,0 +1,15 @@ +diff -up openssl-1.0.2e/crypto/ec/ec.h.nistp224 openssl-1.0.2e/crypto/ec/ec.h +--- openssl-1.0.2e/crypto/ec/ec.h.nistp224 2015-12-04 14:00:57.000000000 +0100 ++++ openssl-1.0.2e/crypto/ec/ec.h 2015-12-08 15:51:37.046747916 +0100 +@@ -149,11 +149,6 @@ const EC_METHOD *EC_GFp_mont_method(void + const EC_METHOD *EC_GFp_nist_method(void); + + # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +-/** Returns 64-bit optimized methods for nistp224 +- * \return EC_METHOD object +- */ +-const EC_METHOD *EC_GFp_nistp224_method(void); +- + /** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ diff --git a/openssl-1.0.2e-rpmbuild.patch b/openssl-1.0.2e-rpmbuild.patch new file mode 100644 index 0000000..db1460c --- /dev/null +++ b/openssl-1.0.2e-rpmbuild.patch @@ -0,0 +1,115 @@ +diff -up openssl-1.0.2e/Configure.rpmbuild openssl-1.0.2e/Configure +--- openssl-1.0.2e/Configure.rpmbuild 2015-12-03 15:04:23.000000000 +0100 ++++ openssl-1.0.2e/Configure 2015-12-04 13:20:22.996835604 +0100 +@@ -365,8 +365,8 @@ my %table=( + #### + # *-generic* is endian-neutral target, but ./config is free to + # throw in -D[BL]_ENDIAN, whichever appropriate... +-"linux-generic32","gcc:-O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-ppc", "gcc:-DB_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc32_asm}:linux32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-generic32","gcc:-Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-ppc", "gcc:-DB_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc32_asm}:linux32:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + + ####################################################################### + # Note that -march is not among compiler options in below linux-armv4 +@@ -395,31 +395,31 @@ my %table=( + # + # ./Configure linux-armv4 -march=armv6 -D__ARM_MAX_ARCH__=8 + # +-"linux-armv4", "gcc: -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-aarch64","gcc: -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${aarch64_asm}:linux64:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-armv4", "gcc:-Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-aarch64","gcc:-DL_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${aarch64_asm}:linux64:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", + # Configure script adds minimally required -march for assembly support, + # if no -march was specified at command line. mips32 and mips64 below + # refer to contemporary MIPS Architecture specifications, MIPS32 and + # MIPS64, rather than to kernel bitness. +-"linux-mips32", "gcc:-mabi=32 -O3 -Wall -DBN_DIV3W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-mips64", "gcc:-mabi=n32 -O3 -Wall -DBN_DIV3W::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips64_asm}:n32:dlfcn:linux-shared:-fPIC:-mabi=n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32", +-"linux64-mips64", "gcc:-mabi=64 -O3 -Wall -DBN_DIV3W::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips64_asm}:64:dlfcn:linux-shared:-fPIC:-mabi=64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", ++"linux-mips32", "gcc:-mabi=32 -Wall \$(RPM_OPT_FLAGS) -DBN_DIV3W::-D_REENTRANT::-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-mips64", "gcc:-mabi=n32 -Wall \$(RPM_OPT_FLAGS) -DBN_DIV3W::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips64_asm}:n32:dlfcn:linux-shared:-fPIC:-mabi=n32 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::32", ++"linux64-mips64", "gcc:-mabi=64 -Wall \$(RPM_OPT_FLAGS) -DBN_DIV3W::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips64_asm}:64:dlfcn:linux-shared:-fPIC:-mabi=64 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", + #### IA-32 targets... + "linux-ia32-icc", "icc:-DL_ENDIAN -O2::-D_REENTRANT::-ldl -no_cpprt:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-elf", "gcc:-DL_ENDIAN -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-elf", "gcc:-DL_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + "linux-aout", "gcc:-DL_ENDIAN -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out", + #### +-"linux-generic64","gcc:-O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-ppc64", "gcc:-m64 -DB_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc64_asm}:linux64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", +-"linux-ppc64le","gcc:-m64 -DL_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:$ppc64_asm:linux64le:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::", +-"linux-ia64", "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-generic64","gcc:-Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", ++"linux-ppc64", "gcc:-m64 -DB_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc64_asm}:linux64:dlfcn:linux-shared:-fPIC:-m64 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", ++"linux-ppc64le","gcc:-m64 -DL_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:$ppc64_asm:linux64le:dlfcn:linux-shared:-fPIC:-m64 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", ++"linux-ia64", "gcc:-DL_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + "linux-ia64-icc","icc:-DL_ENDIAN -O2 -Wall::-D_REENTRANT::-ldl -no_cpprt:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-x86_64", "gcc:-m64 -DL_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", ++"linux-x86_64", "gcc:-m64 -DL_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", + "linux-x86_64-clang", "clang: -m64 -DL_ENDIAN -O3 -Wall -Wextra $clang_disabled_warnings -Qunused-arguments::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", + "debug-linux-x86_64-clang", "clang: -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -g -Wall -Wextra $clang_disabled_warnings -Qunused-arguments::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", + "linux-x86_64-icc", "icc:-DL_ENDIAN -O2::-D_REENTRANT::-ldl -no_cpprt:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", + "linux-x32", "gcc:-mx32 -DL_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-mx32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::x32", +-"linux64-s390x", "gcc:-m64 -DB_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", ++"linux64-s390x", "gcc:-m64 -DB_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:64:dlfcn:linux-shared:-fPIC:-m64 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", + #### So called "highgprs" target for z/Architecture CPUs + # "Highgprs" is kernel feature first implemented in Linux 2.6.32, see + # /proc/cpuinfo. The idea is to preserve most significant bits of +@@ -437,12 +437,12 @@ my %table=( + #### SPARC Linux setups + # Ray Miller has patiently + # assisted with debugging of following two configs. +-"linux-sparcv8","gcc:-mcpu=v8 -DB_ENDIAN -O3 -fomit-frame-pointer -Wall -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sparcv8","gcc:-mcpu=v8 -DB_ENDIAN -Wall \$(RPM_OPT_FLAGS) -DBN_DIV2W::-D_REENTRANT::-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + # it's a real mess with -mcpu=ultrasparc option under Linux, but + # -Wa,-Av8plus should do the trick no matter what. +-"linux-sparcv9","gcc:-m32 -mcpu=ultrasparc -DB_ENDIAN -O3 -fomit-frame-pointer -Wall -Wa,-Av8plus -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sparcv9","gcc:-m32 -mcpu=ultrasparc -DB_ENDIAN -Wall \$(RPM_OPT_FLAGS) -Wa,-Av8plus -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m32 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + # GCC 3.1 is a requirement +-"linux64-sparcv9","gcc:-m64 -mcpu=ultrasparc -DB_ENDIAN -O3 -fomit-frame-pointer -Wall::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64", ++"linux64-sparcv9","gcc:-m64 -mcpu=ultrasparc -DB_ENDIAN -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT:ULTRASPARC:-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m64 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", + #### Alpha Linux with GNU C and Compaq C setups + # Special notes: + # - linux-alpha+bwx-gcc is ment to be used from ./config only. If you +@@ -1767,7 +1767,7 @@ while () + elsif ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*\.[^\.]*$/) + { + my $sotmp = $1; +- s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp.\$(SHLIB_MAJOR) .s$sotmp/; ++ s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp.\$(SHLIB_SONAMEVER) .s$sotmp/; + } + elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.[^\.]*\.dylib$/) + { +diff -up openssl-1.0.2e/Makefile.org.rpmbuild openssl-1.0.2e/Makefile.org +--- openssl-1.0.2e/Makefile.org.rpmbuild 2015-12-03 15:04:23.000000000 +0100 ++++ openssl-1.0.2e/Makefile.org 2015-12-04 13:18:44.913538616 +0100 +@@ -10,6 +10,7 @@ SHLIB_VERSION_HISTORY= + SHLIB_MAJOR= + SHLIB_MINOR= + SHLIB_EXT= ++SHLIB_SONAMEVER=10 + PLATFORM=dist + OPTIONS= + CONFIGURE_ARGS= +@@ -341,10 +342,9 @@ clean-shared: + link-shared: + @ set -e; for i in $(SHLIBDIRS); do \ + $(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \ +- LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \ ++ LIBNAME=$$i LIBVERSION=$(SHLIB_SONAMEVER) \ + LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \ + symlink.$(SHLIB_TARGET); \ +- libs="$$libs -l$$i"; \ + done + + build-shared: do_$(SHLIB_TARGET) link-shared +@@ -355,7 +355,7 @@ do_$(SHLIB_TARGET): + libs="$(LIBKRB5) $$libs"; \ + fi; \ + $(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \ +- LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \ ++ LIBNAME=$$i LIBVERSION=$(SHLIB_SONAMEVER) \ + LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \ + LIBDEPS="$$libs $(EX_LIBS)" \ + link_a.$(SHLIB_TARGET); \ diff --git a/openssl-1.0.2e-speed-doc.patch b/openssl-1.0.2e-speed-doc.patch new file mode 100644 index 0000000..8e3d95b --- /dev/null +++ b/openssl-1.0.2e-speed-doc.patch @@ -0,0 +1,58 @@ +diff -up openssl-1.0.2e/apps/speed.c.speed-doc openssl-1.0.2e/apps/speed.c +--- openssl-1.0.2e/apps/speed.c.speed-doc 2015-12-04 14:00:58.000000000 +0100 ++++ openssl-1.0.2e/apps/speed.c 2016-01-15 14:15:56.482343557 +0100 +@@ -648,10 +648,6 @@ int MAIN(int argc, char **argv) + # endif + int multiblock = 0; + +-# ifndef TIMES +- usertime = -1; +-# endif +- + apps_startup(); + memset(results, 0, sizeof(results)); + # ifndef OPENSSL_NO_DSA +@@ -1145,10 +1141,8 @@ int MAIN(int argc, char **argv) + + BIO_printf(bio_err, "\n"); + BIO_printf(bio_err, "Available options:\n"); +-# if defined(TIMES) || defined(USE_TOD) + BIO_printf(bio_err, "-elapsed " + "measure time in real time instead of CPU user time.\n"); +-# endif + # ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err, + "-engine e " +diff -up openssl-1.0.2e/doc/apps/speed.pod.speed-doc openssl-1.0.2e/doc/apps/speed.pod +--- openssl-1.0.2e/doc/apps/speed.pod.speed-doc 2015-12-03 14:42:07.000000000 +0100 ++++ openssl-1.0.2e/doc/apps/speed.pod 2016-01-15 14:05:23.044222376 +0100 +@@ -8,6 +8,9 @@ speed - test library performance + + B + [B<-engine id>] ++[B<-elapsed>] ++[B<-evp algo>] ++[B<-decrypt>] + [B] + [B] + [B] +@@ -49,6 +52,19 @@ to attempt to obtain a functional refere + thus initialising it if needed. The engine will then be set as the default + for all available algorithms. + ++=item B<-elapsed> ++ ++Measure time in real time instead of CPU time. It can be useful when testing ++speed of hardware engines. ++ ++=item B<-evp algo> ++ ++Use the specified cipher or message digest algorithm via the EVP interface. ++ ++=item B<-decrypt> ++ ++Time the decryption instead of encryption. Affects only the EVP testing. ++ + =item B<[zero or more test algorithms]> + + If any options are given, B tests those algorithms, otherwise all of diff --git a/openssl-1.0.2e-wrap-pad.patch b/openssl-1.0.2e-wrap-pad.patch new file mode 100644 index 0000000..fad043c --- /dev/null +++ b/openssl-1.0.2e-wrap-pad.patch @@ -0,0 +1,541 @@ +diff -up openssl-1.0.2e/crypto/evp/c_allc.c.wrap openssl-1.0.2e/crypto/evp/c_allc.c +--- openssl-1.0.2e/crypto/evp/c_allc.c.wrap 2015-12-04 13:33:42.118550036 +0100 ++++ openssl-1.0.2e/crypto/evp/c_allc.c 2015-12-04 13:33:42.190551722 +0100 +@@ -179,6 +179,7 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher(EVP_aes_128_xts()); + EVP_add_cipher(EVP_aes_128_ccm()); + EVP_add_cipher(EVP_aes_128_wrap()); ++ EVP_add_cipher(EVP_aes_128_wrap_pad()); + 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()); +@@ -191,6 +192,7 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher(EVP_aes_192_gcm()); + EVP_add_cipher(EVP_aes_192_ccm()); + EVP_add_cipher(EVP_aes_192_wrap()); ++ EVP_add_cipher(EVP_aes_192_wrap_pad()); + 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()); +@@ -204,6 +206,7 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher(EVP_aes_256_xts()); + EVP_add_cipher(EVP_aes_256_ccm()); + EVP_add_cipher(EVP_aes_256_wrap()); ++ EVP_add_cipher(EVP_aes_256_wrap_pad()); + EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); + EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); + # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +@@ -258,6 +261,7 @@ void OpenSSL_add_all_ciphers(void) + + EVP_add_cipher(EVP_des_ede()); + EVP_add_cipher(EVP_des_ede3()); ++ EVP_add_cipher(EVP_des_ede3_wrap()); + # endif + + # ifndef OPENSSL_NO_AES +@@ -272,6 +276,7 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher(EVP_aes_128_xts()); + EVP_add_cipher(EVP_aes_128_ccm()); + EVP_add_cipher(EVP_aes_128_wrap()); ++ EVP_add_cipher(EVP_aes_128_wrap_pad()); + 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()); +@@ -284,6 +289,7 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher(EVP_aes_192_gcm()); + EVP_add_cipher(EVP_aes_192_ccm()); + EVP_add_cipher(EVP_aes_192_wrap()); ++ EVP_add_cipher(EVP_aes_192_wrap_pad()); + 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()); +@@ -297,6 +303,7 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher(EVP_aes_256_xts()); + EVP_add_cipher(EVP_aes_256_ccm()); + EVP_add_cipher(EVP_aes_256_wrap()); ++ EVP_add_cipher(EVP_aes_256_wrap_pad()); + EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); + EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); + # endif +diff -up openssl-1.0.2e/crypto/evp/e_aes.c.wrap openssl-1.0.2e/crypto/evp/e_aes.c +--- openssl-1.0.2e/crypto/evp/e_aes.c.wrap 2015-12-04 13:33:42.119550059 +0100 ++++ openssl-1.0.2e/crypto/evp/e_aes.c 2015-12-04 13:33:42.190551722 +0100 +@@ -1,5 +1,5 @@ + /* ==================================================================== +- * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 2001-2014 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 +@@ -1953,7 +1953,7 @@ static int aes_wrap_init_key(EVP_CIPHER_ + wctx->iv = NULL; + } + if (iv) { +- memcpy(ctx->iv, iv, 8); ++ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + wctx->iv = ctx->iv; + } + return 1; +@@ -1964,30 +1964,57 @@ static int aes_wrap_cipher(EVP_CIPHER_CT + { + EVP_AES_WRAP_CTX *wctx = ctx->cipher_data; + size_t rv; ++ /* AES wrap with padding has IV length of 4, without padding 8 */ ++ int pad = EVP_CIPHER_CTX_iv_length(ctx) == 4; ++ /* No final operation so always return zero length */ + if (!in) + return 0; +- if (inlen % 8) ++ /* Input length must always be non-zero */ ++ if (!inlen) + return -1; +- if (ctx->encrypt && inlen < 8) ++ /* If decrypting need at least 16 bytes and multiple of 8 */ ++ if (!ctx->encrypt && (inlen < 16 || inlen & 0x7)) + return -1; +- if (!ctx->encrypt && inlen < 16) ++ /* If not padding input must be multiple of 8 */ ++ if (!pad && inlen & 0x7) + return -1; + if (!out) { +- if (ctx->encrypt) ++ if (ctx->encrypt) { ++ /* If padding round up to multiple of 8 */ ++ if (pad) ++ inlen = (inlen + 7) / 8 * 8; ++ /* 8 byte prefix */ + return inlen + 8; +- else ++ } else { ++ /* If not padding output will be exactly 8 bytes ++ * smaller than input. If padding it will be at ++ * least 8 bytes smaller but we don't know how ++ * much. ++ */ + return inlen - 8; + } ++ } ++ if (pad) { + if (ctx->encrypt) +- rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen, ++ rv = CRYPTO_128_wrap_pad(&wctx->ks.ks, wctx->iv, ++ out, in, inlen, + (block128_f) AES_encrypt); + else +- rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, out, in, inlen, ++ rv = CRYPTO_128_unwrap_pad(&wctx->ks.ks, wctx->iv, ++ out, in, inlen, + (block128_f) AES_decrypt); ++ } else { ++ if (ctx->encrypt) ++ rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, ++ out, in, inlen, (block128_f) AES_encrypt); ++ else ++ rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, ++ out, in, inlen, (block128_f) AES_decrypt); ++ } + return rv ? (int)rv : -1; + } + +-#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \ ++# define WRAP_FLAGS (EVP_CIPH_WRAP_MODE | EVP_CIPH_FLAG_FIPS \ + | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1) + +@@ -2032,3 +2059,45 @@ const EVP_CIPHER *EVP_aes_256_wrap(void) + { + return &aes_256_wrap; + } ++ ++static const EVP_CIPHER aes_128_wrap_pad = { ++ NID_id_aes128_wrap_pad, ++ 8, 16, 4, WRAP_FLAGS, ++ aes_wrap_init_key, aes_wrap_cipher, ++ NULL, ++ sizeof(EVP_AES_WRAP_CTX), ++ NULL, NULL, NULL, NULL ++}; ++ ++const EVP_CIPHER *EVP_aes_128_wrap_pad(void) ++{ ++ return &aes_128_wrap_pad; ++} ++ ++static const EVP_CIPHER aes_192_wrap_pad = { ++ NID_id_aes192_wrap_pad, ++ 8, 24, 4, WRAP_FLAGS, ++ aes_wrap_init_key, aes_wrap_cipher, ++ NULL, ++ sizeof(EVP_AES_WRAP_CTX), ++ NULL, NULL, NULL, NULL ++}; ++ ++const EVP_CIPHER *EVP_aes_192_wrap_pad(void) ++{ ++ return &aes_192_wrap_pad; ++} ++ ++static const EVP_CIPHER aes_256_wrap_pad = { ++ NID_id_aes256_wrap_pad, ++ 8, 32, 4, WRAP_FLAGS, ++ aes_wrap_init_key, aes_wrap_cipher, ++ NULL, ++ sizeof(EVP_AES_WRAP_CTX), ++ NULL, NULL, NULL, NULL ++}; ++ ++const EVP_CIPHER *EVP_aes_256_wrap_pad(void) ++{ ++ return &aes_256_wrap_pad; ++} +diff -up openssl-1.0.2e/crypto/evp/e_des3.c.wrap openssl-1.0.2e/crypto/evp/e_des3.c +--- openssl-1.0.2e/crypto/evp/e_des3.c.wrap 2015-12-04 13:33:42.119550059 +0100 ++++ openssl-1.0.2e/crypto/evp/e_des3.c 2015-12-04 13:33:42.191551745 +0100 +@@ -474,7 +474,7 @@ static const EVP_CIPHER des3_wrap = { + NID_id_smime_alg_CMS3DESwrap, + 8, 24, 0, + EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER +- | EVP_CIPH_FLAG_DEFAULT_ASN1, ++ | EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_FLAG_FIPS, + des_ede3_init_key, des_ede3_wrap_cipher, + NULL, + sizeof(DES_EDE_KEY), +diff -up openssl-1.0.2e/crypto/evp/evp.h.wrap openssl-1.0.2e/crypto/evp/evp.h +--- openssl-1.0.2e/crypto/evp/evp.h.wrap 2015-12-04 13:33:42.120550083 +0100 ++++ openssl-1.0.2e/crypto/evp/evp.h 2015-12-04 13:33:42.191551745 +0100 +@@ -834,6 +834,7 @@ const EVP_CIPHER *EVP_aes_128_ccm(void); + const EVP_CIPHER *EVP_aes_128_gcm(void); + const EVP_CIPHER *EVP_aes_128_xts(void); + const EVP_CIPHER *EVP_aes_128_wrap(void); ++const EVP_CIPHER *EVP_aes_128_wrap_pad(void); + const EVP_CIPHER *EVP_aes_192_ecb(void); + const EVP_CIPHER *EVP_aes_192_cbc(void); + const EVP_CIPHER *EVP_aes_192_cfb1(void); +@@ -845,6 +846,7 @@ const EVP_CIPHER *EVP_aes_192_ctr(void); + const EVP_CIPHER *EVP_aes_192_ccm(void); + const EVP_CIPHER *EVP_aes_192_gcm(void); + const EVP_CIPHER *EVP_aes_192_wrap(void); ++const EVP_CIPHER *EVP_aes_192_wrap_pad(void); + const EVP_CIPHER *EVP_aes_256_ecb(void); + const EVP_CIPHER *EVP_aes_256_cbc(void); + const EVP_CIPHER *EVP_aes_256_cfb1(void); +@@ -857,6 +859,7 @@ const EVP_CIPHER *EVP_aes_256_ccm(void); + const EVP_CIPHER *EVP_aes_256_gcm(void); + const EVP_CIPHER *EVP_aes_256_xts(void); + const EVP_CIPHER *EVP_aes_256_wrap(void); ++const EVP_CIPHER *EVP_aes_256_wrap_pad(void); + # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); + const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +diff -up openssl-1.0.2e/crypto/evp/evptests.txt.wrap openssl-1.0.2e/crypto/evp/evptests.txt +--- openssl-1.0.2e/crypto/evp/evptests.txt.wrap 2015-12-03 15:04:23.000000000 +0100 ++++ openssl-1.0.2e/crypto/evp/evptests.txt 2015-12-04 13:33:42.191551745 +0100 +@@ -399,3 +399,7 @@ id-aes256-wrap:000102030405060708090A0B0 + id-aes192-wrap:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF0001020304050607:031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2 + id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF0001020304050607:A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1 + id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F:28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21 ++# AES wrap tests from RFC5649 ++id-aes192-wrap-pad:5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8::c37b7e6492584340bed12207808941155068f738:138bdeaa9b8fa7fc61f97742e72248ee5ae6ae5360d1ae6a5f54f373fa543b6a ++id-aes192-wrap-pad:5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8::466f7250617369:afbeb0f07dfbf5419200f2ccb50bb24f ++ +diff -up openssl-1.0.2e/crypto/modes/modes.h.wrap openssl-1.0.2e/crypto/modes/modes.h +--- openssl-1.0.2e/crypto/modes/modes.h.wrap 2015-12-04 13:33:41.770541886 +0100 ++++ openssl-1.0.2e/crypto/modes/modes.h 2015-12-04 13:33:42.191551745 +0100 +@@ -157,6 +157,12 @@ size_t CRYPTO_128_unwrap(void *key, cons + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); ++size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, ++ unsigned char *out, const unsigned char *in, ++ size_t inlen, block128_f block); ++size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, ++ unsigned char *out, const unsigned char *in, ++ size_t inlen, block128_f block); + + #ifdef __cplusplus + } +diff -up openssl-1.0.2e/crypto/modes/wrap128.c.wrap openssl-1.0.2e/crypto/modes/wrap128.c +--- openssl-1.0.2e/crypto/modes/wrap128.c.wrap 2015-12-03 15:04:23.000000000 +0100 ++++ openssl-1.0.2e/crypto/modes/wrap128.c 2015-12-04 13:37:51.486366984 +0100 +@@ -2,6 +2,7 @@ + /* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. ++ * Mode with padding contributed by Petr Spacek (pspacek@redhat.com). + */ + /* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. +@@ -52,19 +53,44 @@ + * ==================================================================== + */ + ++/** Beware! ++ * ++ * Following wrapping modes were designed for AES but this implementation ++ * allows you to use them for any 128 bit block cipher. ++ */ ++ + #include "cryptlib.h" + #include + ++/** RFC 3394 section 2.2.3.1 Default Initial Value */ + static const unsigned char default_iv[] = { + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, + }; + +-/* +- * Input size limit: lower than maximum of standards but far larger than ++/** RFC 5649 section 3 Alternative Initial Value 32-bit constant */ ++static const unsigned char default_aiv[] = { ++ 0xA6, 0x59, 0x59, 0xA6 ++}; ++ ++/** Input size limit: lower than maximum of standards but far larger than + * anything that will be used in practice. + */ + #define CRYPTO128_WRAP_MAX (1UL << 31) + ++/** Wrapping according to RFC 3394 section 2.2.1. ++ * ++ * @param[in] key Key value. ++ * @param[in] iv IV value. Length = 8 bytes. NULL = use default_iv. ++ * @param[in] in Plain text as n 64-bit blocks, n >= 2. ++ * @param[in] inlen Length of in. ++ * @param[out] out Cipher text. Minimal buffer length = (inlen + 8) bytes. ++ * Input and output buffers can overlap if block function ++ * supports that. ++ * @param[in] block Block processing function. ++ * @return 0 if inlen does not consist of n 64-bit blocks, n >= 2. ++ * or if inlen > CRYPTO128_WRAP_MAX. ++ * Output length if wrapping succeeded. ++ */ + size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, +@@ -72,7 +98,7 @@ size_t CRYPTO_128_wrap(void *key, const + { + unsigned char *A, B[16], *R; + size_t i, j, t; +- if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX)) ++ if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) + return 0; + A = B; + t = 1; +@@ -100,7 +126,23 @@ size_t CRYPTO_128_wrap(void *key, const + return inlen + 8; + } + +-size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, ++/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2. ++ * IV check (step 3) is responsibility of the caller. ++ * ++ * @param[in] key Key value. ++ * @param[out] iv Unchecked IV value. Minimal buffer length = 8 bytes. ++ * @param[out] out Plain text without IV. ++ * Minimal buffer length = (inlen - 8) bytes. ++ * Input and output buffers can overlap if block function ++ * supports that. ++ * @param[in] in Ciphertext text as n 64-bit blocks ++ * @param[in] inlen Length of in. ++ * @param[in] block Block processing function. ++ * @return 0 if inlen is out of range [24, CRYPTO128_WRAP_MAX] ++ * or if inlen is not multiply of 8. ++ * Output length otherwise. ++ */ ++static size_t crypto_128_unwrap_raw(void *key, unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block) +@@ -128,11 +170,190 @@ size_t CRYPTO_128_unwrap(void *key, cons + memcpy(R, B + 8, 8); + } + } ++ memcpy(iv, A, 8); ++ return inlen; ++} ++ ++/** Unwrapping according to RFC 3394 section 2.2.2 including IV check. ++ * First block of plain text have to match supplied IV otherwise an error is ++ * returned. ++ * ++ * @param[in] key Key value. ++ * @param[out] iv Unchecked IV value. Minimal buffer length = 8 bytes. ++ * @param[out] out Plain text without IV. ++ * Minimal buffer length = (inlen - 8) bytes. ++ * Input and output buffers can overlap if block function ++ * supports that. ++ * @param[in] in Ciphertext text as n 64-bit blocks ++ * @param[in] inlen Length of in. ++ * @param[in] block Block processing function. ++ * @return 0 if inlen is out of range [24, CRYPTO128_WRAP_MAX] ++ * or if inlen is not multiply of 8 ++ * or if IV doesn't match expected value. ++ * Output length otherwise. ++ */ ++size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, ++ unsigned char *out, const unsigned char *in, ++ size_t inlen, block128_f block) ++{ ++ size_t ret; ++ unsigned char got_iv[8]; ++ ++ ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block); ++ if (ret == 0) ++ return 0; ++ + if (!iv) + iv = default_iv; +- if (memcmp(A, iv, 8)) { ++ if (CRYPTO_memcmp(got_iv, iv, 8)) { ++ OPENSSL_cleanse(out, ret); ++ return 0; ++ } ++ return ret; ++} ++ ++/** Wrapping according to RFC 5649 section 4.1. ++ * ++ * @param[in] key Key value. ++ * @param[in] icv (Non-standard) IV, 4 bytes. NULL = use default_aiv. ++ * @param[out] out Cipher text. Minimal buffer length = (inlen + 15) bytes. ++ * Input and output buffers can overlap if block function ++ * supports that. ++ * @param[in] in Plain text as n 64-bit blocks, n >= 2. ++ * @param[in] inlen Length of in. ++ * @param[in] block Block processing function. ++ * @return 0 if inlen is out of range [1, CRYPTO128_WRAP_MAX]. ++ * Output length if wrapping succeeded. ++ */ ++size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv, ++ unsigned char *out, ++ const unsigned char *in, size_t inlen, ++ block128_f block) ++{ ++ /* n: number of 64-bit blocks in the padded key data */ ++ const size_t blocks_padded = (inlen + 7) / 8; ++ const size_t padded_len = blocks_padded * 8; ++ const size_t padding_len = padded_len - inlen; ++ /* RFC 5649 section 3: Alternative Initial Value */ ++ unsigned char aiv[8]; ++ int ret; ++ ++ /* Section 1: use 32-bit fixed field for plaintext octet length */ ++ if (inlen == 0 || inlen >= CRYPTO128_WRAP_MAX) ++ return 0; ++ ++ /* Section 3: Alternative Initial Value */ ++ if (!icv) ++ memcpy(aiv, default_aiv, 4); ++ else ++ memcpy(aiv, icv, 4); /* Standard doesn't mention this. */ ++ ++ aiv[4] = (inlen >> 24) & 0xFF; ++ aiv[5] = (inlen >> 16) & 0xFF; ++ aiv[6] = (inlen >> 8) & 0xFF; ++ aiv[7] = inlen & 0xFF; ++ ++ if (padded_len == 8) { ++ /* Section 4.1 - special case in step 2: ++ * If the padded plaintext contains exactly eight octets, then ++ * prepend the AIV and encrypt the resulting 128-bit block ++ * using AES in ECB mode. */ ++ memmove(out + 8, in, inlen); ++ memcpy(out, aiv, 8); ++ memset(out + 8 + inlen, 0, padding_len); ++ block(out, out, key); ++ ret = 16; /* AIV + padded input */ ++ } else { ++ memmove(out, in, inlen); ++ memset(out + inlen, 0, padding_len); /* Section 4.1 step 1 */ ++ ret = CRYPTO_128_wrap(key, aiv, out, out, padded_len, block); ++ } ++ ++ return ret; ++} ++ ++/** Unwrapping according to RFC 5649 section 4.2. ++ * ++ * @param[in] key Key value. ++ * @param[in] icv (Non-standard) IV, 4 bytes. NULL = use default_aiv. ++ * @param[out] out Plain text. Minimal buffer length = inlen bytes. ++ * Input and output buffers can overlap if block function ++ * supports that. ++ * @param[in] in Ciphertext text as n 64-bit blocks ++ * @param[in] inlen Length of in. ++ * @param[in] block Block processing function. ++ * @return 0 if inlen is out of range [16, CRYPTO128_WRAP_MAX], ++ * or if inlen is not multiply of 8 ++ * or if IV and message length indicator doesn't match. ++ * Output length if unwrapping succeeded and IV matches. ++ */ ++size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, ++ unsigned char *out, ++ const unsigned char *in, size_t inlen, ++ block128_f block) ++{ ++ /* n: number of 64-bit blocks in the padded key data */ ++ size_t n = inlen / 8 - 1; ++ size_t padded_len; ++ size_t padding_len; ++ size_t ptext_len; ++ /* RFC 5649 section 3: Alternative Initial Value */ ++ unsigned char aiv[8]; ++ static unsigned char zeros[8] = { 0x0 }; ++ size_t ret; ++ ++ /* Section 4.2: Cipher text length has to be (n+1) 64-bit blocks. */ ++ if ((inlen & 0x7) != 0 || inlen < 16 || inlen >= CRYPTO128_WRAP_MAX) ++ return 0; ++ ++ memmove(out, in, inlen); ++ if (inlen == 16) { ++ /* Section 4.2 - special case in step 1: ++ * When n=1, the ciphertext contains exactly two 64-bit ++ * blocks and they are decrypted as a single AES ++ * block using AES in ECB mode: ++ * AIV | P[1] = DEC(K, C[0] | C[1]) ++ */ ++ block(out, out, key); ++ memcpy(aiv, out, 8); ++ /* Remove AIV */ ++ memmove(out, out + 8, 8); ++ padded_len = 8; ++ } else { ++ padded_len = inlen - 8; ++ ret = crypto_128_unwrap_raw(key, aiv, out, out, inlen, block); ++ if (padded_len != ret) { + OPENSSL_cleanse(out, inlen); + return 0; + } +- return inlen; ++ } ++ ++ /* Section 3: AIV checks: Check that MSB(32,A) = A65959A6. ++ * Optionally a user-supplied value can be used ++ * (even if standard doesn't mention this). */ ++ if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4)) ++ || (icv && CRYPTO_memcmp(aiv, icv, 4))) { ++ OPENSSL_cleanse(out, inlen); ++ return 0; ++ } ++ ++ /* Check that 8*(n-1) < LSB(32,AIV) <= 8*n. ++ * If so, let ptext_len = LSB(32,AIV). */ ++ ++ ptext_len = (aiv[4] << 24) | (aiv[5] << 16) | (aiv[6] << 8) | aiv[7]; ++ if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) { ++ OPENSSL_cleanse(out, inlen); ++ return 0; ++ } ++ ++ /* Check that the rightmost padding_len octets of the output data ++ * are zero. */ ++ padding_len = padded_len - ptext_len; ++ if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) { ++ OPENSSL_cleanse(out, inlen); ++ return 0; ++ } ++ ++ /* Section 4.2 step 3: Remove padding */ ++ return ptext_len; + } diff --git a/openssl-1.0.2g-manfix.patch b/openssl-1.0.2g-manfix.patch new file mode 100644 index 0000000..12e5103 --- /dev/null +++ b/openssl-1.0.2g-manfix.patch @@ -0,0 +1,90 @@ +diff -up openssl-1.0.2g/doc/apps/ec.pod.manfix openssl-1.0.2g/doc/apps/ec.pod +--- openssl-1.0.2g/doc/apps/ec.pod.manfix 2016-03-01 14:35:05.000000000 +0100 ++++ openssl-1.0.2g/doc/apps/ec.pod 2016-03-01 16:47:35.331568290 +0100 +@@ -93,10 +93,6 @@ prints out the public, private key compo + + this option prevents output of the encoded version of the key. + +-=item B<-modulus> +- +-this option prints out the value of the public key component of the key. +- + =item B<-pubin> + + by default a private key is read from the input file: with this option a +diff -up openssl-1.0.2g/doc/apps/openssl.pod.manfix openssl-1.0.2g/doc/apps/openssl.pod +--- openssl-1.0.2g/doc/apps/openssl.pod.manfix 2016-03-01 14:35:05.000000000 +0100 ++++ openssl-1.0.2g/doc/apps/openssl.pod 2016-03-01 16:47:35.331568290 +0100 +@@ -163,7 +163,7 @@ Create or examine a netscape certificate + + Online Certificate Status Protocol utility. + +-=item L|passwd(1)> ++=item L|sslpasswd(1)> + + Generation of hashed passwords. + +@@ -187,7 +187,7 @@ Public key algorithm parameter managemen + + Public key algorithm cryptographic operation utility. + +-=item L|rand(1)> ++=item L|sslrand(1)> + + Generate pseudo-random bytes. + +@@ -401,9 +401,9 @@ L, L, L, L, + L, L, L, + L, L, L, +-L, ++L, + L, L, L, +-L, L, L, ++L, L, L, + L, L, + L, L, + L, L, +diff -up openssl-1.0.2g/doc/apps/s_client.pod.manfix openssl-1.0.2g/doc/apps/s_client.pod +--- openssl-1.0.2g/doc/apps/s_client.pod.manfix 2016-03-01 14:35:53.000000000 +0100 ++++ openssl-1.0.2g/doc/apps/s_client.pod 2016-03-01 16:47:35.358568902 +0100 +@@ -35,6 +35,9 @@ B B + [B<-ssl2>] + [B<-ssl3>] + [B<-tls1>] ++[B<-tls1_1>] ++[B<-tls1_2>] ++[B<-dtls1>] + [B<-no_ssl2>] + [B<-no_ssl3>] + [B<-no_tls1>] +@@ -201,7 +204,7 @@ Use the PSK key B when using a PSK + given as a hexadecimal number without leading 0x, for example -psk + 1a2b3c4d. + +-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> ++=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-dtls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> + + These options require or disable the use of the specified SSL or TLS protocols. + By default the initial handshake uses a I method which will +diff -up openssl-1.0.2g/doc/apps/s_server.pod.manfix openssl-1.0.2g/doc/apps/s_server.pod +--- openssl-1.0.2g/doc/apps/s_server.pod.manfix 2016-03-01 14:35:53.000000000 +0100 ++++ openssl-1.0.2g/doc/apps/s_server.pod 2016-03-01 16:47:35.359568925 +0100 +@@ -42,6 +42,8 @@ B B + [B<-ssl2>] + [B<-ssl3>] + [B<-tls1>] ++[B<-tls1_1>] ++[B<-tls1_2>] + [B<-no_ssl2>] + [B<-no_ssl3>] + [B<-no_tls1>] +@@ -217,7 +219,7 @@ Use the PSK key B when using a PSK + given as a hexadecimal number without leading 0x, for example -psk + 1a2b3c4d. + +-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> ++=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-dtls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> + + These options require or disable the use of the specified SSL or TLS protocols. + By default the initial handshake uses a I method which will diff --git a/openssl-1.0.2h-pkgconfig.patch b/openssl-1.0.2h-pkgconfig.patch new file mode 100644 index 0000000..f810157 --- /dev/null +++ b/openssl-1.0.2h-pkgconfig.patch @@ -0,0 +1,24 @@ +diff -up openssl-1.0.2h/Makefile.org.pkgconfig openssl-1.0.2h/Makefile.org +--- openssl-1.0.2h/Makefile.org.pkgconfig 2016-05-03 18:06:45.869834730 +0200 ++++ openssl-1.0.2h/Makefile.org 2016-06-27 12:04:15.444245018 +0200 +@@ -377,7 +377,7 @@ libcrypto.pc: Makefile + echo 'Requires: '; \ + echo 'Libs: -L$${libdir} -lcrypto'; \ + echo 'Libs.private: $(EX_LIBS)'; \ +- echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc ++ echo 'Cflags: -I$${includedir}' ) > libcrypto.pc + + libssl.pc: Makefile + @ ( echo 'prefix=$(INSTALLTOP)'; \ +@@ -388,9 +388,9 @@ libssl.pc: Makefile + echo 'Name: OpenSSL-libssl'; \ + echo 'Description: Secure Sockets Layer and cryptography libraries'; \ + echo 'Version: '$(VERSION); \ +- echo 'Requires.private: libcrypto'; \ ++ echo 'Requires: libcrypto'; \ + echo 'Libs: -L$${libdir} -lssl'; \ +- echo 'Libs.private: $(EX_LIBS)'; \ ++ echo 'Libs.private: $(EX_LIBS) $(LIBKRB5)'; \ + echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc + + openssl.pc: Makefile diff --git a/openssl-1.0.2i-chil-fixes.patch b/openssl-1.0.2i-chil-fixes.patch new file mode 100644 index 0000000..c7f1820 --- /dev/null +++ b/openssl-1.0.2i-chil-fixes.patch @@ -0,0 +1,15 @@ +diff -up openssl-1.0.2i/engines/e_chil.c.chil openssl-1.0.2i/engines/e_chil.c +--- openssl-1.0.2i/engines/e_chil.c.chil 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/engines/e_chil.c 2016-09-22 13:49:32.532017102 +0200 +@@ -1274,6 +1274,11 @@ static int hwcrhk_insert_card(const char + UI *ui; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; ++ /* Despite what the documentation says prompt_info can be ++ * an empty string. ++ */ ++ if (prompt_info && !*prompt_info) ++ prompt_info = NULL; + + if (cactx) { + if (cactx->ui_method) diff --git a/openssl-1.0.2i-enc-fail.patch b/openssl-1.0.2i-enc-fail.patch new file mode 100644 index 0000000..819a3fc --- /dev/null +++ b/openssl-1.0.2i-enc-fail.patch @@ -0,0 +1,25 @@ +diff -up openssl-1.0.2i/crypto/evp/bio_enc.c.enc-fail openssl-1.0.2i/crypto/evp/bio_enc.c +--- openssl-1.0.2i/crypto/evp/bio_enc.c.enc-fail 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/bio_enc.c 2016-09-22 13:58:24.592381002 +0200 +@@ -307,8 +307,9 @@ static long enc_ctrl(BIO *b, int cmd, lo + case BIO_CTRL_RESET: + ctx->ok = 1; + ctx->finished = 0; +- EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL, +- ctx->cipher.encrypt); ++ if (!EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL, ++ ctx->cipher.encrypt)) ++ ctx->ok = 0; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ +@@ -430,7 +431,8 @@ void BIO_set_cipher(BIO *b, const EVP_CI + + b->init = 1; + ctx = (BIO_ENC_CTX *)b->ptr; +- EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e); ++ if (!EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e)) ++ ctx->ok = 0; + + if (b->callback != NULL) + b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L); diff --git a/openssl-1.0.2i-enginesdir.patch b/openssl-1.0.2i-enginesdir.patch new file mode 100644 index 0000000..862ef1b --- /dev/null +++ b/openssl-1.0.2i-enginesdir.patch @@ -0,0 +1,83 @@ +diff --git a/Configure b/Configure +index c39f71a..7f3d905 100755 +--- a/Configure ++++ b/Configure +@@ -727,6 +727,7 @@ my $idx_multilib = $idx++; + my $prefix=""; + my $libdir=""; + my $openssldir=""; ++my $enginesdir=""; + my $exe_ext=""; + my $install_prefix= "$ENV{'INSTALL_PREFIX'}"; + my $cross_compile_prefix=""; +@@ -956,6 +957,10 @@ PROCESS_ARGS: + { + $openssldir=$1; + } ++ elsif (/^--enginesdir=(.*)$/) ++ { ++ $enginesdir=$1; ++ } + elsif (/^--install.prefix=(.*)$/) + { + $install_prefix=$1; +@@ -1207,7 +1212,7 @@ chop $prefix if $prefix =~ /.\/$/; + + $openssldir=$prefix . "/ssl" if $openssldir eq ""; + $openssldir=$prefix . "/" . $openssldir if $openssldir !~ /(^\/|^[a-zA-Z]:[\\\/])/; +- ++$enginesdir="$prefix/lib/engines" if $enginesdir eq ""; + + print "IsMK1MF=$IsMK1MF\n"; + +@@ -1709,6 +1714,7 @@ while () + s/^INSTALLTOP=.*$/INSTALLTOP=$prefix/; + s/^MULTILIB=.*$/MULTILIB=$multilib/; + s/^OPENSSLDIR=.*$/OPENSSLDIR=$openssldir/; ++ s/^ENGINESDIR=.*$/ENGINESDIR=$enginesdir/; + s/^LIBDIR=.*$/LIBDIR=$libdir/; + s/^INSTALL_PREFIX=.*$/INSTALL_PREFIX=$install_prefix/; + s/^PLATFORM=.*$/PLATFORM=$target/; +@@ -1915,7 +1921,7 @@ while () + } + elsif (/^#define\s+ENGINESDIR/) + { +- my $foo = "$prefix/$libdir/engines"; ++ my $foo = "$enginesdir"; + $foo =~ s/\\/\\\\/g; + print OUT "#define ENGINESDIR \"$foo\"\n"; + } +diff --git a/Makefile.org b/Makefile.org +index 2377f50..fe8d54c 100644 +--- a/Makefile.org ++++ b/Makefile.org +@@ -28,6 +28,7 @@ INSTALLTOP=/usr/local/ssl + + # Do not edit this manually. Use Configure --openssldir=DIR do change this! + OPENSSLDIR=/usr/local/ssl ++ENGINESDIR=$${libdir}/engines + + # NO_IDEA - Define to build without the IDEA algorithm + # NO_RC4 - Define to build without the RC4 algorithm +@@ -368,7 +369,7 @@ libcrypto.pc: Makefile + echo 'exec_prefix=$${prefix}'; \ + echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \ + echo 'includedir=$${prefix}/include'; \ +- echo 'enginesdir=$${libdir}/engines'; \ ++ echo 'enginesdir=$(ENGINESDIR)'; \ + echo ''; \ + echo 'Name: OpenSSL-libcrypto'; \ + echo 'Description: OpenSSL cryptography library'; \ +diff --git a/engines/Makefile b/engines/Makefile +index 2058ff4..a2c407b 100644 +--- a/engines/Makefile ++++ b/engines/Makefile +@@ -124,7 +124,7 @@ install: + esac; \ + cp $$pfx$$l$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \ + fi; \ +- chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \ ++ chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new; \ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$$pfx$$l$$sfx ); \ + done; \ + fi diff --git a/openssl-1.0.2i-fips.patch b/openssl-1.0.2i-fips.patch new file mode 100644 index 0000000..9a2dd6c --- /dev/null +++ b/openssl-1.0.2i-fips.patch @@ -0,0 +1,13703 @@ +diff -up openssl-1.0.2i/apps/speed.c.fips openssl-1.0.2i/apps/speed.c +--- openssl-1.0.2i/apps/speed.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/apps/speed.c 2016-09-22 13:35:57.007220767 +0200 +@@ -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 -up openssl-1.0.2i/Configure.fips openssl-1.0.2i/Configure +--- openssl-1.0.2i/Configure.fips 2016-09-22 13:35:56.993220444 +0200 ++++ openssl-1.0.2i/Configure 2016-09-22 13:35:57.008220790 +0200 +@@ -1067,11 +1067,6 @@ if (defined($disabled{"md5"}) || defined + $disabled{"ssl2"} = "forced"; + } + +-if ($fips && $fipslibdir eq "") +- { +- $fipslibdir = $fipsdir . "/lib/"; +- } +- + # RSAX ENGINE sets default non-FIPS RSA method. + if ($fips) + { +@@ -1556,7 +1551,6 @@ $cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($b + if ($fips) + { + $openssl_other_defines.="#define OPENSSL_FIPS\n"; +- $cflags .= " -I\$(FIPSDIR)/include"; + } + + $cpuid_obj="mem_clr.o" unless ($cpuid_obj =~ /\.o$/); +@@ -1768,9 +1762,12 @@ while () + + 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 -up openssl-1.0.2i/crypto/aes/aes_misc.c.fips openssl-1.0.2i/crypto/aes/aes_misc.c +--- openssl-1.0.2i/crypto/aes/aes_misc.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/aes/aes_misc.c 2016-09-22 13:35:57.008220790 +0200 +@@ -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 -up openssl-1.0.2i/crypto/cmac/cmac.c.fips openssl-1.0.2i/crypto/cmac/cmac.c +--- openssl-1.0.2i/crypto/cmac/cmac.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/cmac/cmac.c 2016-09-22 13:35:57.008220790 +0200 +@@ -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 + 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 voi + { + 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 voi + 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 -up openssl-1.0.2i/crypto/crypto.h.fips openssl-1.0.2i/crypto/crypto.h +--- openssl-1.0.2i/crypto/crypto.h.fips 2016-09-22 13:35:56.890218070 +0200 ++++ openssl-1.0.2i/crypto/crypto.h 2016-09-22 13:35:57.008220790 +0200 +@@ -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 + */ + 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 -up openssl-1.0.2i/crypto/des/des.h.fips openssl-1.0.2i/crypto/des/des.h +--- openssl-1.0.2i/crypto/des/des.h.fips 2016-09-22 13:35:56.918218715 +0200 ++++ openssl-1.0.2i/crypto/des/des.h 2016-09-22 13:35:57.008220790 +0200 +@@ -231,10 +231,6 @@ int DES_set_key(const_DES_cblock *key, D + 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 -up openssl-1.0.2i/crypto/des/set_key.c.fips openssl-1.0.2i/crypto/des/set_key.c +--- openssl-1.0.2i/crypto/des/set_key.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/des/set_key.c 2016-09-22 13:35:57.008220790 +0200 +@@ -359,15 +359,6 @@ int DES_set_key_checked(const_DES_cblock + } + + 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 -up openssl-1.0.2i/crypto/dh/dh_gen.c.fips openssl-1.0.2i/crypto/dh/dh_gen.c +--- openssl-1.0.2i/crypto/dh/dh_gen.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dh/dh_gen.c 2016-09-22 13:35:57.009220813 +0200 +@@ -85,10 +85,6 @@ int DH_generate_parameters_ex(DH *ret, i + #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 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 -up openssl-1.0.2i/crypto/dh/dh.h.fips openssl-1.0.2i/crypto/dh/dh.h +--- openssl-1.0.2i/crypto/dh/dh.h.fips 2016-09-22 13:35:56.863217447 +0200 ++++ openssl-1.0.2i/crypto/dh/dh.h 2016-09-22 13:35:57.009220813 +0200 +@@ -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 -up openssl-1.0.2i/crypto/dh/dh_key.c.fips openssl-1.0.2i/crypto/dh/dh_key.c +--- openssl-1.0.2i/crypto/dh/dh_key.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dh/dh_key.c 2016-09-22 13:35:57.009220813 +0200 +@@ -61,6 +61,9 @@ + #include + #include + #include ++#ifdef OPENSSL_FIPS ++# include ++#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, c + 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 *ke + 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, B + + static int dh_init(DH *dh) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + dh->flags |= DH_FLAG_CACHE_MONT_P; + return (1); + } +diff -up openssl-1.0.2i/crypto/dh/dh_lib.c.fips openssl-1.0.2i/crypto/dh/dh_lib.c +--- openssl-1.0.2i/crypto/dh/dh_lib.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dh/dh_lib.c 2016-09-22 13:35:57.009220813 +0200 +@@ -80,14 +80,7 @@ void DH_set_default_method(const DH_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 -up openssl-1.0.2i/crypto/dsa/dsa_err.c.fips openssl-1.0.2i/crypto/dsa/dsa_err.c +--- openssl-1.0.2i/crypto/dsa/dsa_err.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa_err.c 2016-09-22 13:35:57.009220813 +0200 +@@ -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 -up openssl-1.0.2i/crypto/dsa/dsa_gen.c.fips openssl-1.0.2i/crypto/dsa/dsa_gen.c +--- openssl-1.0.2i/crypto/dsa/dsa_gen.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa_gen.c 2016-09-22 13:42:54.389840662 +0200 +@@ -91,6 +91,16 @@ + # include + # 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,83 +116,146 @@ int DSA_generate_parameters_ex(DSA *ret, + 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 (test == NULL) +@@ -191,15 +264,20 @@ int dsa_builtin_paramgen(DSA *ret, size_ + 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_bytes(seed, qsize) <= 0) + goto err; + seed_is_random = 1; +@@ -209,29 +287,18 @@ int dsa_builtin_paramgen(DSA *ret, size_ + * 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) +@@ -239,8 +306,6 @@ int dsa_builtin_paramgen(DSA *ret, size_ + if (r != 0) + goto err; + +- /* do a callback call */ +- /* step 5 */ + } + + if (!BN_GENCB_call(cb, 2, 0)) +@@ -248,19 +313,16 @@ int dsa_builtin_paramgen(DSA *ret, size_ + 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: +@@ -274,36 +336,37 @@ int dsa_builtin_paramgen(DSA *ret, size_ + 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 */ +@@ -311,12 +374,12 @@ int dsa_builtin_paramgen(DSA *ret, size_ + goto err; + } + +- /* step 13 */ ++ /* step 11.9 */ + counter++; + /* "offset = offset + n + 1" */ + +- /* step 14 */ +- if (counter >= 4096) ++ /* step 12 */ ++ if (counter >= 4 * bits) + break; + } + } +@@ -324,7 +387,33 @@ int dsa_builtin_paramgen(DSA *ret, size_ + 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; +@@ -353,46 +442,14 @@ int dsa_builtin_paramgen(DSA *ret, size_ + 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. +@@ -418,14 +475,6 @@ int dsa_builtin_paramgen2(DSA *ret, size + 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 -up openssl-1.0.2i/crypto/dsa/dsa.h.fips openssl-1.0.2i/crypto/dsa/dsa.h +--- openssl-1.0.2i/crypto/dsa/dsa.h.fips 2016-09-22 13:35:56.789215742 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa.h 2016-09-22 13:35:57.010220836 +0200 +@@ -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, + 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 201 ++# 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 -up openssl-1.0.2i/crypto/dsa/dsa_key.c.fips openssl-1.0.2i/crypto/dsa/dsa_key.c +--- openssl-1.0.2i/crypto/dsa/dsa_key.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa_key.c 2016-09-22 13:35:57.010220836 +0200 +@@ -66,6 +66,34 @@ + + # ifdef OPENSSL_FIPS + # include ++# include ++ ++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 -up openssl-1.0.2i/crypto/dsa/dsa_lib.c.fips openssl-1.0.2i/crypto/dsa/dsa_lib.c +--- openssl-1.0.2i/crypto/dsa/dsa_lib.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa_lib.c 2016-09-22 13:35:57.010220836 +0200 +@@ -86,14 +86,7 @@ void DSA_set_default_method(const DSA_ME + 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 -up openssl-1.0.2i/crypto/dsa/dsa_locl.h.fips openssl-1.0.2i/crypto/dsa/dsa_locl.h +--- openssl-1.0.2i/crypto/dsa/dsa_locl.h.fips 2016-09-22 13:35:56.790215765 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa_locl.h 2016-09-22 13:35:57.010220836 +0200 +@@ -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 -up openssl-1.0.2i/crypto/dsa/dsa_ossl.c.fips openssl-1.0.2i/crypto/dsa/dsa_ossl.c +--- openssl-1.0.2i/crypto/dsa/dsa_ossl.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa_ossl.c 2016-09-22 13:35:57.010220836 +0200 +@@ -65,6 +65,9 @@ + #include + #include + #include ++#ifdef OPENSSL_FIPS ++# include ++#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 unsign + 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); + +@@ -335,6 +351,18 @@ static int dsa_do_verify(const unsigned + 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); +@@ -415,6 +443,9 @@ static int dsa_do_verify(const unsigned + + static int dsa_init(DSA *dsa) + { ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + dsa->flags |= DSA_FLAG_CACHE_MONT_P; + return (1); + } +diff -up openssl-1.0.2i/crypto/dsa/dsa_pmeth.c.fips openssl-1.0.2i/crypto/dsa/dsa_pmeth.c +--- openssl-1.0.2i/crypto/dsa/dsa_pmeth.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsa_pmeth.c 2016-09-22 13:35:57.010220836 +0200 +@@ -253,7 +253,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CT + 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 -up openssl-1.0.2i/crypto/dsa/dsatest.c.fips openssl-1.0.2i/crypto/dsa/dsatest.c +--- openssl-1.0.2i/crypto/dsa/dsatest.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/dsa/dsatest.c 2016-09-22 13:35:57.010220836 +0200 +@@ -100,36 +100,41 @@ static int MS_CALLBACK dsa_cb(int p, int + * 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 -up openssl-1.0.2i/crypto/engine/eng_all.c.fips openssl-1.0.2i/crypto/engine/eng_all.c +--- openssl-1.0.2i/crypto/engine/eng_all.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/engine/eng_all.c 2016-09-22 13:35:57.011220859 +0200 +@@ -59,11 +59,25 @@ + + #include "cryptlib.h" + #include "eng_int.h" ++#ifdef OPENSSL_FIPS ++# include ++#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 -up openssl-1.0.2i/crypto/evp/c_allc.c.fips openssl-1.0.2i/crypto/evp/c_allc.c +--- openssl-1.0.2i/crypto/evp/c_allc.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/c_allc.c 2016-09-22 13:35:57.011220859 +0200 +@@ -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 -up openssl-1.0.2i/crypto/evp/c_alld.c.fips openssl-1.0.2i/crypto/evp/c_alld.c +--- openssl-1.0.2i/crypto/evp/c_alld.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/c_alld.c 2016-09-22 13:35:57.011220859 +0200 +@@ -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 -up openssl-1.0.2i/crypto/evp/digest.c.fips openssl-1.0.2i/crypto/evp/digest.c +--- openssl-1.0.2i/crypto/evp/digest.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/digest.c 2016-09-22 13:45:40.054658929 +0200 +@@ -143,18 +143,55 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, cons + 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 +@@ -212,6 +249,16 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c + } + #endif + if (ctx->digest != type) { ++#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 + if (ctx->digest && ctx->digest->ctx_size) { + OPENSSL_free(ctx->md_data); + ctx->md_data = NULL; +@@ -238,23 +285,13 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, c + } + 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 +- if (FIPS_mode()) +- return FIPS_digestupdate(ctx, data, count); ++ FIPS_selftest_check(); + #endif + return ctx->update(ctx, data, count); + } +@@ -272,11 +309,10 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, uns + int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) + { + int ret; ++ + #ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_digestfinal(ctx, md, size); ++ FIPS_selftest_check(); + #endif +- + OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ret = ctx->digest->final(ctx, md); + if (size != NULL) +@@ -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 -up openssl-1.0.2i/crypto/evp/e_aes.c.fips openssl-1.0.2i/crypto/evp/e_aes.c +--- openssl-1.0.2i/crypto/evp/e_aes.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/e_aes.c 2016-09-22 13:35:57.011220859 +0200 +@@ -60,9 +60,6 @@ + # include "modes_lcl.h" + # include + +-# 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 * + 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 + 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 -up openssl-1.0.2i/crypto/evp/e_des3.c.fips openssl-1.0.2i/crypto/evp/e_des3.c +--- openssl-1.0.2i/crypto/evp/e_des3.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/e_des3.c 2016-09-22 13:35:57.012220882 +0200 +@@ -65,10 +65,6 @@ + # include + # include + +-/* Block use of implementations in FIPS mode */ +-# undef EVP_CIPH_FLAG_FIPS +-# define EVP_CIPH_FLAG_FIPS 0 +- + typedef struct { + union { + double align; +diff -up openssl-1.0.2i/crypto/evp/e_null.c.fips openssl-1.0.2i/crypto/evp/e_null.c +--- openssl-1.0.2i/crypto/evp/e_null.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/e_null.c 2016-09-22 13:35:57.012220882 +0200 +@@ -68,7 +68,7 @@ static int null_cipher(EVP_CIPHER_CTX *c + static const EVP_CIPHER n_cipher = { + NID_undef, + 1, 0, 0, +- 0, ++ EVP_CIPH_FLAG_FIPS, + null_init_key, + null_cipher, + NULL, +diff -up openssl-1.0.2i/crypto/evp/evp_enc.c.fips openssl-1.0.2i/crypto/evp/evp_enc.c +--- openssl-1.0.2i/crypto/evp/evp_enc.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/evp_enc.c 2016-09-22 13:46:12.998418222 +0200 +@@ -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 *ct + 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 *ct + ctx->engine = NULL; + #endif + +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) { +- const EVP_CIPHER *fcipher = NULL; +- 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 *ct + #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 *ct + 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 + + 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_CT + } + 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_CT + */ + ENGINE_finish(c->engine); + #endif +-#ifdef OPENSSL_FIPS +- FIPS_cipher_ctx_cleanup(c); +-#endif + memset(c, 0, sizeof(EVP_CIPHER_CTX)); + return 1; + } +diff -up openssl-1.0.2i/crypto/evp/evp.h.fips openssl-1.0.2i/crypto/evp/evp.h +--- openssl-1.0.2i/crypto/evp/evp.h.fips 2016-09-22 13:35:56.902218346 +0200 ++++ openssl-1.0.2i/crypto/evp/evp.h 2016-09-22 13:35:57.012220882 +0200 +@@ -122,6 +122,10 @@ + extern "C" { + #endif + ++# ifdef OPENSSL_FIPS ++# include ++# 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 -up openssl-1.0.2i/crypto/evp/evp_lib.c.fips openssl-1.0.2i/crypto/evp/evp_lib.c +--- openssl-1.0.2i/crypto/evp/evp_lib.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/evp_lib.c 2016-09-22 13:35:57.012220882 +0200 +@@ -60,10 +60,6 @@ + #include "cryptlib.h" + #include + #include +-#ifdef OPENSSL_FIPS +-# include +-# 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_ + 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( + + 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 -up openssl-1.0.2i/crypto/evp/evp_locl.h.fips openssl-1.0.2i/crypto/evp/evp_locl.h +--- openssl-1.0.2i/crypto/evp/evp_locl.h.fips 2016-09-22 13:35:56.898218254 +0200 ++++ openssl-1.0.2i/crypto/evp/evp_locl.h 2016-09-22 13:35:57.013220905 +0200 +@@ -258,10 +258,8 @@ const EVP_CIPHER *EVP_##cname##_ecb(void + 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(co + # 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(co + # 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 -up openssl-1.0.2i/crypto/evp/m_dss.c.fips openssl-1.0.2i/crypto/evp/m_dss.c +--- openssl-1.0.2i/crypto/evp/m_dss.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/m_dss.c 2016-09-22 13:35:57.013220905 +0200 +@@ -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 -up openssl-1.0.2i/crypto/evp/m_dss1.c.fips openssl-1.0.2i/crypto/evp/m_dss1.c +--- openssl-1.0.2i/crypto/evp/m_dss1.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/m_dss1.c 2016-09-22 13:35:57.013220905 +0200 +@@ -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 -up openssl-1.0.2i/crypto/evp/m_md2.c.fips openssl-1.0.2i/crypto/evp/m_md2.c +--- openssl-1.0.2i/crypto/evp/m_md2.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/m_md2.c 2016-09-22 13:35:57.013220905 +0200 +@@ -68,6 +68,7 @@ + # ifndef OPENSSL_NO_RSA + # include + # endif ++# include "evp_locl.h" + + static int init(EVP_MD_CTX *ctx) + { +diff -up openssl-1.0.2i/crypto/evp/m_sha1.c.fips openssl-1.0.2i/crypto/evp/m_sha1.c +--- openssl-1.0.2i/crypto/evp/m_sha1.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/m_sha1.c 2016-09-22 13:35:57.013220905 +0200 +@@ -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 -up openssl-1.0.2i/crypto/evp/p_sign.c.fips openssl-1.0.2i/crypto/evp/p_sign.c +--- openssl-1.0.2i/crypto/evp/p_sign.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/p_sign.c 2016-09-22 13:35:57.013220905 +0200 +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + #ifdef undef + void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) +@@ -101,6 +102,22 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsig + 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 -up openssl-1.0.2i/crypto/evp/p_verify.c.fips openssl-1.0.2i/crypto/evp/p_verify.c +--- openssl-1.0.2i/crypto/evp/p_verify.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/evp/p_verify.c 2016-09-22 13:35:57.013220905 +0200 +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + 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, con + 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 -up openssl-1.0.2i/crypto/fips/fips_aes_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_aes_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_aes_selftest.c.fips 2016-09-22 13:35:57.013220905 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_aes_selftest.c 2016-09-22 13:35:57.013220905 +0200 +@@ -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 ++#include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++#include ++ ++#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 -up openssl-1.0.2i/crypto/fips/fips.c.fips openssl-1.0.2i/crypto/fips/fips.c +--- openssl-1.0.2i/crypto/fips/fips.c.fips 2016-09-22 13:35:57.014220928 +0200 ++++ openssl-1.0.2i/crypto/fips/fips.c 2016-09-22 13:35:57.014220928 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "fips_locl.h" ++ ++#ifdef OPENSSL_FIPS ++ ++# include ++ ++# ifndef PATH_MAX ++# define PATH_MAX 1024 ++# endif ++ ++static int fips_selftest_fail = 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 -up openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c.fips 2016-09-22 13:35:57.014220928 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_cmac_selftest.c 2016-09-22 13:35:57.014220928 +0200 +@@ -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 ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_des_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_des_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_des_selftest.c.fips 2016-09-22 13:35:57.014220928 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_des_selftest.c 2016-09-22 13:35:57.014220928 +0200 +@@ -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 ++#include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++#include ++#include ++ ++#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 -up openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c +--- openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c.fips 2016-09-22 13:35:57.014220928 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_drbg_ctr.c 2016-09-22 13:35:57.014220928 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_drbg_hash.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_hash.c +--- openssl-1.0.2i/crypto/fips/fips_drbg_hash.c.fips 2016-09-22 13:35:57.014220928 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_drbg_hash.c 2016-09-22 13:35:57.014220928 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c +--- openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c.fips 2016-09-22 13:35:57.015220951 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_drbg_hmac.c 2016-09-22 13:35:57.015220951 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_drbg_lib.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_lib.c +--- openssl-1.0.2i/crypto/fips/fips_drbg_lib.c.fips 2016-09-22 13:35:57.015220951 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_drbg_lib.c 2016-09-22 13:35:57.015220951 +0200 +@@ -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 ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_drbg_rand.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_rand.c +--- openssl-1.0.2i/crypto/fips/fips_drbg_rand.c.fips 2016-09-22 13:35:57.015220951 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_drbg_rand.c 2016-09-22 13:35:57.015220951 +0200 +@@ -0,0 +1,164 @@ ++/* 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 ++#include ++#include ++#include ++#include ++#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; ++ rv = dctx->status == DRBG_STATUS_READY ? 1 : 0; ++ 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 -up openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c.fips 2016-09-22 13:35:57.015220951 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_drbg_selftest.c 2016-09-22 13:35:57.015220951 +0200 +@@ -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 ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h.fips openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h +--- openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h.fips 2016-09-22 13:35:57.016220974 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_drbg_selftest.h 2016-09-22 13:35:57.016220974 +0200 +@@ -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 -up openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c.fips 2016-09-22 13:35:57.016220974 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_dsa_selftest.c 2016-09-22 13:35:57.016220974 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_enc.c.fips openssl-1.0.2i/crypto/fips/fips_enc.c +--- openssl-1.0.2i/crypto/fips/fips_enc.c.fips 2016-09-22 13:35:57.017220997 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_enc.c 2016-09-22 13:35:57.017220997 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++ ++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 -up openssl-1.0.2i/crypto/fips/fips.h.fips openssl-1.0.2i/crypto/fips/fips.h +--- openssl-1.0.2i/crypto/fips/fips.h.fips 2016-09-22 13:35:57.017220997 +0200 ++++ openssl-1.0.2i/crypto/fips/fips.h 2016-09-22 13:35:57.017220997 +0200 +@@ -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 ++#include ++#include ++ ++#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 -up openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c.fips 2016-09-22 13:35:57.017220997 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_hmac_selftest.c 2016-09-22 13:35:57.017220997 +0200 +@@ -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 ++#include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++#include ++ ++#ifdef OPENSSL_FIPS ++typedef struct { ++ const EVP_MD *(*alg) (void); ++ const char *key, *iv; ++ unsigned char kaval[EVP_MAX_MD_SIZE]; ++} HMAC_KAT; ++ ++static const HMAC_KAT vector[] = { ++ {EVP_sha1, ++ /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */ ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0x09, 0x22, 0xd3, 0x40, 0x5f, 0xaa, 0x3d, 0x19, ++ 0x4f, 0x82, 0xa4, 0x58, 0x30, 0x73, 0x7d, 0x5c, ++ 0xc6, 0xc7, 0x5d, 0x24} ++ }, ++ {EVP_sha224, ++ /* just keep extending the above... */ ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0xdd, 0xef, 0x0a, 0x40, 0xcb, 0x7d, 0x50, 0xfb, ++ 0x6e, 0xe6, 0xce, 0xa1, 0x20, 0xba, 0x26, 0xaa, ++ 0x08, 0xf3, 0x07, 0x75, 0x87, 0xb8, 0xad, 0x1b, ++ 0x8c, 0x8d, 0x12, 0xc7} ++ }, ++ {EVP_sha256, ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0xb8, 0xf2, 0x0d, 0xb5, 0x41, 0xea, 0x43, 0x09, ++ 0xca, 0x4e, 0xa9, 0x38, 0x0c, 0xd0, 0xe8, 0x34, ++ 0xf7, 0x1f, 0xbe, 0x91, 0x74, 0xa2, 0x61, 0x38, ++ 0x0d, 0xc1, 0x7e, 0xae, 0x6a, 0x34, 0x51, 0xd9} ++ }, ++ {EVP_sha384, ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0x08, 0xbc, 0xb0, 0xda, 0x49, 0x1e, 0x87, 0xad, ++ 0x9a, 0x1d, 0x6a, 0xce, 0x23, 0xc5, 0x0b, 0xf6, ++ 0xb7, 0x18, 0x06, 0xa5, 0x77, 0xcd, 0x49, 0x04, ++ 0x89, 0xf1, 0xe6, 0x23, 0x44, 0x51, 0x51, 0x9f, ++ 0x85, 0x56, 0x80, 0x79, 0x0c, 0xbd, 0x4d, 0x50, ++ 0xa4, 0x5f, 0x29, 0xe3, 0x93, 0xf0, 0xe8, 0x7f} ++ }, ++ {EVP_sha512, ++ "0123456789:;<=>?@ABC", ++ "Sample #2", ++ {0x80, 0x9d, 0x44, 0x05, 0x7c, 0x5b, 0x95, 0x41, ++ 0x05, 0xbd, 0x04, 0x13, 0x16, 0xdb, 0x0f, 0xac, ++ 0x44, 0xd5, 0xa4, 0xd5, 0xd0, 0x89, 0x2b, 0xd0, ++ 0x4e, 0x86, 0x64, 0x12, 0xc0, 0x90, 0x77, 0x68, ++ 0xf1, 0x87, 0xb7, 0x7c, 0x4f, 0xae, 0x2c, 0x2f, ++ 0x21, 0xa5, 0xb5, 0x65, 0x9a, 0x4f, 0x4b, 0xa7, ++ 0x47, 0x02, 0xa3, 0xde, 0x9b, 0x51, 0xf1, 0x45, ++ 0xbd, 0x4f, 0x25, 0x27, 0x42, 0x98, 0x99, 0x05} ++ }, ++}; ++ ++int FIPS_selftest_hmac() ++{ ++ int n; ++ unsigned int outlen; ++ unsigned char out[EVP_MAX_MD_SIZE]; ++ const EVP_MD *md; ++ const HMAC_KAT *t; ++ ++ for (n = 0, t = vector; 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 -up openssl-1.0.2i/crypto/fips/fips_locl.h.fips openssl-1.0.2i/crypto/fips/fips_locl.h +--- openssl-1.0.2i/crypto/fips/fips_locl.h.fips 2016-09-22 13:35:57.017220997 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_locl.h 2016-09-22 13:35:57.017220997 +0200 +@@ -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 -up openssl-1.0.2i/crypto/fips/fips_md.c.fips openssl-1.0.2i/crypto/fips/fips_md.c +--- openssl-1.0.2i/crypto/fips/fips_md.c.fips 2016-09-22 13:35:57.017220997 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_md.c 2016-09-22 13:35:57.017220997 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++ ++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 -up openssl-1.0.2i/crypto/fips/fips_post.c.fips openssl-1.0.2i/crypto/fips/fips_post.c +--- openssl-1.0.2i/crypto/fips/fips_post.c.fips 2016-09-22 13:35:57.017220997 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_post.c 2016-09-22 13:35:57.017220997 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++/* Power on self test (POST) support functions */ ++ ++# include ++# 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 -up openssl-1.0.2i/crypto/fips/fips_rand.c.fips openssl-1.0.2i/crypto/fips/fips_rand.c +--- openssl-1.0.2i/crypto/fips/fips_rand.c.fips 2016-09-22 13:35:57.018221020 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_rand.c 2016-09-22 13:35:57.018221020 +0200 +@@ -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 ++#include "e_os.h" ++ ++/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't ++ be defined and gettimeofday() won't be declared with strict compilers ++ like DEC C in ANSI C mode. */ ++#ifndef _XOPEN_SOURCE_EXTENDED ++# define _XOPEN_SOURCE_EXTENDED 1 ++#endif ++ ++#include ++#include ++#include ++#include ++#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS)) ++# include ++#endif ++#if defined(OPENSSL_SYS_VXWORKS) ++# include ++#endif ++#include ++#ifndef OPENSSL_SYS_WIN32 ++# ifdef OPENSSL_UNISTD ++# include OPENSSL_UNISTD ++# else ++# include ++# endif ++#endif ++#include ++#include ++#include "fips_locl.h" ++ ++#ifdef OPENSSL_FIPS ++ ++void *OPENSSL_stderr(void); ++ ++# define AES_BLOCK_LENGTH 16 ++ ++/* AES FIPS PRNG implementation */ ++ ++typedef struct { ++ int seeded; ++ int keyed; ++ int test_mode; ++ int second; ++ int error; ++ unsigned long counter; ++ AES_KEY ks; ++ int vpos; ++ /* Temporary storage for key if it equals seed length */ ++ unsigned char tmp_key[AES_BLOCK_LENGTH]; ++ unsigned char V[AES_BLOCK_LENGTH]; ++ unsigned char DT[AES_BLOCK_LENGTH]; ++ unsigned char last[AES_BLOCK_LENGTH]; ++} FIPS_PRNG_CTX; ++ ++static FIPS_PRNG_CTX sctx; ++ ++static int fips_prng_fail = 0; ++ ++void FIPS_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 -up openssl-1.0.2i/crypto/fips/fips_rand.h.fips openssl-1.0.2i/crypto/fips/fips_rand.h +--- openssl-1.0.2i/crypto/fips/fips_rand.h.fips 2016-09-22 13:35:57.018221020 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_rand.h 2016-09-22 13:35:57.018221020 +0200 +@@ -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 ++# include ++# include ++# include ++ ++# 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 -up openssl-1.0.2i/crypto/fips/fips_rand_lcl.h.fips openssl-1.0.2i/crypto/fips/fips_rand_lcl.h +--- openssl-1.0.2i/crypto/fips/fips_rand_lcl.h.fips 2016-09-22 13:35:57.018221020 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_rand_lcl.h 2016-09-22 13:35:57.018221020 +0200 +@@ -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 -up openssl-1.0.2i/crypto/fips/fips_rand_lib.c.fips openssl-1.0.2i/crypto/fips/fips_rand_lib.c +--- openssl-1.0.2i/crypto/fips/fips_rand_lib.c.fips 2016-09-22 13:35:57.018221020 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_rand_lib.c 2016-09-22 13:35:57.018221020 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_rand_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_rand_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_rand_selftest.c.fips 2016-09-22 13:35:57.018221020 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_rand_selftest.c 2016-09-22 13:35:57.018221020 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#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 -up openssl-1.0.2i/crypto/fips/fips_randtest.c.fips openssl-1.0.2i/crypto/fips/fips_randtest.c +--- openssl-1.0.2i/crypto/fips/fips_randtest.c.fips 2016-09-22 13:35:57.018221020 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_randtest.c 2016-09-22 13:35:57.018221020 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "e_os.h" ++ ++#ifndef OPENSSL_FIPS ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS RAND support\n"); ++ return (0); ++} ++ ++#else ++ ++# include "fips_utl.h" ++# include ++ ++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 -up openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c.fips 2016-09-22 13:35:57.019221043 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_rsa_selftest.c 2016-09-22 13:35:57.019221043 +0200 +@@ -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 ++#include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++#include ++#include ++#include ++#include ++ ++#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 -up openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c.fips openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c +--- openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c.fips 2016-09-22 13:35:57.019221043 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_rsa_x931g.c 2016-09-22 13:35:57.019221043 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#ifdef OPENSSL_FIPS ++# include ++ ++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 -up openssl-1.0.2i/crypto/fips/fips_sha_selftest.c.fips openssl-1.0.2i/crypto/fips/fips_sha_selftest.c +--- openssl-1.0.2i/crypto/fips/fips_sha_selftest.c.fips 2016-09-22 13:35:57.019221043 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_sha_selftest.c 2016-09-22 13:35:57.019221043 +0200 +@@ -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 ++#include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++#include ++#include ++ ++#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 -up openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c.fips openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c +--- openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c.fips 2016-09-22 13:35:57.019221043 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_standalone_hmac.c 2016-09-22 13:35:57.019221043 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 []+\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 -up openssl-1.0.2i/crypto/fips/fips_test_suite.c.fips openssl-1.0.2i/crypto/fips/fips_test_suite.c +--- openssl-1.0.2i/crypto/fips/fips_test_suite.c.fips 2016-09-22 13:35:57.020221066 +0200 ++++ openssl-1.0.2i/crypto/fips/fips_test_suite.c 2016-09-22 13:35:57.019221043 +0200 +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS support\n"); ++ return (0); ++} ++#else ++ ++# include ++# include "fips_utl.h" ++ ++/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext ++*/ ++static int FIPS_aes_test(void) ++{ ++ int ret = 0; ++ unsigned char pltmp[16]; ++ unsigned char citmp[16]; ++ unsigned char key[16] = ++ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; ++ unsigned char plaintext[16] = "etaonrishdlcu"; ++ EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX_init(&ctx); ++ if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 1) <= 0) ++ goto err; ++ EVP_Cipher(&ctx, citmp, plaintext, 16); ++ if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, key, NULL, 0) <= 0) ++ goto err; ++ EVP_Cipher(&ctx, pltmp, citmp, 16); ++ if (memcmp(pltmp, plaintext, 16)) ++ goto err; ++ ret = 1; ++ err: ++ EVP_CIPHER_CTX_cleanup(&ctx); ++ return ret; ++} ++ ++static int FIPS_des3_test(void) ++{ ++ int ret = 0; ++ unsigned char pltmp[8]; ++ unsigned char citmp[8]; ++ unsigned char key[] = ++ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ++ 19, 20, 21, 22, 23, 24 ++ }; ++ unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' }; ++ EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX_init(&ctx); ++ if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 1) <= 0) ++ goto err; ++ EVP_Cipher(&ctx, citmp, plaintext, 8); ++ if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, key, NULL, 0) <= 0) ++ goto err; ++ EVP_Cipher(&ctx, pltmp, citmp, 8); ++ if (memcmp(pltmp, plaintext, 8)) ++ goto err; ++ ret = 1; ++ err: ++ EVP_CIPHER_CTX_cleanup(&ctx); ++ return ret; ++} ++ ++/* ++ * DSA: generate keys and sign, verify input plaintext. ++ */ ++static int FIPS_dsa_test(int bad) ++{ ++ DSA *dsa = NULL; ++ EVP_PKEY pk; ++ unsigned char dgst[] = "etaonrishdlc"; ++ unsigned char buf[60]; ++ unsigned int slen; ++ int r = 0; ++ EVP_MD_CTX mctx; ++ ++ ERR_clear_error(); ++ EVP_MD_CTX_init(&mctx); ++ dsa = 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 -up openssl-1.0.2i/crypto/fips/Makefile.fips openssl-1.0.2i/crypto/fips/Makefile +--- openssl-1.0.2i/crypto/fips/Makefile.fips 2016-09-22 13:35:57.020221066 +0200 ++++ openssl-1.0.2i/crypto/fips/Makefile 2016-09-22 13:35:57.020221066 +0200 +@@ -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 -up openssl-1.0.2i/crypto/hmac/hmac.c.fips openssl-1.0.2i/crypto/hmac/hmac.c +--- openssl-1.0.2i/crypto/hmac/hmac.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/hmac/hmac.c 2016-09-22 13:35:57.020221066 +0200 +@@ -89,12 +89,6 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const vo + 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 vo + } + + 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 + + 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 c + { + 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_C + + 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 -up openssl-1.0.2i/crypto/mdc2/mdc2dgst.c.fips openssl-1.0.2i/crypto/mdc2/mdc2dgst.c +--- openssl-1.0.2i/crypto/mdc2/mdc2dgst.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/mdc2/mdc2dgst.c 2016-09-22 13:35:57.020221066 +0200 +@@ -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 -up openssl-1.0.2i/crypto/md2/md2_dgst.c.fips openssl-1.0.2i/crypto/md2/md2_dgst.c +--- openssl-1.0.2i/crypto/md2/md2_dgst.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/md2/md2_dgst.c 2016-09-22 13:35:57.020221066 +0200 +@@ -62,6 +62,11 @@ + #include + #include + #include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++ ++#include + + 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 -up openssl-1.0.2i/crypto/md4/md4_dgst.c.fips openssl-1.0.2i/crypto/md4/md4_dgst.c +--- openssl-1.0.2i/crypto/md4/md4_dgst.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/md4/md4_dgst.c 2016-09-22 13:35:57.020221066 +0200 +@@ -72,7 +72,7 @@ const char MD4_version[] = "MD4" OPENSSL + #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 -up openssl-1.0.2i/crypto/md5/md5_dgst.c.fips openssl-1.0.2i/crypto/md5/md5_dgst.c +--- openssl-1.0.2i/crypto/md5/md5_dgst.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/md5/md5_dgst.c 2016-09-22 13:35:57.020221066 +0200 +@@ -72,7 +72,7 @@ const char MD5_version[] = "MD5" OPENSSL + #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 -up openssl-1.0.2i/crypto/o_fips.c.fips openssl-1.0.2i/crypto/o_fips.c +--- openssl-1.0.2i/crypto/o_fips.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/o_fips.c 2016-09-22 13:35:57.020221066 +0200 +@@ -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 -up openssl-1.0.2i/crypto/o_init.c.fips openssl-1.0.2i/crypto/o_init.c +--- openssl-1.0.2i/crypto/o_init.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/o_init.c 2016-09-22 13:38:19.150496906 +0200 +@@ -56,8 +56,37 @@ + #include + #include + #ifdef OPENSSL_FIPS ++# include ++# include ++# include ++# include ++# include ++# include + # include + # include ++ ++# 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,22 +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); +-# ifndef OPENSSL_NO_DEPRECATED +- FIPS_crypto_set_id_callback(CRYPTO_thread_id); +-# endif +- 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 -up openssl-1.0.2i/crypto/opensslconf.h.in.fips openssl-1.0.2i/crypto/opensslconf.h.in +--- openssl-1.0.2i/crypto/opensslconf.h.in.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/opensslconf.h.in 2016-09-22 13:35:57.021221089 +0200 +@@ -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 -up openssl-1.0.2i/crypto/rand/md_rand.c.fips openssl-1.0.2i/crypto/rand/md_rand.c +--- openssl-1.0.2i/crypto/rand/md_rand.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rand/md_rand.c 2016-09-22 13:35:57.021221089 +0200 +@@ -391,7 +391,10 @@ int ssleay_rand_bytes(unsigned char *buf + 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 -up openssl-1.0.2i/crypto/rand/rand.h.fips openssl-1.0.2i/crypto/rand/rand.h +--- openssl-1.0.2i/crypto/rand/rand.h.fips 2016-09-22 13:35:56.777215465 +0200 ++++ openssl-1.0.2i/crypto/rand/rand.h 2016-09-22 13:35:57.021221089 +0200 +@@ -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 -up openssl-1.0.2i/crypto/ripemd/rmd_dgst.c.fips openssl-1.0.2i/crypto/ripemd/rmd_dgst.c +--- openssl-1.0.2i/crypto/ripemd/rmd_dgst.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/ripemd/rmd_dgst.c 2016-09-22 13:35:57.021221089 +0200 +@@ -70,7 +70,7 @@ void ripemd160_block_x86(RIPEMD160_CTX * + 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 -up openssl-1.0.2i/crypto/rsa/rsa_crpt.c.fips openssl-1.0.2i/crypto/rsa/rsa_crpt.c +--- openssl-1.0.2i/crypto/rsa/rsa_crpt.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa_crpt.c 2016-09-22 13:35:57.021221089 +0200 +@@ -89,9 +89,9 @@ int RSA_private_encrypt(int flen, const + 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 u + 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 -up openssl-1.0.2i/crypto/rsa/rsa_eay.c.fips openssl-1.0.2i/crypto/rsa/rsa_eay.c +--- openssl-1.0.2i/crypto/rsa/rsa_eay.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa_eay.c 2016-09-22 13:35:57.022221112 +0200 +@@ -114,6 +114,10 @@ + #include + #include + #include ++#include ++#ifdef OPENSSL_FIPS ++# include ++#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 fl + 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 f + 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 f + 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 fl + 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, c + + 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 -up openssl-1.0.2i/crypto/rsa/rsa_err.c.fips openssl-1.0.2i/crypto/rsa/rsa_err.c +--- openssl-1.0.2i/crypto/rsa/rsa_err.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa_err.c 2016-09-22 13:35:57.022221112 +0200 +@@ -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 -up openssl-1.0.2i/crypto/rsa/rsa_gen.c.fips openssl-1.0.2i/crypto/rsa/rsa_gen.c +--- openssl-1.0.2i/crypto/rsa/rsa_gen.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa_gen.c 2016-09-22 13:35:57.022221112 +0200 +@@ -69,8 +69,80 @@ + #include + #ifdef OPENSSL_FIPS + # include +-extern int FIPS_rsa_x931_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, +- BN_GENCB *cb); ++# include ++# include ++ ++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 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 bi + #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 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, + 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 -up openssl-1.0.2i/crypto/rsa/rsa.h.fips openssl-1.0.2i/crypto/rsa/rsa.h +--- openssl-1.0.2i/crypto/rsa/rsa.h.fips 2016-09-22 13:35:56.906218439 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa.h 2016-09-22 13:35:57.022221112 +0200 +@@ -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 + + /* 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 -up openssl-1.0.2i/crypto/rsa/rsa_lib.c.fips openssl-1.0.2i/crypto/rsa/rsa_lib.c +--- openssl-1.0.2i/crypto/rsa/rsa_lib.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa_lib.c 2016-09-22 13:35:57.022221112 +0200 +@@ -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_M + * 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); +@@ -166,6 +171,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; +@@ -184,7 +200,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 -up openssl-1.0.2i/crypto/rsa/rsa_pmeth.c.fips openssl-1.0.2i/crypto/rsa/rsa_pmeth.c +--- openssl-1.0.2i/crypto/rsa/rsa_pmeth.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa_pmeth.c 2016-09-22 13:35:57.022221112 +0200 +@@ -228,20 +228,6 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *c + 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 + } + #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 -up openssl-1.0.2i/crypto/rsa/rsa_sign.c.fips openssl-1.0.2i/crypto/rsa/rsa_sign.c +--- openssl-1.0.2i/crypto/rsa/rsa_sign.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rsa/rsa_sign.c 2016-09-22 13:35:57.023221135 +0200 +@@ -132,7 +132,10 @@ int RSA_sign(int type, const unsigned ch + 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 unsi + } + + 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 unsi + 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 -up openssl-1.0.2i/crypto/sha/sha.h.fips openssl-1.0.2i/crypto/sha/sha.h +--- openssl-1.0.2i/crypto/sha/sha.h.fips 2016-09-22 13:35:56.699213667 +0200 ++++ openssl-1.0.2i/crypto/sha/sha.h 2016-09-22 13:35:57.023221135 +0200 +@@ -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 * + 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 -up openssl-1.0.2i/crypto/sha/sha_locl.h.fips openssl-1.0.2i/crypto/sha/sha_locl.h +--- openssl-1.0.2i/crypto/sha/sha_locl.h.fips 2016-09-22 13:35:56.702213737 +0200 ++++ openssl-1.0.2i/crypto/sha/sha_locl.h 2016-09-22 13:35:57.023221135 +0200 +@@ -123,11 +123,14 @@ void sha1_block_data_order(SHA_CTX *c, c + #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 -up openssl-1.0.2i/crypto/sha/sha256.c.fips openssl-1.0.2i/crypto/sha/sha256.c +--- openssl-1.0.2i/crypto/sha/sha256.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/sha/sha256.c 2016-09-22 13:35:57.023221135 +0200 +@@ -12,12 +12,19 @@ + + # include + # include ++# ifdef OPENSSL_FIPS ++# include ++# endif ++ + # include + + 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 -up openssl-1.0.2i/crypto/sha/sha512.c.fips openssl-1.0.2i/crypto/sha/sha512.c +--- openssl-1.0.2i/crypto/sha/sha512.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/sha/sha512.c 2016-09-22 13:35:57.023221135 +0200 +@@ -5,6 +5,10 @@ + * ==================================================================== + */ + #include ++#ifdef OPENSSL_FIPS ++# include ++#endif ++ + #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) + /*- + * IMPLEMENTATION NOTES. +@@ -62,6 +66,9 @@ const char SHA512_version[] = "SHA-512" + + 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 -up openssl-1.0.2i/crypto/whrlpool/wp_dgst.c.fips openssl-1.0.2i/crypto/whrlpool/wp_dgst.c +--- openssl-1.0.2i/crypto/whrlpool/wp_dgst.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/whrlpool/wp_dgst.c 2016-09-22 13:35:57.023221135 +0200 +@@ -56,7 +56,7 @@ + #include + #include + +-fips_md_init(WHIRLPOOL) ++nonfips_md_init(WHIRLPOOL) + { + memset(c, 0, sizeof(*c)); + return (1); +diff -up openssl-1.0.2i/Makefile.org.fips openssl-1.0.2i/Makefile.org +--- openssl-1.0.2i/Makefile.org.fips 2016-09-22 13:35:56.996220513 +0200 ++++ openssl-1.0.2i/Makefile.org 2016-09-22 13:35:57.023221135 +0200 +@@ -138,6 +138,9 @@ FIPSCANLIB= + + BASEADDR= + ++# Non-empty if FIPS enabled ++FIPS= ++ + DIRS= crypto ssl engines apps test tools + ENGDIRS= ccgost + SHLIBDIRS= crypto ssl +@@ -150,7 +153,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... + +@@ -241,6 +244,7 @@ BUILDENV= LC_ALL=C PLATFORM='$(PLATFORM) + 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 -up openssl-1.0.2i/ssl/ssl_algs.c.fips openssl-1.0.2i/ssl/ssl_algs.c +--- openssl-1.0.2i/ssl/ssl_algs.c.fips 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/ssl/ssl_algs.c 2016-09-22 13:35:57.024221158 +0200 +@@ -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 diff --git a/openssl-1.0.2i-trusted-first-doc.patch b/openssl-1.0.2i-trusted-first-doc.patch new file mode 100644 index 0000000..12ea01e --- /dev/null +++ b/openssl-1.0.2i-trusted-first-doc.patch @@ -0,0 +1,286 @@ +diff -up openssl-1.0.2i/apps/cms.c.trusted-first openssl-1.0.2i/apps/cms.c +--- openssl-1.0.2i/apps/cms.c.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/apps/cms.c 2016-09-22 14:01:27.436630359 +0200 +@@ -646,6 +646,8 @@ int MAIN(int argc, char **argv) + "-CApath dir trusted certificates directory\n"); + BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); + BIO_printf(bio_err, ++ "-trusted_first use trusted certificates first when building the trust chain\n"); ++ BIO_printf(bio_err, + "-no_alt_chains only ever use the first certificate chain found\n"); + BIO_printf(bio_err, + "-crl_check check revocation status of signer's certificate using CRLs\n"); +diff -up openssl-1.0.2i/apps/ocsp.c.trusted-first openssl-1.0.2i/apps/ocsp.c +--- openssl-1.0.2i/apps/ocsp.c.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/apps/ocsp.c 2016-09-22 14:01:27.436630359 +0200 +@@ -537,6 +537,8 @@ int MAIN(int argc, char **argv) + BIO_printf(bio_err, + "-CAfile file trusted certificates file\n"); + BIO_printf(bio_err, ++ "-trusted_first use trusted certificates first when building the trust chain\n"); ++ BIO_printf(bio_err, + "-no_alt_chains only ever use the first certificate chain found\n"); + BIO_printf(bio_err, + "-VAfile file validator certificates file\n"); +diff -up openssl-1.0.2i/apps/s_client.c.trusted-first openssl-1.0.2i/apps/s_client.c +--- openssl-1.0.2i/apps/s_client.c.trusted-first 2016-09-22 14:01:27.402629569 +0200 ++++ openssl-1.0.2i/apps/s_client.c 2016-09-22 14:01:27.436630359 +0200 +@@ -330,6 +330,8 @@ static void sc_usage(void) + BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); + BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); + BIO_printf(bio_err, ++ " -trusted_first - Use trusted CA's first when building the trust chain\n"); ++ BIO_printf(bio_err, + " -no_alt_chains - only ever use the first certificate chain found\n"); + BIO_printf(bio_err, + " -reconnect - Drop and re-make the connection with the same Session-ID\n"); +diff -up openssl-1.0.2i/apps/smime.c.trusted-first openssl-1.0.2i/apps/smime.c +--- openssl-1.0.2i/apps/smime.c.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/apps/smime.c 2016-09-22 14:01:27.436630359 +0200 +@@ -442,6 +442,8 @@ int MAIN(int argc, char **argv) + "-CApath dir trusted certificates directory\n"); + BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); + BIO_printf(bio_err, ++ "-trusted_first use trusted certificates first when building the trust chain\n"); ++ BIO_printf(bio_err, + "-no_alt_chains only ever use the first certificate chain found\n"); + BIO_printf(bio_err, + "-crl_check check revocation status of signer's certificate using CRLs\n"); +diff -up openssl-1.0.2i/apps/s_server.c.trusted-first openssl-1.0.2i/apps/s_server.c +--- openssl-1.0.2i/apps/s_server.c.trusted-first 2016-09-22 14:01:27.374628918 +0200 ++++ openssl-1.0.2i/apps/s_server.c 2016-09-22 14:01:27.437630382 +0200 +@@ -571,6 +571,8 @@ static void sv_usage(void) + BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); + BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); + BIO_printf(bio_err, ++ " -trusted_first - Use trusted CA's first when building the trust chain\n"); ++ BIO_printf(bio_err, + " -no_alt_chains - only ever use the first certificate chain found\n"); + BIO_printf(bio_err, + " -nocert - Don't use any certificates (Anon-DH)\n"); +diff -up openssl-1.0.2i/apps/s_time.c.trusted-first openssl-1.0.2i/apps/s_time.c +--- openssl-1.0.2i/apps/s_time.c.trusted-first 2016-09-22 14:01:27.368628779 +0200 ++++ openssl-1.0.2i/apps/s_time.c 2016-09-22 14:01:27.437630382 +0200 +@@ -182,6 +182,7 @@ static void s_time_usage(void) + file if not specified by this option\n\ + -CApath arg - PEM format directory of CA's\n\ + -CAfile arg - PEM format file of CA's\n\ ++-trusted_first - Use trusted CA's first when building the trust chain\n\ + -cipher - preferred cipher to use, play with 'openssl ciphers'\n\n"; + + printf("usage: s_time \n\n"); +diff -up openssl-1.0.2i/apps/ts.c.trusted-first openssl-1.0.2i/apps/ts.c +--- openssl-1.0.2i/apps/ts.c.trusted-first 2016-09-22 14:01:27.400629522 +0200 ++++ openssl-1.0.2i/apps/ts.c 2016-09-22 14:01:27.437630382 +0200 +@@ -352,7 +352,7 @@ int MAIN(int argc, char **argv) + "ts -verify [-data file_to_hash] [-digest digest_bytes] " + "[-queryfile request.tsq] " + "-in response.tsr [-token_in] " +- "-CApath ca_path -CAfile ca_file.pem " ++ "-CApath ca_path -CAfile ca_file.pem -trusted_first" + "-untrusted cert_file.pem\n"); + cleanup: + /* Clean up. */ +diff -up openssl-1.0.2i/apps/verify.c.trusted-first openssl-1.0.2i/apps/verify.c +--- openssl-1.0.2i/apps/verify.c.trusted-first 2016-09-22 14:01:27.438630405 +0200 ++++ openssl-1.0.2i/apps/verify.c 2016-09-22 14:02:37.951269140 +0200 +@@ -231,7 +231,7 @@ int MAIN(int argc, char **argv) + usage: + if (ret == 1) { + BIO_printf(bio_err, +- "usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]"); ++ "usage: verify [-verbose] [-CApath path] [-CAfile file] [-trusted_first] [-purpose purpose] [-crl_check]"); + BIO_printf(bio_err, " [-no_alt_chains] [-attime timestamp]"); + #ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err, " [-engine e]"); +diff -up openssl-1.0.2i/doc/apps/cms.pod.trusted-first openssl-1.0.2i/doc/apps/cms.pod +--- openssl-1.0.2i/doc/apps/cms.pod.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/doc/apps/cms.pod 2016-09-22 14:01:27.438630405 +0200 +@@ -35,6 +35,7 @@ B B + [B<-print>] + [B<-CAfile file>] + [B<-CApath dir>] ++[B<-trusted_first>] + [B<-no_alt_chains>] + [B<-md digest>] + [B<-[cipher]>] +@@ -248,6 +249,12 @@ B<-verify>. This directory must be a sta + is a hash of each subject name (using B) should be linked + to each certificate. + ++=item B<-trusted_first> ++ ++Use certificates in CA file or CA directory before untrusted certificates ++from the message when building the trust chain to verify certificates. ++This is mainly useful in environments with Bridge CA or Cross-Certified CAs. ++ + =item B<-md digest> + + digest algorithm to use when signing or resigning. If not present then the +diff -up openssl-1.0.2i/doc/apps/ocsp.pod.trusted-first openssl-1.0.2i/doc/apps/ocsp.pod +--- openssl-1.0.2i/doc/apps/ocsp.pod.trusted-first 2016-09-22 14:01:27.401629545 +0200 ++++ openssl-1.0.2i/doc/apps/ocsp.pod 2016-09-22 14:01:27.438630405 +0200 +@@ -29,6 +29,7 @@ B B + [B<-path>] + [B<-CApath dir>] + [B<-CAfile file>] ++[B<-trusted_first>] + [B<-no_alt_chains>] + [B<-VAfile file>] + [B<-validity_period n>] +@@ -144,6 +145,13 @@ connection timeout to the OCSP responder + file or pathname containing trusted CA certificates. These are used to verify + the signature on the OCSP response. + ++=item B<-trusted_first> ++ ++Use certificates in CA file or CA directory over certificates provided ++in the response or residing in other certificates file when building the trust ++chain to verify responder certificate. ++This is mainly useful in environments with Bridge CA or Cross-Certified CAs. ++ + =item B<-no_alt_chains> + + See L|verify(1)> manual page for details. +diff -up openssl-1.0.2i/doc/apps/s_client.pod.trusted-first openssl-1.0.2i/doc/apps/s_client.pod +--- openssl-1.0.2i/doc/apps/s_client.pod.trusted-first 2016-09-22 14:01:27.412629801 +0200 ++++ openssl-1.0.2i/doc/apps/s_client.pod 2016-09-22 14:01:27.438630405 +0200 +@@ -19,6 +19,7 @@ B B + [B<-pass arg>] + [B<-CApath directory>] + [B<-CAfile filename>] ++[B<-trusted_first>] + [B<-no_alt_chains>] + [B<-reconnect>] + [B<-pause>] +@@ -125,7 +126,7 @@ also used when building the client certi + A file containing trusted certificates to use during server authentication + and to use when attempting to build the client certificate chain. + +-=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains> ++=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig, -trusted_first -no_alt_chains> + + Set various certificate chain valiadition option. See the + L|verify(1)> manual page for details. +diff -up openssl-1.0.2i/doc/apps/smime.pod.trusted-first openssl-1.0.2i/doc/apps/smime.pod +--- openssl-1.0.2i/doc/apps/smime.pod.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/doc/apps/smime.pod 2016-09-22 14:01:27.438630405 +0200 +@@ -15,6 +15,9 @@ B B + [B<-pk7out>] + [B<-[cipher]>] + [B<-in file>] ++[B<-CAfile file>] ++[B<-CApath dir>] ++[B<-trusted_first>] + [B<-no_alt_chains>] + [B<-certfile file>] + [B<-signer file>] +@@ -150,6 +153,12 @@ B<-verify>. This directory must be a sta + is a hash of each subject name (using B) should be linked + to each certificate. + ++=item B<-trusted_first> ++ ++Use certificates in CA file or CA directory over certificates provided ++in the message when building the trust chain to verify a certificate. ++This is mainly useful in environments with Bridge CA or Cross-Certified CAs. ++ + =item B<-md digest> + + digest algorithm to use when signing or resigning. If not present then the +diff -up openssl-1.0.2i/doc/apps/s_server.pod.trusted-first openssl-1.0.2i/doc/apps/s_server.pod +--- openssl-1.0.2i/doc/apps/s_server.pod.trusted-first 2016-09-22 14:01:27.412629801 +0200 ++++ openssl-1.0.2i/doc/apps/s_server.pod 2016-09-22 14:01:27.438630405 +0200 +@@ -33,6 +33,7 @@ B B + [B<-state>] + [B<-CApath directory>] + [B<-CAfile filename>] ++[B<-trusted_first>] + [B<-no_alt_chains>] + [B<-nocert>] + [B<-cipher cipherlist>] +@@ -178,6 +179,12 @@ and to use when attempting to build the + is also used in the list of acceptable client CAs passed to the client when + a certificate is requested. + ++=item B<-trusted_first> ++ ++Use certificates in CA file or CA directory before other certificates ++when building the trust chain to verify client certificates. ++This is mainly useful in environments with Bridge CA or Cross-Certified CAs. ++ + =item B<-no_alt_chains> + + See the L|verify(1)> manual page for details. +diff -up openssl-1.0.2i/doc/apps/s_time.pod.trusted-first openssl-1.0.2i/doc/apps/s_time.pod +--- openssl-1.0.2i/doc/apps/s_time.pod.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/doc/apps/s_time.pod 2016-09-22 14:01:27.439630429 +0200 +@@ -14,6 +14,7 @@ B B + [B<-key filename>] + [B<-CApath directory>] + [B<-CAfile filename>] ++[B<-trusted_first>] + [B<-reuse>] + [B<-new>] + [B<-verify depth>] +@@ -76,6 +77,12 @@ also used when building the client certi + A file containing trusted certificates to use during server authentication + and to use when attempting to build the client certificate chain. + ++=item B<-trusted_first> ++ ++Use certificates in CA file or CA directory over the certificates provided ++by the server when building the trust chain to verify server certificate. ++This is mainly useful in environments with Bridge CA or Cross-Certified CAs. ++ + =item B<-new> + + performs the timing test using a new session ID for each connection. +diff -up openssl-1.0.2i/doc/apps/ts.pod.trusted-first openssl-1.0.2i/doc/apps/ts.pod +--- openssl-1.0.2i/doc/apps/ts.pod.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/doc/apps/ts.pod 2016-09-22 14:01:27.439630429 +0200 +@@ -46,6 +46,7 @@ B<-verify> + [B<-token_in>] + [B<-CApath> trusted_cert_path] + [B<-CAfile> trusted_certs.pem] ++[B<-trusted_first>] + [B<-untrusted> cert_file.pem] + + =head1 DESCRIPTION +@@ -324,6 +325,12 @@ L for additional de + or B<-CApath> must be specified. + (Optional) + ++=item B<-trusted_first> ++ ++Use certificates in CA file or CA directory before other certificates ++when building the trust chain to verify certificates. ++This is mainly useful in environments with Bridge CA or Cross-Certified CAs. ++ + =item B<-untrusted> cert_file.pem + + Set of additional untrusted certificates in PEM format which may be +diff -up openssl-1.0.2i/doc/apps/verify.pod.trusted-first openssl-1.0.2i/doc/apps/verify.pod +--- openssl-1.0.2i/doc/apps/verify.pod.trusted-first 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/doc/apps/verify.pod 2016-09-22 14:01:27.439630429 +0200 +@@ -9,6 +9,7 @@ verify - Utility to verify certificates. + B B + [B<-CApath directory>] + [B<-CAfile file>] ++[B<-trusted_first>] + [B<-purpose purpose>] + [B<-policy arg>] + [B<-ignore_critical>] +@@ -86,6 +87,12 @@ If a valid CRL cannot be found an error + A file of untrusted certificates. The file should contain multiple certificates + in PEM format concatenated together. + ++=item B<-trusted_first> ++ ++Use certificates in CA file or CA directory before the certificates in the untrusted ++file when building the trust chain to verify certificates. ++This is mainly useful in environments with Bridge CA or Cross-Certified CAs. ++ + =item B<-purpose purpose> + + The intended use for the certificate. If this option is not specified, diff --git a/openssl-1.0.2j-deprecate-algos.patch b/openssl-1.0.2j-deprecate-algos.patch new file mode 100644 index 0000000..edb6889 --- /dev/null +++ b/openssl-1.0.2j-deprecate-algos.patch @@ -0,0 +1,229 @@ +diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c +index 3ffd934..23271be 100644 +--- a/crypto/asn1/a_verify.c ++++ b/crypto/asn1/a_verify.c +@@ -56,6 +56,9 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE ++ + #include + #include + +@@ -133,6 +136,30 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, + + #endif + ++static int legacy_mds[] = { NID_md5, NID_sha, NID_md4, NID_md2, 0 }; ++extern int private_ossl_allowed_legacy_mds[]; ++ ++static int is_md_legacy_disallowed(int mdnid) ++{ ++ int i; ++ ++ if (mdnid == NID_md5 && secure_getenv("OPENSSL_ENABLE_MD5_VERIFY") != NULL) ++ return 0; ++ ++ for (i = 0; legacy_mds[i] != 0; ++i) { ++ if (mdnid == legacy_mds[i]) { ++ int j; ++ ++ for (j = 0; private_ossl_allowed_legacy_mds[j] != 0; ++j) { ++ if (mdnid == private_ossl_allowed_legacy_mds[j]) ++ return 0; ++ } ++ return 1; ++ } ++ } ++ return 0; ++} ++ + int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) + { +@@ -174,6 +201,10 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + if (ret != 2) + goto err; + ret = -1; ++ } else if (is_md_legacy_disallowed(mdnid)) { ++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ++ ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); ++ goto err; + } else { + const EVP_MD *type; + type = EVP_get_digestbynid(mdnid); +diff --git a/crypto/o_init.c b/crypto/o_init.c +index 2f754ef..59439c2 100644 +--- a/crypto/o_init.c ++++ b/crypto/o_init.c +@@ -55,6 +55,12 @@ + + #include + #include ++# include ++# include ++# include ++# include ++# include ++# include + #ifdef OPENSSL_FIPS + # include + # include +@@ -89,6 +95,121 @@ static void init_fips_mode(void) + } + #endif + ++# define LEGACY_SETTINGS_FILE "/etc/pki/tls/legacy-settings" ++ ++# define NUM_MAX_LEGACY_MDS 8 ++ ++int private_ossl_allowed_legacy_mds[NUM_MAX_LEGACY_MDS + 1]; /* zero terminated */ ++ ++int private_ossl_minimum_dh_bits; ++ ++#if !defined(_WIN32) ++static void parse_legacy_mds(char *p) ++{ ++ int idx = 0; ++ char *e = p; ++ ++ while (p[0] != '\0') { ++ while (e[0] != '\0' && !isspace(e[0]) && e[0] != ',') { ++ ++e; ++ } ++ if (e[0] != '\0') { ++ e[0] = '\0'; ++ ++e; ++ } ++ ++ if (strcasecmp(p, "md5") == 0) { ++ private_ossl_allowed_legacy_mds[idx++] = NID_md5; ++ } else if (strcasecmp(p, "md4") == 0) { ++ private_ossl_allowed_legacy_mds[idx++] = NID_md4; ++ } else if (strcasecmp(p, "sha") == 0) { ++ private_ossl_allowed_legacy_mds[idx++] = NID_sha; ++ } else if (strcasecmp(p, "md2") == 0) { ++ private_ossl_allowed_legacy_mds[idx++] = NID_md2; ++ } ++ ++ if (idx >= ++ sizeof(private_ossl_allowed_legacy_mds) / ++ sizeof(private_ossl_allowed_legacy_mds[0])) { ++ break; ++ } ++ ++ while (e[0] == ',' || isspace(e[0])) { ++ ++e; ++ } ++ ++ p = e; ++ } ++} ++ ++static void parse_minimum_dh_bits(char *p) ++{ ++ private_ossl_minimum_dh_bits = strtol(p, NULL, 10); ++ if (private_ossl_minimum_dh_bits < 512 ++ || private_ossl_minimum_dh_bits > OPENSSL_DH_MAX_MODULUS_BITS) { ++ /* use default */ ++ private_ossl_minimum_dh_bits = 0; ++ } ++} ++ ++static void load_legacy_settings(void) ++{ ++ FILE *f; ++ char *line = NULL; ++ size_t len = 0; ++ ++ if ((f = fopen(LEGACY_SETTINGS_FILE, "r")) == NULL) { ++ return; ++ } ++ ++ while (getline(&line, &len, f) > 0) { ++ char *p = line, *e, *val; ++ ++ /* skip initial whitespace */ ++ while (isspace(p[0])) { ++ ++p; ++ } ++ ++ e = p; ++ ++ while (e[0] != '\0' && !isspace(e[0])) { ++ ++e; ++ } ++ ++ /* terminate name, skip whitespace between name and value */ ++ if (e[0] != '\0') { ++ e[0] = '\0'; ++ ++e; ++ while (isspace(e[0])) { ++ ++e; ++ } ++ } ++ ++ val = e; ++ ++ e = e + strlen(val); ++ ++ /* trim terminating whitespace */ ++ while (e > val) { ++ --e; ++ if (isspace(e[0])) { ++ e[0] = '\0'; ++ } else { ++ break; ++ } ++ } ++ ++ if (strcasecmp(p, "LegacySigningMDs") == 0) { ++ parse_legacy_mds(val); ++ } else if (strcasecmp(line, "MinimumDHBits") == 0) { ++ parse_minimum_dh_bits(val); ++ } ++ /* simply skip other unrecognized lines */ ++ } ++ (void)fclose(f); ++} ++#endif ++ + /* + * Perform any essential OpenSSL initialization operations. Currently only + * sets FIPS callbacks +@@ -100,6 +221,10 @@ void OPENSSL_init_library(void) + if (done) + return; + done = 1; ++ ++#if !defined(_WIN32) ++ load_legacy_settings(); ++#endif + #ifdef OPENSSL_FIPS + RAND_init_fips(); + init_fips_mode(); +diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c +index 32f2f1a..6734e8a 100644 +--- a/ssl/s3_clnt.c ++++ b/ssl/s3_clnt.c +@@ -3500,6 +3500,8 @@ int ssl3_send_client_certificate(SSL *s) + + #define has_bits(i,m) (((i)&(m)) == (m)) + ++extern int private_ossl_minimum_dh_bits; ++ + int ssl3_check_cert_and_algorithm(SSL *s) + { + int i, idx; +@@ -3630,8 +3632,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) + DH_free(dh_srvr); + } + +- if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 1024) +- || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { ++ if (dh_size < (private_ossl_minimum_dh_bits ? private_ossl_minimum_dh_bits : 1024)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); + goto f_err; + } diff --git a/openssl-1.0.2j-downgrade-strength.patch b/openssl-1.0.2j-downgrade-strength.patch new file mode 100644 index 0000000..6e9e387 --- /dev/null +++ b/openssl-1.0.2j-downgrade-strength.patch @@ -0,0 +1,138 @@ +diff -up openssl-1.0.2j/ssl/s3_lib.c.downgrade-strength openssl-1.0.2j/ssl/s3_lib.c +--- openssl-1.0.2j/ssl/s3_lib.c.downgrade-strength 2017-01-05 17:23:21.091203023 +0100 ++++ openssl-1.0.2j/ssl/s3_lib.c 2017-01-05 17:36:37.250194225 +0100 +@@ -227,7 +227,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -243,7 +243,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -278,7 +278,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + #endif +@@ -575,7 +575,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -730,7 +730,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -746,7 +746,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -796,7 +796,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -812,7 +812,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -1429,7 +1429,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + #endif +@@ -1714,7 +1714,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -2106,7 +2106,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -2186,7 +2186,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -2266,7 +2266,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -2346,7 +2346,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + +@@ -2426,7 +2426,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, +- 128, ++ 112, + 128, + }, + diff --git a/openssl-1.0.2j-krb5keytab.patch b/openssl-1.0.2j-krb5keytab.patch new file mode 100644 index 0000000..9feb8cf --- /dev/null +++ b/openssl-1.0.2j-krb5keytab.patch @@ -0,0 +1,172 @@ +diff -up openssl-1.0.2j/apps/s_client.c.krb5keytab openssl-1.0.2j/apps/s_client.c +--- openssl-1.0.2j/apps/s_client.c.krb5keytab 2017-01-05 17:02:05.481441088 +0100 ++++ openssl-1.0.2j/apps/s_client.c 2017-01-05 17:08:28.311073180 +0100 +@@ -171,6 +171,10 @@ typedef unsigned int u_int; + #include "s_apps.h" + #include "timeouts.h" + ++#ifndef OPENSSL_NO_KRB5 ++static char *krb5svc = NULL; ++#endif ++ + #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) + /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ + # undef FIONBIO +@@ -400,6 +404,9 @@ static void sc_usage(void) + BIO_printf(bio_err, + " only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n"); + BIO_printf(bio_err, " are supported.\n"); ++#ifndef OPENSSL_NO_KRB5 ++ BIO_printf(bio_err, " -krb5svc arg - Kerberos service name\n"); ++#endif + #ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err, + " -engine id - Initialise and use the specified engine\n"); +@@ -1069,6 +1076,13 @@ int MAIN(int argc, char **argv) + c_nbio = 1; + } + #endif ++#ifndef OPENSSL_NO_KRB5 ++ else if (strcmp(*argv, "-krb5svc") == 0) { ++ if (--argc < 1) ++ goto bad; ++ krb5svc= *(++argv); ++ } ++#endif + else if (strcmp(*argv, "-starttls") == 0) { + if (--argc < 1) + goto bad; +@@ -1435,6 +1449,8 @@ int MAIN(int argc, char **argv) + if (con && (kctx = kssl_ctx_new()) != NULL) { + SSL_set0_kssl_ctx(con, kctx); + kssl_ctx_setstring(kctx, KSSL_SERVER, host); ++ if (krb5svc != NULL) ++ kssl_ctx_setstring(kctx, KSSL_SERVICE, krb5svc); + } + #endif /* OPENSSL_NO_KRB5 */ + /* SSL_set_cipher_list(con,"RC4-MD5"); */ +diff -up openssl-1.0.2j/apps/s_server.c.krb5keytab openssl-1.0.2j/apps/s_server.c +--- openssl-1.0.2j/apps/s_server.c.krb5keytab 2017-01-05 17:02:05.482441111 +0100 ++++ openssl-1.0.2j/apps/s_server.c 2017-01-05 17:16:36.458078609 +0100 +@@ -206,6 +206,11 @@ typedef unsigned int u_int; + # include + #endif + ++#ifndef OPENSSL_NO_KRB5 ++static char *krb5svc = NULL; ++static char *keytab = NULL; ++#endif ++ + #ifndef OPENSSL_NO_RSA + static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); + #endif +@@ -579,6 +584,10 @@ static void sv_usage(void) + BIO_printf(bio_err, " -serverpref - Use server's cipher preferences\n"); + BIO_printf(bio_err, " -quiet - No server output\n"); + BIO_printf(bio_err, " -no_tmp_rsa - Do not generate a tmp RSA key\n"); ++#ifndef OPENSSL_NO_KRB5 ++ BIO_printf(bio_err, " -krb5svc arg - Kerberos service name\n"); ++ BIO_printf(bio_err, " -keytab arg - Kerberos keytab filename\n"); ++#endif + #ifndef OPENSSL_NO_PSK + BIO_printf(bio_err, " -psk_hint arg - PSK identity hint to use\n"); + BIO_printf(bio_err, " -psk arg - PSK in hex (without 0x)\n"); +@@ -1326,6 +1335,17 @@ int MAIN(int argc, char *argv[]) + goto bad; + vfyCAfile = *(++argv); + } ++#ifndef OPENSSL_NO_KRB5 ++ else if (strcmp(*argv, "-krb5svc") == 0) { ++ if (--argc < 1) ++ goto bad; ++ krb5svc = *(++argv); ++ } else if (strcmp(*argv, "-keytab") == 0) { ++ if (--argc < 1) ++ goto bad; ++ keytab = *(++argv); ++ } ++#endif + #ifdef FIONBIO + else if (strcmp(*argv, "-nbio") == 0) { + s_nbio = 1; +@@ -2226,8 +2246,10 @@ static int sv_body(char *hostname, int s + #ifndef OPENSSL_NO_KRB5 + if ((kctx = kssl_ctx_new()) != NULL) { + SSL_set0_kssl_ctx(con, kctx); +- kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC); +- kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB); ++ kssl_ctx_setstring(kctx, KSSL_SERVICE, ++ krb5svc == NULL ? KRB5SVC : krb5svc); ++ if (keytab != NULL) ++ kssl_ctx_setstring(kctx, KSSL_KEYTAB, keytab); + } + #endif /* OPENSSL_NO_KRB5 */ + if (context) +@@ -2836,8 +2858,11 @@ static int www_body(char *hostname, int + #endif + #ifndef OPENSSL_NO_KRB5 + if ((kctx = kssl_ctx_new()) != NULL) { +- kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC); +- kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB); ++ SSL_set0_kssl_ctx(con, kctx); ++ kssl_ctx_setstring(kctx, KSSL_SERVICE, ++ krb5svc == NULL ? KRB5SVC : krb5svc); ++ if (keytab != NULL) ++ kssl_ctx_setstring(kctx, KSSL_KEYTAB, keytab); + } + #endif /* OPENSSL_NO_KRB5 */ + if (context) +diff -up openssl-1.0.2j/doc/apps/s_client.pod.krb5keytab openssl-1.0.2j/doc/apps/s_client.pod +--- openssl-1.0.2j/doc/apps/s_client.pod.krb5keytab 2016-09-26 11:49:07.000000000 +0200 ++++ openssl-1.0.2j/doc/apps/s_client.pod 2017-01-05 17:21:30.562709291 +0100 +@@ -43,6 +43,7 @@ B B + [B<-fallback_scsv>] + [B<-bugs>] + [B<-cipher cipherlist>] ++[B<-krb5svc service>] + [B<-serverpref>] + [B<-starttls protocol>] + [B<-engine id>] +@@ -228,6 +229,12 @@ command for more information. + + use the server's cipher preferences; only used for SSLV2. + ++=item B<-krb5svc service> ++ ++the Kerberos service name to use (default "host"). This means s_server ++will expect a ticket for the principal I/hostname@REALM, and will ++need keys for that principal in its keytab. ++ + =item B<-starttls protocol> + + send the protocol-specific message(s) to switch to TLS for communication. +diff -up openssl-1.0.2j/doc/apps/s_server.pod.krb5keytab openssl-1.0.2j/doc/apps/s_server.pod +--- openssl-1.0.2j/doc/apps/s_server.pod.krb5keytab 2017-01-05 17:02:05.482441111 +0100 ++++ openssl-1.0.2j/doc/apps/s_server.pod 2017-01-05 17:20:54.769902331 +0100 +@@ -37,6 +37,8 @@ B B + [B<-nocert>] + [B<-cipher cipherlist>] + [B<-serverpref>] ++[B<-krb5svc service>] ++[B<-keytab filename>] + [B<-quiet>] + [B<-no_tmp_rsa>] + [B<-ssl2>] +@@ -246,6 +248,17 @@ the B command for more informat + + use the server's cipher preferences, rather than the client's preferences. + ++=item B<-krb5svc service> ++ ++the Kerberos service name to use (default "host"). This means s_server ++will expect a ticket for the principal I/hostname@REALM, and will ++need keys for that principal in its keytab. ++ ++=item B<-keytab filename> ++ ++the Kerberos "keytab" (key table) file, containing keys for the s_server ++service principal (Kerberos identity; see -krb5svc). ++ + =item B<-tlsextdebug> + + print out a hex dump of any TLS extensions received from the server. diff --git a/openssl-1.0.2k-backports.patch b/openssl-1.0.2k-backports.patch new file mode 100644 index 0000000..4d1e578 --- /dev/null +++ b/openssl-1.0.2k-backports.patch @@ -0,0 +1,244 @@ +diff -up openssl-1.0.2k/crypto/aes/asm/aesni-sha1-x86_64.pl.backports openssl-1.0.2k/crypto/aes/asm/aesni-sha1-x86_64.pl +--- openssl-1.0.2k/crypto/aes/asm/aesni-sha1-x86_64.pl.backports 2017-03-09 17:59:26.367233931 +0100 ++++ openssl-1.0.2k/crypto/aes/asm/aesni-sha1-x86_64.pl 2017-03-27 15:25:28.615014528 +0200 +@@ -1702,6 +1702,7 @@ $code.=<<___; + mov 240($key),$rounds + sub $in0,$out + movups ($key),$rndkey0 # $key[0] ++ movups ($ivp),$iv # load IV + movups 16($key),$rndkey[0] # forward reference + lea 112($key),$key # size optimization + +diff -up openssl-1.0.2k/crypto/aes/asm/aesni-sha256-x86_64.pl.backports openssl-1.0.2k/crypto/aes/asm/aesni-sha256-x86_64.pl +--- openssl-1.0.2k/crypto/aes/asm/aesni-sha256-x86_64.pl.backports 2017-03-09 17:59:26.369233978 +0100 ++++ openssl-1.0.2k/crypto/aes/asm/aesni-sha256-x86_64.pl 2017-03-27 15:25:28.618014599 +0200 +@@ -1299,6 +1299,7 @@ $code.=<<___; + mov 240($key),$rounds + sub $in0,$out + movups ($key),$rndkey0 # $key[0] ++ movups ($ivp),$iv # load IV + movups 16($key),$rndkey[0] # forward reference + lea 112($key),$key # size optimization + +diff -up openssl-1.0.2k/crypto/x86cpuid.pl.backports openssl-1.0.2k/crypto/x86cpuid.pl +--- openssl-1.0.2k/crypto/x86cpuid.pl.backports 2017-03-09 17:59:26.339233278 +0100 ++++ openssl-1.0.2k/crypto/x86cpuid.pl 2017-03-27 15:26:06.833916588 +0200 +@@ -20,10 +20,10 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA3 + &pop ("eax"); + &xor ("ecx","eax"); + &xor ("eax","eax"); ++ &mov ("esi",&wparam(0)); ++ &mov (&DWP(8,"esi"),"eax"); # clear extended feature flags + &bt ("ecx",21); + &jnc (&label("nocpuid")); +- &mov ("esi",&wparam(0)); +- &mov (&DWP(8,"esi"),"eax"); # clear 3rd word + &cpuid (); + &mov ("edi","eax"); # max value for standard query level + +@@ -81,26 +81,16 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA3 + &jmp (&label("generic")); + + &set_label("intel"); +- &cmp ("edi",7); +- &jb (&label("cacheinfo")); +- +- &mov ("esi",&wparam(0)); +- &mov ("eax",7); +- &xor ("ecx","ecx"); +- &cpuid (); +- &mov (&DWP(8,"esi"),"ebx"); +- +-&set_label("cacheinfo"); + &cmp ("edi",4); +- &mov ("edi",-1); ++ &mov ("esi",-1); + &jb (&label("nocacheinfo")); + + &mov ("eax",4); + &mov ("ecx",0); # query L1D + &cpuid (); +- &mov ("edi","eax"); +- &shr ("edi",14); +- &and ("edi",0xfff); # number of cores -1 per L1D ++ &mov ("esi","eax"); ++ &shr ("esi",14); ++ &and ("esi",0xfff); # number of cores -1 per L1D + + &set_label("nocacheinfo"); + &mov ("eax",1); +@@ -118,7 +108,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA3 + &bt ("edx",28); # test hyper-threading bit + &jnc (&label("generic")); + &and ("edx",0xefffffff); +- &cmp ("edi",0); ++ &cmp ("esi",0); + &je (&label("generic")); + + &or ("edx",0x10000000); +@@ -130,10 +120,19 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA3 + &set_label("generic"); + &and ("ebp",1<<11); # isolate AMD XOP flag + &and ("ecx",0xfffff7ff); # force 11th bit to 0 +- &mov ("esi","edx"); ++ &mov ("esi","edx"); # %ebp:%esi is copy of %ecx:%edx + &or ("ebp","ecx"); # merge AMD XOP flag + +- &bt ("ecx",27); # check OSXSAVE bit ++ &cmp ("edi",7); ++ &mov ("edi",&wparam(0)); ++ &jb (&label("no_extended_info")); ++ &mov ("eax",7); ++ &xor ("ecx","ecx"); ++ &cpuid (); ++ &mov (&DWP(8,"edi"),"ebx"); # save extended feature flag ++&set_label("no_extended_info"); ++ ++ &bt ("ebp",27); # check OSXSAVE bit + &jnc (&label("clear_avx")); + &xor ("ecx","ecx"); + &data_byte(0x0f,0x01,0xd0); # xgetbv +@@ -147,7 +146,6 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA3 + &and ("esi",0xfeffffff); # clear FXSR + &set_label("clear_avx"); + &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits +- &mov ("edi",&wparam(0)); + &and (&DWP(8,"edi"),0xffffffdf); # clear AVX2 + &set_label("done"); + &mov ("eax","esi"); +diff -up openssl-1.0.2k/crypto/x86_64cpuid.pl.backports openssl-1.0.2k/crypto/x86_64cpuid.pl +--- openssl-1.0.2k/crypto/x86_64cpuid.pl.backports 2017-03-09 17:59:26.339233278 +0100 ++++ openssl-1.0.2k/crypto/x86_64cpuid.pl 2017-03-27 15:26:06.833916588 +0200 +@@ -59,7 +59,7 @@ OPENSSL_ia32_cpuid: + mov %rbx,%r8 # save %rbx + + xor %eax,%eax +- mov %eax,8(%rdi) # clear 3rd word ++ mov %eax,8(%rdi) # clear extended feature flags + cpuid + mov %eax,%r11d # max value for standard query level + +@@ -127,14 +127,6 @@ OPENSSL_ia32_cpuid: + shr \$14,%r10d + and \$0xfff,%r10d # number of cores -1 per L1D + +- cmp \$7,%r11d +- jb .Lnocacheinfo +- +- mov \$7,%eax +- xor %ecx,%ecx +- cpuid +- mov %ebx,8(%rdi) +- + .Lnocacheinfo: + mov \$1,%eax + cpuid +@@ -164,6 +156,15 @@ OPENSSL_ia32_cpuid: + or %ecx,%r9d # merge AMD XOP flag + + mov %edx,%r10d # %r9d:%r10d is copy of %ecx:%edx ++ ++ cmp \$7,%r11d ++ jb .Lno_extended_info ++ mov \$7,%eax ++ xor %ecx,%ecx ++ cpuid ++ mov %ebx,8(%rdi) # save extended feature flags ++.Lno_extended_info: ++ + bt \$27,%r9d # check OSXSAVE bit + jnc .Lclear_avx + xor %ecx,%ecx # XCR0 +diff -up openssl-1.0.2k/ssl/ssl_locl.h.backports openssl-1.0.2k/ssl/ssl_locl.h +--- openssl-1.0.2k/ssl/ssl_locl.h.backports 2017-03-09 17:59:26.183229642 +0100 ++++ openssl-1.0.2k/ssl/ssl_locl.h 2017-03-09 17:59:26.311232626 +0100 +@@ -1430,7 +1430,7 @@ int ssl_parse_clienthello_renegotiate_ex + long ssl_get_algorithm2(SSL *s); + int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize); + int tls1_process_sigalgs(SSL *s); +-size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs); ++size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs); + int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, + const unsigned char *sig, EVP_PKEY *pkey); + void ssl_set_client_disabled(SSL *s); +diff -up openssl-1.0.2k/ssl/s3_lib.c.backports openssl-1.0.2k/ssl/s3_lib.c +--- openssl-1.0.2k/ssl/s3_lib.c.backports 2017-03-09 17:59:26.294232230 +0100 ++++ openssl-1.0.2k/ssl/s3_lib.c 2017-03-09 17:59:26.311232626 +0100 +@@ -4237,7 +4237,7 @@ int ssl3_get_req_cert_type(SSL *s, unsig + return (int)s->cert->ctype_num; + } + /* get configured sigalgs */ +- siglen = tls12_get_psigalgs(s, &sig); ++ siglen = tls12_get_psigalgs(s, 1, &sig); + if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) + nostrict = 0; + for (i = 0; i < siglen; i += 2, sig += 2) { +diff -up openssl-1.0.2k/ssl/s3_srvr.c.backports openssl-1.0.2k/ssl/s3_srvr.c +--- openssl-1.0.2k/ssl/s3_srvr.c.backports 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/ssl/s3_srvr.c 2017-03-09 17:59:26.311232626 +0100 +@@ -2084,7 +2084,7 @@ int ssl3_send_certificate_request(SSL *s + + if (SSL_USE_SIGALGS(s)) { + const unsigned char *psigs; +- nl = tls12_get_psigalgs(s, &psigs); ++ nl = tls12_get_psigalgs(s, 1, &psigs); + s2n(nl, p); + memcpy(p, psigs, nl); + p += nl; +diff -up openssl-1.0.2k/ssl/t1_lib.c.backports openssl-1.0.2k/ssl/t1_lib.c +--- openssl-1.0.2k/ssl/t1_lib.c.backports 2017-03-09 17:59:26.297232299 +0100 ++++ openssl-1.0.2k/ssl/t1_lib.c 2017-03-09 17:59:26.312232649 +0100 +@@ -1015,7 +1015,7 @@ static unsigned char suiteb_sigalgs[] = + tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) + }; + # endif +-size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) ++size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs) + { + /* + * If Suite B mode use Suite B sigalgs only, ignore any other +@@ -1037,7 +1037,7 @@ size_t tls12_get_psigalgs(SSL *s, const + } + # endif + /* If server use client authentication sigalgs if not NULL */ +- if (s->server && s->cert->client_sigalgs) { ++ if (s->server == sent && s->cert->client_sigalgs) { + *psigs = s->cert->client_sigalgs; + return s->cert->client_sigalgslen; + } else if (s->cert->conf_sigalgs) { +@@ -1101,7 +1101,7 @@ int tls12_check_peer_sigalg(const EVP_MD + # endif + + /* Check signature matches a type we sent */ +- sent_sigslen = tls12_get_psigalgs(s, &sent_sigs); ++ sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); + for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { + if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1]) + break; +@@ -1149,7 +1149,7 @@ void ssl_set_client_disabled(SSL *s) + * Now go through all signature algorithms seeing if we support any for + * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. + */ +- sigalgslen = tls12_get_psigalgs(s, &sigalgs); ++ sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); + for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { + switch (sigalgs[1]) { + # ifndef OPENSSL_NO_RSA +@@ -1420,7 +1420,7 @@ unsigned char *ssl_add_clienthello_tlsex + if (SSL_CLIENT_USE_SIGALGS(s)) { + size_t salglen; + const unsigned char *salg; +- salglen = tls12_get_psigalgs(s, &salg); ++ salglen = tls12_get_psigalgs(s, 1, &salg); + + /*- + * check for enough space. +@@ -3783,7 +3783,7 @@ static int tls1_set_shared_sigalgs(SSL * + conf = c->conf_sigalgs; + conflen = c->conf_sigalgslen; + } else +- conflen = tls12_get_psigalgs(s, &conf); ++ conflen = tls12_get_psigalgs(s, 0, &conf); + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { + pref = conf; + preflen = conflen; diff --git a/openssl-1.0.2k-cc-reqs.patch b/openssl-1.0.2k-cc-reqs.patch new file mode 100644 index 0000000..683d9af --- /dev/null +++ b/openssl-1.0.2k-cc-reqs.patch @@ -0,0 +1,27 @@ +diff -up openssl-1.0.2k/crypto/rsa/rsa_gen.c.cc-reqs openssl-1.0.2k/crypto/rsa/rsa_gen.c +--- openssl-1.0.2k/crypto/rsa/rsa_gen.c.cc-reqs 2017-02-06 16:42:47.313963001 +0100 ++++ openssl-1.0.2k/crypto/rsa/rsa_gen.c 2017-02-06 16:46:54.453628783 +0100 +@@ -474,6 +474,12 @@ static int rsa_builtin_keygen(RSA *rsa, + if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) + goto err; + ++ /* prepare minimum p and q difference */ ++ if (!BN_one(r3)) ++ goto err; ++ if (bitsp > 100 && !BN_lshift(r3, r3, bitsp - 100)) ++ goto err; ++ + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + +@@ -502,7 +508,9 @@ static int rsa_builtin_keygen(RSA *rsa, + do { + if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; +- } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); ++ if (!BN_sub(r2, rsa->q, rsa->p)) ++ goto err; ++ } while ((BN_ucmp(r2, r3) <= 0) && (++degenerate < 3)); + if (degenerate == 3) { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); diff --git a/openssl-1.0.2k-cve-2017-3735.patch b/openssl-1.0.2k-cve-2017-3735.patch new file mode 100644 index 0000000..19b4b4b --- /dev/null +++ b/openssl-1.0.2k-cve-2017-3735.patch @@ -0,0 +1,20 @@ +diff -up openssl-1.0.2k/crypto/x509v3/v3_addr.c.overread openssl-1.0.2k/crypto/x509v3/v3_addr.c +--- openssl-1.0.2k/crypto/x509v3/v3_addr.c.overread 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/crypto/x509v3/v3_addr.c 2018-06-18 13:49:30.001625137 +0200 +@@ -130,10 +130,12 @@ static int length_from_afi(const unsigne + */ + unsigned int v3_addr_get_afi(const IPAddressFamily *f) + { +- return ((f != NULL && +- f->addressFamily != NULL && f->addressFamily->data != NULL) +- ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) +- : 0); ++ if (f == NULL ++ || f->addressFamily == NULL ++ || f->addressFamily->data == NULL ++ || f->addressFamily->length < 2) ++ return 0; ++ return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; + } + + /* diff --git a/openssl-1.0.2k-cve-2017-3736.patch b/openssl-1.0.2k-cve-2017-3736.patch new file mode 100644 index 0000000..6fc0491 --- /dev/null +++ b/openssl-1.0.2k-cve-2017-3736.patch @@ -0,0 +1,43 @@ +From 38d600147331d36e74174ebbd4008b63188b321b Mon Sep 17 00:00:00 2001 +From: Andy Polyakov +Date: Thu, 17 Aug 2017 21:08:57 +0200 +Subject: [PATCH] bn/asm/x86_64-mont5.pl: fix carry bug in bn_sqrx8x_internal. + +Credit to OSS-Fuzz for finding this. + +CVE-2017-3736 + +Reviewed-by: Rich Salz +--- + crypto/bn/asm/x86_64-mont5.pl | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl +index 3bb0cdf..42178e4 100755 +--- a/crypto/bn/asm/x86_64-mont5.pl ++++ b/crypto/bn/asm/x86_64-mont5.pl +@@ -3090,11 +3090,19 @@ $code.=<<___; + + .align 32 + .Lsqrx8x_break: +- sub 16+8(%rsp),%r8 # consume last carry ++ xor $zero,$zero ++ sub 16+8(%rsp),%rbx # mov 16(%rsp),%cf ++ adcx $zero,%r8 + mov 24+8(%rsp),$carry # initial $tptr, borrow $carry ++ adcx $zero,%r9 + mov 0*8($aptr),%rdx # a[8], modulo-scheduled +- xor %ebp,%ebp # xor $zero,$zero ++ adc \$0,%r10 + mov %r8,0*8($tptr) ++ adc \$0,%r11 ++ adc \$0,%r12 ++ adc \$0,%r13 ++ adc \$0,%r14 ++ adc \$0,%r15 + cmp $carry,$tptr # cf=0, of=0 + je .Lsqrx8x_outer_loop + +-- +2.9.5 + diff --git a/openssl-1.0.2k-cve-2017-3737.patch b/openssl-1.0.2k-cve-2017-3737.patch new file mode 100644 index 0000000..0f6f462 --- /dev/null +++ b/openssl-1.0.2k-cve-2017-3737.patch @@ -0,0 +1,232 @@ +diff -up openssl-1.0.2k/ssl/fatalerrtest.c.ssl-err openssl-1.0.2k/ssl/fatalerrtest.c +--- openssl-1.0.2k/ssl/fatalerrtest.c.ssl-err 2017-12-13 14:17:46.730350538 +0100 ++++ openssl-1.0.2k/ssl/fatalerrtest.c 2017-12-13 14:18:54.879940227 +0100 +@@ -0,0 +1,109 @@ ++/* ++ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ ++#include ++#include ++#include "ssltestlib.h" ++ ++int main(int argc, char *argv[]) ++{ ++ SSL_CTX *sctx = NULL, *cctx = NULL; ++ SSL *sssl = NULL, *cssl = NULL; ++ const char *msg = "Dummy"; ++ BIO *err = NULL, *wbio = NULL; ++ int ret = 1, len; ++ char buf[80]; ++ unsigned char dummyrec[] = { ++ 0x17, 0x03, 0x03, 0x00, 0x05, 'D', 'u', 'm', 'm', 'y' ++ }; ++ ++ if (argc != 3) { ++ printf("Incorrect number of parameters\n"); ++ return 1; ++ } ++ ++ SSL_library_init(); ++ SSL_load_error_strings(); ++ err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); ++ CRYPTO_malloc_debug_init(); ++ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); ++ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); ++ ++ if (!create_ssl_ctx_pair(SSLv23_method(), SSLv23_method(), &sctx, &cctx, ++ argv[1], argv[2])) { ++ printf("Failed to create SSL_CTX pair\n"); ++ goto err; ++ } ++ ++ /* ++ * Deliberately set the cipher lists for client and server to be different ++ * to force a handshake failure. ++ */ ++ if (!SSL_CTX_set_cipher_list(sctx, "AES128-SHA") ++ || !SSL_CTX_set_cipher_list(cctx, "AES256-SHA")) { ++ printf("Failed to set cipher lists\n"); ++ goto err; ++ } ++ ++ if (!create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL)) { ++ printf("Failed to create SSL objectx\n"); ++ goto err; ++ } ++ ++ wbio = SSL_get_wbio(cssl); ++ if (wbio == NULL) { ++ printf("Unexpected NULL bio received\n"); ++ goto err; ++ } ++ ++ if (create_ssl_connection(sssl, cssl)) { ++ printf("Unexpected success creating a connection\n"); ++ goto err; ++ } ++ ++ ERR_clear_error(); ++ ++ /* Inject a plaintext record from client to server */ ++ if (BIO_write(wbio, dummyrec, sizeof(dummyrec)) <= 0) { ++ printf("Unexpected failure injecting dummy record\n"); ++ goto err; ++ } ++ ++ /* SSL_read()/SSL_write should fail because of a previous fatal error */ ++ if ((len = SSL_read(sssl, buf, sizeof(buf) - 1)) > 0) { ++ buf[len] = '\0'; ++ printf("Unexpected success reading data: %s\n", buf); ++ goto err; ++ } ++ if (SSL_write(sssl, msg, strlen(msg)) > 0) { ++ printf("Unexpected success writing data\n"); ++ goto err; ++ } ++ ++ ret = 0; ++ err: ++ SSL_free(sssl); ++ SSL_free(cssl); ++ SSL_CTX_free(sctx); ++ SSL_CTX_free(cctx); ++ ERR_print_errors_fp(stderr); ++ ++ if (ret) { ++ printf("Fatal err test: FAILED\n"); ++ } ++ ++ ERR_free_strings(); ++ ERR_remove_thread_state(NULL); ++ EVP_cleanup(); ++ CRYPTO_cleanup_all_ex_data(); ++ CRYPTO_mem_leaks(err); ++ BIO_free(err); ++ ++ return ret; ++} +diff -up openssl-1.0.2k/ssl/Makefile.ssl-err openssl-1.0.2k/ssl/Makefile +--- openssl-1.0.2k/ssl/Makefile.ssl-err 2017-03-09 17:59:42.832617740 +0100 ++++ openssl-1.0.2k/ssl/Makefile 2017-12-13 14:17:46.729350514 +0100 +@@ -15,7 +15,8 @@ KRB5_INCLUDES= + CFLAGS= $(INCLUDES) $(CFLAG) + + GENERAL=Makefile README ssl-lib.com install.com +-TEST=ssltest.c heartbeat_test.c clienthellotest.c sslv2conftest.c dtlstest.c bad_dtls_test.c ++TEST=ssltest.c heartbeat_test.c clienthellotest.c sslv2conftest.c dtlstest.c \ ++ bad_dtls_test.c fatalerrtest.c + APPS= + + LIB=$(TOP)/libssl.a +diff -up openssl-1.0.2k/ssl/ssl.h.ssl-err openssl-1.0.2k/ssl/ssl.h +--- openssl-1.0.2k/ssl/ssl.h.ssl-err 2017-03-09 17:59:26.177229502 +0100 ++++ openssl-1.0.2k/ssl/ssl.h 2017-12-13 14:17:07.341431733 +0100 +@@ -1683,7 +1683,7 @@ extern "C" { + # define SSL_ST_BEFORE 0x4000 + # define SSL_ST_OK 0x03 + # define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) +-# define SSL_ST_ERR 0x05 ++# define SSL_ST_ERR (0x05|SSL_ST_INIT) + + # define SSL_CB_LOOP 0x01 + # define SSL_CB_EXIT 0x02 +diff -up openssl-1.0.2k/test/Makefile.ssl-err openssl-1.0.2k/test/Makefile +--- openssl-1.0.2k/test/Makefile.ssl-err 2017-03-09 17:59:45.580681798 +0100 ++++ openssl-1.0.2k/test/Makefile 2017-12-13 14:17:46.731350561 +0100 +@@ -73,6 +73,7 @@ CLIENTHELLOTEST= clienthellotest + BADDTLSTEST= bad_dtls_test + SSLV2CONFTEST = sslv2conftest + DTLSTEST = dtlstest ++FATALERRTEST = fatalerrtest + + TESTS= alltests + +@@ -87,7 +88,7 @@ EXE= $(BNTEST)$(EXE_EXT) $(ECTEST)$(EXE_ + $(ASN1TEST)$(EXE_EXT) $(V3NAMETEST)$(EXE_EXT) $(HEARTBEATTEST)$(EXE_EXT) \ + $(CONSTTIMETEST)$(EXE_EXT) $(VERIFYEXTRATEST)$(EXE_EXT) \ + $(CLIENTHELLOTEST)$(EXE_EXT) $(SSLV2CONFTEST)$(EXE_EXT) $(DTLSTEST)$(EXE_EXT) \ +- $(BADDTLSTEST)$(EXE_EXT) ++ $(BADDTLSTEST)$(EXE_EXT) $(FATALERRTEST)$(EXE_EXT) + + # $(METHTEST)$(EXE_EXT) + +@@ -102,7 +103,7 @@ OBJ= $(BNTEST).o $(ECTEST).o $(ECDSATES + $(EVPTEST).o $(EVPEXTRATEST).o $(IGETEST).o $(JPAKETEST).o $(ASN1TEST).o $(V3NAMETEST).o \ + $(HEARTBEATTEST).o $(CONSTTIMETEST).o $(VERIFYEXTRATEST).o \ + $(CLIENTHELLOTEST).o $(SSLV2CONFTEST).o $(DTLSTEST).o ssltestlib.o \ +- $(BADDTLSTEST).o ++ $(BADDTLSTEST).o $(FATALERRTEST).o + + SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \ + $(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \ +@@ -114,7 +115,7 @@ SRC= $(BNTEST).c $(ECTEST).c $(ECDSATES + $(EVPTEST).c $(EVPEXTRATEST).c $(IGETEST).c $(JPAKETEST).c $(SRPTEST).c $(ASN1TEST).c \ + $(V3NAMETEST).c $(HEARTBEATTEST).c $(CONSTTIMETEST).c $(VERIFYEXTRATEST).c \ + $(CLIENTHELLOTEST).c $(SSLV2CONFTEST).c $(DTLSTEST).c ssltestlib.c \ +- $(BADDTLSTEST).c ++ $(BADDTLSTEST).c $(FATALERRTEST).c + + EXHEADER= + HEADER= testutil.h ssltestlib.h $(EXHEADER) +@@ -159,7 +160,7 @@ alltests: \ + test_ss test_ca test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \ + test_jpake test_srp test_cms test_ocsp test_v3name test_heartbeat \ + test_constant_time test_verify_extra test_clienthello test_sslv2conftest \ +- test_dtls test_bad_dtls ++ test_dtls test_bad_dtls test_fatalerr + + test_evp: $(EVPTEST)$(EXE_EXT) evptests.txt + ../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt +@@ -372,6 +373,10 @@ test_bad_dtls: $(BADDTLSTEST)$(EXE_EXT) + @echo $(START) $@ + ../util/shlib_wrap.sh ./$(BADDTLSTEST) + ++test_fatalerr: $(FATALERRTEST)$(EXE_EXT) ++ @echo $(START) $@ ++ ../util/shlib_wrap.sh ./$(FATALERRTEST) ../apps/server.pem ../apps/server.pem ++ + test_sslv2conftest: $(SSLV2CONFTEST)$(EXE_EXT) + @echo $(START) $@ + ../util/shlib_wrap.sh ./$(SSLV2CONFTEST) +@@ -560,6 +565,9 @@ $(CLIENTHELLOTEST)$(EXE_EXT): $(CLIENTHE + $(BADDTLSTEST)$(EXE_EXT): $(BADDTLSTEST).o + @target=$(BADDTLSTEST) $(BUILD_CMD) + ++$(FATALERRTEST)$(EXE_EXT): $(FATALERRTEST).o ssltestlib.o $(DLIBSSL) $(DLIBCRYPTO) ++ @target=$(FATALERRTEST); exobj=ssltestlib.o; $(BUILD_CMD) ++ + $(SSLV2CONFTEST)$(EXE_EXT): $(SSLV2CONFTEST).o + @target=$(SSLV2CONFTEST) $(BUILD_CMD) + +@@ -779,6 +787,25 @@ exptest.o: ../include/openssl/opensslcon + exptest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h + exptest.o: ../include/openssl/safestack.h ../include/openssl/stack.h + exptest.o: ../include/openssl/symhacks.h exptest.c ++fatalerrtest.o: ../include/openssl/asn1.h ../include/openssl/bio.h ++fatalerrtest.o: ../include/openssl/buffer.h ../include/openssl/comp.h ++fatalerrtest.o: ../include/openssl/crypto.h ../include/openssl/dtls1.h ++fatalerrtest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h ++fatalerrtest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h ++fatalerrtest.o: ../include/openssl/err.h ../include/openssl/evp.h ++fatalerrtest.o: ../include/openssl/hmac.h ../include/openssl/kssl.h ++fatalerrtest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h ++fatalerrtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h ++fatalerrtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h ++fatalerrtest.o: ../include/openssl/pem.h ../include/openssl/pem2.h ++fatalerrtest.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h ++fatalerrtest.o: ../include/openssl/safestack.h ../include/openssl/sha.h ++fatalerrtest.o: ../include/openssl/srtp.h ../include/openssl/ssl.h ++fatalerrtest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h ++fatalerrtest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h ++fatalerrtest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h ++fatalerrtest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ++fatalerrtest.o: fatalerrtest.c ssltestlib.h + heartbeat_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h + heartbeat_test.o: ../include/openssl/buffer.h ../include/openssl/comp.h + heartbeat_test.o: ../include/openssl/crypto.h ../include/openssl/dsa.h diff --git a/openssl-1.0.2k-cve-2017-3738.patch b/openssl-1.0.2k-cve-2017-3738.patch new file mode 100644 index 0000000..e8b6ba5 --- /dev/null +++ b/openssl-1.0.2k-cve-2017-3738.patch @@ -0,0 +1,80 @@ +From ca51bafc1a88d8b8348f5fd97adc5d6ca93f8e76 Mon Sep 17 00:00:00 2001 +From: Andy Polyakov +Date: Fri, 24 Nov 2017 11:35:50 +0100 +Subject: [PATCH] bn/asm/rsaz-avx2.pl: fix digit correction bug in + rsaz_1024_mul_avx2. + +Credit to OSS-Fuzz for finding this. + +CVE-2017-3738 + +Reviewed-by: Rich Salz +--- + crypto/bn/asm/rsaz-avx2.pl | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/crypto/bn/asm/rsaz-avx2.pl b/crypto/bn/asm/rsaz-avx2.pl +index 712a77f..2b3f8b0 100755 +--- a/crypto/bn/asm/rsaz-avx2.pl ++++ b/crypto/bn/asm/rsaz-avx2.pl +@@ -239,7 +239,7 @@ $code.=<<___; + vmovdqu 32*8-128($ap), $ACC8 + + lea 192(%rsp), $tp0 # 64+128=192 +- vpbroadcastq .Land_mask(%rip), $AND_MASK ++ vmovdqu .Land_mask(%rip), $AND_MASK + jmp .LOOP_GRANDE_SQR_1024 + + .align 32 +@@ -1070,10 +1070,10 @@ $code.=<<___; + vpmuludq 32*6-128($np),$Yi,$TEMP1 + vpaddq $TEMP1,$ACC6,$ACC6 + vpmuludq 32*7-128($np),$Yi,$TEMP2 +- vpblendd \$3, $ZERO, $ACC9, $ACC9 # correct $ACC3 ++ vpblendd \$3, $ZERO, $ACC9, $TEMP1 # correct $ACC3 + vpaddq $TEMP2,$ACC7,$ACC7 + vpmuludq 32*8-128($np),$Yi,$TEMP0 +- vpaddq $ACC9, $ACC3, $ACC3 # correct $ACC3 ++ vpaddq $TEMP1, $ACC3, $ACC3 # correct $ACC3 + vpaddq $TEMP0,$ACC8,$ACC8 + + mov %rbx, %rax +@@ -1086,7 +1086,9 @@ $code.=<<___; + vmovdqu -8+32*2-128($ap),$TEMP2 + + mov $r1, %rax ++ vpblendd \$0xfc, $ZERO, $ACC9, $ACC9 # correct $ACC3 + imull $n0, %eax ++ vpaddq $ACC9,$ACC4,$ACC4 # correct $ACC3 + and \$0x1fffffff, %eax + + imulq 16-128($ap),%rbx +@@ -1322,15 +1324,12 @@ ___ + # But as we underutilize resources, it's possible to correct in + # each iteration with marginal performance loss. But then, as + # we do it in each iteration, we can correct less digits, and +-# avoid performance penalties completely. Also note that we +-# correct only three digits out of four. This works because +-# most significant digit is subjected to less additions. ++# avoid performance penalties completely. + + $TEMP0 = $ACC9; + $TEMP3 = $Bi; + $TEMP4 = $Yi; + $code.=<<___; +- vpermq \$0, $AND_MASK, $AND_MASK + vpaddq (%rsp), $TEMP1, $ACC0 + + vpsrlq \$29, $ACC0, $TEMP1 +@@ -1763,7 +1762,7 @@ $code.=<<___; + + .align 64 + .Land_mask: +- .quad 0x1fffffff,0x1fffffff,0x1fffffff,-1 ++ .quad 0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff + .Lscatter_permd: + .long 0,2,4,6,7,7,7,7 + .Lgather_permd: +-- +2.9.5 + diff --git a/openssl-1.0.2k-cve-2018-0495.patch b/openssl-1.0.2k-cve-2018-0495.patch new file mode 100644 index 0000000..10a9528 --- /dev/null +++ b/openssl-1.0.2k-cve-2018-0495.patch @@ -0,0 +1,905 @@ +diff --git a/crypto/Makefile b/crypto/Makefile +index 8bc5850..3a2bc51 100644 +--- a/crypto/Makefile ++++ b/crypto/Makefile +@@ -45,7 +45,7 @@ SRC= $(LIBSRC) + EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \ + ossl_typ.h + HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h \ +- constant_time_locl.h $(EXHEADER) ++ constant_time_locl.h bn_int.h $(EXHEADER) + + ALL= $(GENERAL) $(SRC) $(HEADER) + +diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h +index b37f6ec..0e6e30f 100644 +--- a/crypto/bn/bn.h ++++ b/crypto/bn/bn.h +@@ -702,6 +702,16 @@ BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */ + /* We only need assert() when debugging */ + # include + ++/* ++ * The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with ++ * bn_correct_top, in other words such vectors are permitted to have zeros ++ * in most significant limbs. Such vectors are used internally to achieve ++ * execution time invariance for critical operations with private keys. ++ * It's BN_DEBUG-only flag, because user application is not supposed to ++ * observe it anyway. Moreover, optimizing compiler would actually remove ++ * all operations manipulating the bit in question in non-BN_DEBUG build. ++ */ ++# define BN_FLG_FIXED_TOP 0x10000 + # ifdef BN_DEBUG_RAND + /* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */ + # ifndef RAND_pseudo_bytes +@@ -734,8 +744,10 @@ int RAND_pseudo_bytes(unsigned char *buf, int num); + do { \ + const BIGNUM *_bnum2 = (a); \ + if (_bnum2 != NULL) { \ +- assert((_bnum2->top == 0) || \ +- (_bnum2->d[_bnum2->top - 1] != 0)); \ ++ int _top = _bnum2->top; \ ++ assert((_top == 0) || \ ++ (_bnum2->flags & BN_FLG_FIXED_TOP) || \ ++ (_bnum2->d[_top - 1] != 0)); \ + bn_pollute(_bnum2); \ + } \ + } while(0) +@@ -753,6 +765,7 @@ int RAND_pseudo_bytes(unsigned char *buf, int num); + + # else /* !BN_DEBUG */ + ++# define BN_FLG_FIXED_TOP 0 + # define bn_pollute(a) + # define bn_check_top(a) + # define bn_fix_top(a) bn_correct_top(a) +diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c +index bc37671..460d8b7 100644 +--- a/crypto/bn/bn_div.c ++++ b/crypto/bn/bn_div.c +@@ -290,6 +290,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, + wnum.neg = 0; + wnum.d = &(snum->d[loop]); + wnum.top = div_n; ++ wnum.flags = BN_FLG_STATIC_DATA; + /* + * only needed when BN_ucmp messes up the values between top and max + */ +diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c +index 195a786..816a198 100644 +--- a/crypto/bn/bn_exp.c ++++ b/crypto/bn/bn_exp.c +@@ -466,17 +466,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + ret = 1; + goto err; + } +- if (!BN_to_montgomery(val[0], aa, mont, ctx)) ++ if (!bn_to_mont_fixed_top(val[0], aa, mont, ctx)) + goto err; /* 1 */ + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { +- if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) ++ if (!bn_mul_mont_fixed_top(d, val[0], val[0], mont, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || +- !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) ++ !bn_mul_mont_fixed_top(val[i], val[i - 1], d, mont, ctx)) + goto err; + } + } +@@ -498,19 +498,15 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + for (i = 1; i < j; i++) + r->d[i] = (~m->d[i]) & BN_MASK2; + r->top = j; +- /* +- * Upper words will be zero if the corresponding words of 'm' were +- * 0xfff[...], so decrement r->top accordingly. +- */ +- bn_correct_top(r); ++ r->flags |= BN_FLG_FIXED_TOP; + } else + #endif +- if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) ++ if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx)) + goto err; + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) { +- if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) ++ if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx)) + goto err; + } + if (wstart == 0) +@@ -541,12 +537,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { +- if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) ++ if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ +- if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) ++ if (!bn_mul_mont_fixed_top(r, r, val[wvalue >> 1], mont, ctx)) + goto err; + + /* move the 'window' down further */ +@@ -556,6 +552,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + if (wstart < 0) + break; + } ++ /* ++ * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery ++ * removes padding [if any] and makes return value suitable for public ++ * API consumer. ++ */ + #if defined(SPARC_T4_MONT) + if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) { + j = mont->N.top; /* borrow j */ +@@ -674,7 +675,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, + } + + b->top = top; +- bn_correct_top(b); ++ b->flags |= BN_FLG_FIXED_TOP; + return 1; + } + +@@ -841,16 +842,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + tmp.top = top; + } else + #endif +- if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx)) ++ if (!bn_to_mont_fixed_top(&tmp, BN_value_one(), mont, ctx)) + goto err; + + /* prepare a^1 in Montgomery domain */ + if (a->neg || BN_ucmp(a, m) >= 0) { + if (!BN_mod(&am, a, m, ctx)) + goto err; +- if (!BN_to_montgomery(&am, &am, mont, ctx)) ++ if (!bn_to_mont_fixed_top(&am, &am, mont, ctx)) + goto err; +- } else if (!BN_to_montgomery(&am, a, mont, ctx)) ++ } else if (!bn_to_mont_fixed_top(&am, a, mont, ctx)) + goto err; + + #if defined(SPARC_T4_MONT) +@@ -1117,14 +1118,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + * performance advantage of sqr over mul). + */ + if (window > 1) { +- if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) ++ if (!bn_mul_mont_fixed_top(&tmp, &am, &am, mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, + window)) + goto err; + for (i = 3; i < numPowers; i++) { + /* Calculate a^i = a^(i-1) * a */ +- if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) ++ if (!bn_mul_mont_fixed_top(&tmp, &am, &tmp, mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i, + window)) +@@ -1148,7 +1149,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + + /* Scan the window, squaring the result as we go */ + for (i = 0; i < window; i++, bits--) { +- if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx)) ++ if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx)) + goto err; + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } +@@ -1161,12 +1162,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + goto err; + + /* Multiply the result into the intermediate result */ +- if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) ++ if (!bn_mul_mont_fixed_top(&tmp, &tmp, &am, mont, ctx)) + goto err; + } + } + +- /* Convert the final result from montgomery to standard format */ ++ /* ++ * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery ++ * removes padding [if any] and makes return value suitable for public ++ * API consumer. ++ */ + #if defined(SPARC_T4_MONT) + if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) { + am.d[0] = 1; /* borrow am */ +diff --git a/crypto/bn/bn_lcl.h b/crypto/bn/bn_lcl.h +index 00f4f09..1aa7fe8 100644 +--- a/crypto/bn/bn_lcl.h ++++ b/crypto/bn/bn_lcl.h +@@ -113,6 +113,7 @@ + # define HEADER_BN_LCL_H + + # include ++# include "bn_int.h" + + #ifdef __cplusplus + extern "C" { +diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c +index 10b78f5..e42e3fb 100644 +--- a/crypto/bn/bn_lib.c ++++ b/crypto/bn/bn_lib.c +@@ -290,8 +290,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) + const BN_ULONG *B; + int i; + +- bn_check_top(b); +- + if (words > (INT_MAX / (4 * BN_BITS2))) { + BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG); + return NULL; +@@ -425,8 +423,6 @@ BIGNUM *bn_dup_expand(const BIGNUM *b, int words) + + BIGNUM *bn_expand2(BIGNUM *b, int words) + { +- bn_check_top(b); +- + if (words > b->dmax) { + BN_ULONG *a = bn_expand_internal(b, words); + if (!a) +@@ -460,7 +456,6 @@ BIGNUM *bn_expand2(BIGNUM *b, int words) + assert(A == &(b->d[b->dmax])); + } + #endif +- bn_check_top(b); + return b; + } + +@@ -572,6 +567,7 @@ void BN_clear(BIGNUM *a) + OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); + a->top = 0; + a->neg = 0; ++ a->flags &= ~BN_FLG_FIXED_TOP; + } + + BN_ULONG BN_get_word(const BIGNUM *a) +@@ -592,6 +588,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w) + a->neg = 0; + a->d[0] = w; + a->top = (w ? 1 : 0); ++ a->flags &= ~BN_FLG_FIXED_TOP; + bn_check_top(a); + return (1); + } +@@ -738,6 +735,7 @@ int BN_set_bit(BIGNUM *a, int n) + for (k = a->top; k < i + 1; k++) + a->d[k] = 0; + a->top = i + 1; ++ a->flags &= ~BN_FLG_FIXED_TOP; + } + + a->d[i] |= (((BN_ULONG)1) << j); +diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c +index ffbce89..23ddd48 100644 +--- a/crypto/bn/bn_mod.c ++++ b/crypto/bn/bn_mod.c +@@ -149,16 +149,71 @@ int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + + /* + * BN_mod_add variant that may be used if both a and b are non-negative and +- * less than m ++ * less than m. The original algorithm was ++ * ++ * if (!BN_uadd(r, a, b)) ++ * return 0; ++ * if (BN_ucmp(r, m) >= 0) ++ * return BN_usub(r, r, m); ++ * ++ * which is replaced with addition, subtracting modulus, and conditional ++ * move depending on whether or not subtraction borrowed. + */ ++int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ++ const BIGNUM *m) ++{ ++ size_t i, ai, bi, mtop = m->top; ++ BN_ULONG storage[1024 / BN_BITS2]; ++ BN_ULONG carry, temp, mask, *rp, *tp = storage; ++ const BN_ULONG *ap, *bp; ++ ++ if (bn_wexpand(r, m->top) == NULL) ++ return 0; ++ ++ if (mtop > sizeof(storage) / sizeof(storage[0]) ++ && (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL) ++ return 0; ++ ++ ap = a->d != NULL ? a->d : tp; ++ bp = b->d != NULL ? b->d : tp; ++ ++ for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) { ++ mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); ++ temp = ((ap[ai] & mask) + carry) & BN_MASK2; ++ carry = (temp < carry); ++ ++ mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); ++ tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2; ++ carry += (tp[i] < temp); ++ ++ i++; ++ ai += (i - a->dmax) >> (8 * sizeof(i) - 1); ++ bi += (i - b->dmax) >> (8 * sizeof(i) - 1); ++ } ++ rp = r->d; ++ carry -= bn_sub_words(rp, tp, m->d, mtop); ++ for (i = 0; i < mtop; i++) { ++ rp[i] = (carry & tp[i]) | (~carry & rp[i]); ++ ((volatile BN_ULONG *)tp)[i] = 0; ++ } ++ r->top = mtop; ++ r->neg = 0; ++ ++ if (tp != storage) ++ OPENSSL_free(tp); ++ ++ return 1; ++} ++ + int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) + { +- if (!BN_uadd(r, a, b)) +- return 0; +- if (BN_ucmp(r, m) >= 0) +- return BN_usub(r, r, m); +- return 1; ++ int ret = bn_mod_add_fixed_top(r, a, b, m); ++ ++ if (ret) ++ bn_correct_top(r); ++ ++ return ret; + } + + int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, +diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c +index be95bd5..d41434a 100644 +--- a/crypto/bn/bn_mont.c ++++ b/crypto/bn/bn_mont.c +@@ -56,7 +56,7 @@ + * [including the GNU Public Licence.] + */ + /* ==================================================================== +- * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 1998-2018 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 +@@ -123,11 +123,22 @@ + #define MONT_WORD /* use the faster word-based algorithm */ + + #ifdef MONT_WORD +-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); ++static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); + #endif + + int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx) ++{ ++ int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx); ++ ++ bn_correct_top(r); ++ bn_check_top(r); ++ ++ return ret; ++} ++ ++int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ++ BN_MONT_CTX *mont, BN_CTX *ctx) + { + BIGNUM *tmp; + int ret = 0; +@@ -140,8 +151,8 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { + r->neg = a->neg ^ b->neg; + r->top = num; +- bn_correct_top(r); +- return (1); ++ r->flags |= BN_FLG_FIXED_TOP; ++ return 1; + } + } + #endif +@@ -161,13 +172,12 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + } + /* reduce from aRR to aR */ + #ifdef MONT_WORD +- if (!BN_from_montgomery_word(r, tmp, mont)) ++ if (!bn_from_montgomery_word(r, tmp, mont)) + goto err; + #else + if (!BN_from_montgomery(r, tmp, mont, ctx)) + goto err; + #endif +- bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); +@@ -175,7 +185,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + } + + #ifdef MONT_WORD +-static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) ++static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) + { + BIGNUM *n; + BN_ULONG *ap, *np, *rp, n0, v, carry; +@@ -205,28 +215,16 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) + # endif + + r->top = max; ++ r->flags |= BN_FLG_FIXED_TOP; + n0 = mont->n0[0]; + +-# ifdef BN_COUNT +- fprintf(stderr, "word BN_from_montgomery_word %d * %d\n", nl, nl); +-# endif ++ /* ++ * Add multiples of |n| to |r| until R = 2^(nl * BN_BITS2) divides it. On ++ * input, we had |r| < |n| * R, so now |r| < 2 * |n| * R. Note that |r| ++ * includes |carry| which is stored separately. ++ */ + for (carry = 0, i = 0; i < nl; i++, rp++) { +-# ifdef __TANDEM +- { +- long long t1; +- long long t2; +- long long t3; +- t1 = rp[0] * (n0 & 0177777); +- t2 = 037777600000l; +- t2 = n0 & t2; +- t3 = rp[0] & 0177777; +- t2 = (t3 * t2) & BN_MASK2; +- t1 = t1 + t2; +- v = bn_mul_add_words(rp, np, nl, (BN_ULONG)t1); +- } +-# else + v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2); +-# endif + v = (v + carry + rp[nl]) & BN_MASK2; + carry |= (v != rp[nl]); + carry &= (v <= rp[nl]); +@@ -236,52 +234,27 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) + if (bn_wexpand(ret, nl) == NULL) + return (0); + ret->top = nl; ++ ret->flags |= BN_FLG_FIXED_TOP; + ret->neg = r->neg; + + rp = ret->d; ++ ++ /* ++ * Shift |nl| words to divide by R. We have |ap| < 2 * |n|. Note that |ap| ++ * includes |carry| which is stored separately. ++ */ + ap = &(r->d[nl]); + +-# define BRANCH_FREE 1 +-# if BRANCH_FREE +- { +- BN_ULONG *nrp; +- size_t m; +- +- v = bn_sub_words(rp, ap, np, nl) - carry; +- /* +- * if subtraction result is real, then trick unconditional memcpy +- * below to perform in-place "refresh" instead of actual copy. +- */ +- m = (0 - (size_t)v); +- nrp = +- (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m)); +- +- for (i = 0, nl -= 4; i < nl; i += 4) { +- BN_ULONG t1, t2, t3, t4; +- +- t1 = nrp[i + 0]; +- t2 = nrp[i + 1]; +- t3 = nrp[i + 2]; +- ap[i + 0] = 0; +- t4 = nrp[i + 3]; +- ap[i + 1] = 0; +- rp[i + 0] = t1; +- ap[i + 2] = 0; +- rp[i + 1] = t2; +- ap[i + 3] = 0; +- rp[i + 2] = t3; +- rp[i + 3] = t4; +- } +- for (nl += 4; i < nl; i++) +- rp[i] = nrp[i], ap[i] = 0; ++ carry -= bn_sub_words(rp, ap, np, nl); ++ /* ++ * |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note ++ * |carry| cannot be 1. That would imply the subtraction did not fit in ++ * |nl| words, and we know at most one subtraction is needed. ++ */ ++ for (i = 0; i < nl; i++) { ++ rp[i] = (carry & ap[i]) | (~carry & rp[i]); ++ ap[i] = 0; + } +-# else +- if (bn_sub_words(rp, ap, np, nl) - carry) +- memcpy(rp, ap, nl * sizeof(BN_ULONG)); +-# endif +- bn_correct_top(r); +- bn_correct_top(ret); +- bn_check_top(ret); + + return (1); + } +@@ -295,8 +268,11 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BIGNUM *t; + + BN_CTX_start(ctx); +- if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) +- retn = BN_from_montgomery_word(ret, t, mont); ++ if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) { ++ retn = bn_from_montgomery_word(ret, t, mont); ++ bn_correct_top(ret); ++ bn_check_top(ret); ++ } + BN_CTX_end(ctx); + #else /* !MONT_WORD */ + BIGNUM *t1, *t2; +@@ -334,6 +310,12 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + return (retn); + } + ++int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, ++ BN_CTX *ctx) ++{ ++ return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx); ++} ++ + BN_MONT_CTX *BN_MONT_CTX_new(void) + { + BN_MONT_CTX *ret; +@@ -370,7 +352,7 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) + + int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) + { +- int ret = 0; ++ int i, ret = 0; + BIGNUM *Ri, *R; + + if (BN_is_zero(mod)) +@@ -382,6 +364,8 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) + R = &(mont->RR); /* grab RR as a temp */ + if (!BN_copy(&(mont->N), mod)) + goto err; /* Set N */ ++ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) ++ BN_set_flags(&(mont->N), BN_FLG_CONSTTIME); + mont->N.neg = 0; + + #ifdef MONT_WORD +@@ -394,6 +378,9 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) + tmod.dmax = 2; + tmod.neg = 0; + ++ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) ++ BN_set_flags(&tmod, BN_FLG_CONSTTIME); ++ + mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; + + # if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) +@@ -496,6 +483,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) + if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) + goto err; + ++ for (i = mont->RR.top, ret = mont->N.top; i < ret; i++) ++ mont->RR.d[i] = 0; ++ mont->RR.top = ret; ++ mont->RR.flags |= BN_FLG_FIXED_TOP; ++ + ret = 1; + err: + BN_CTX_end(ctx); +diff --git a/crypto/bn/bn_sqr.c b/crypto/bn/bn_sqr.c +index 256d26e..5e69297 100644 +--- a/crypto/bn/bn_sqr.c ++++ b/crypto/bn/bn_sqr.c +@@ -135,14 +135,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) + } + + rr->neg = 0; +- /* +- * If the most-significant half of the top word of 'a' is zero, then the +- * square of 'a' will max-1 words. +- */ +- if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l)) +- rr->top = max - 1; +- else +- rr->top = max; ++ rr->top = max; ++ bn_correct_top(rr); + if (r != rr && BN_copy(r, rr) == NULL) + goto err; + +diff -up openssl-1.0.2k/crypto/bn_int.h.rohnp-fix openssl-1.0.2k/crypto/bn_int.h +--- openssl-1.0.2k/crypto/bn_int.h.rohnp-fix 2018-08-14 10:57:21.597518822 +0200 ++++ openssl-1.0.2k/crypto/bn_int.h 2018-08-14 10:57:21.599518871 +0200 +@@ -0,0 +1,13 @@ ++/* ++ * Some BIGNUM functions assume most significant limb to be non-zero, which ++ * is customarily arranged by bn_correct_top. Output from below functions ++ * is not processed with bn_correct_top, and for this reason it may not be ++ * returned out of public API. It may only be passed internally into other ++ * functions known to support non-minimal or zero-padded BIGNUMs. ++ */ ++int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ++ BN_MONT_CTX *mont, BN_CTX *ctx); ++int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, ++ BN_CTX *ctx); ++int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ++ const BIGNUM *m); + +diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c +index b5f67bd..894dff8 100644 +--- a/crypto/dsa/dsa_ossl.c ++++ b/crypto/dsa/dsa_ossl.c +@@ -136,8 +136,7 @@ const DSA_METHOD *DSA_OpenSSL(void) + static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) + { + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; +- BIGNUM m; +- BIGNUM xr; ++ BIGNUM *m, *blind, *blindm, *tmp; + BN_CTX *ctx = NULL; + int reason = ERR_R_BN_LIB; + DSA_SIG *ret = NULL; +@@ -156,9 +155,6 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) + } + #endif + +- BN_init(&m); +- BN_init(&xr); +- + if (!dsa->p || !dsa->q || !dsa->g) { + reason = DSA_R_MISSING_PARAMETERS; + goto err; +@@ -170,6 +166,14 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; ++ BN_CTX_start(ctx); ++ m = BN_CTX_get(ctx); ++ blind = BN_CTX_get(ctx); ++ blindm = BN_CTX_get(ctx); ++ tmp = BN_CTX_get(ctx); ++ if (tmp == NULL) ++ goto err; ++ + redo: + if ((dsa->kinv == NULL) || (dsa->r == NULL)) { + if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) +@@ -189,20 +193,52 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) + * 4.2 + */ + dlen = BN_num_bytes(dsa->q); +- if (BN_bin2bn(dgst, dlen, &m) == NULL) ++ if (BN_bin2bn(dgst, dlen, m) == NULL) + goto err; + +- /* Compute s = inv(k) (m + xr) mod q */ +- if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) +- goto err; /* s = xr */ +- if (!BN_add(s, &xr, &m)) +- goto err; /* s = m + xr */ +- if (BN_cmp(s, dsa->q) > 0) +- if (!BN_sub(s, s, dsa->q)) ++ /* ++ * The normal signature calculation is: ++ * ++ * s := k^-1 * (m + r * priv_key) mod q ++ * ++ * We will blind this to protect against side channel attacks ++ * ++ * s := blind^-1 * k^-1 * (blind * m + blind * r * priv_key) mod q ++ */ ++ ++ /* Generate a blinding value */ ++ do { ++ if (!BN_rand(blind, BN_num_bits(dsa->q) - 1, -1, 0)) + goto err; ++ } while (BN_is_zero(blind)); ++ BN_set_flags(blind, BN_FLG_CONSTTIME); ++ BN_set_flags(blindm, BN_FLG_CONSTTIME); ++ BN_set_flags(tmp, BN_FLG_CONSTTIME); ++ ++ /* tmp := blind * priv_key * r mod q */ ++ if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx)) ++ goto err; ++ if (!BN_mod_mul(tmp, tmp, r, dsa->q, ctx)) ++ goto err; ++ ++ /* blindm := blind * m mod q */ ++ if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx)) ++ goto err; ++ ++ /* s : = (blind * priv_key * r) + (blind * m) mod q */ ++ if (!BN_mod_add_quick(s, tmp, blindm, dsa->q)) ++ goto err; ++ ++ /* s := s * k^-1 mod q */ + if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) + goto err; + ++ /* s:= s * blind^-1 mod q */ ++ if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL) ++ goto err; ++ if (!BN_mod_mul(s, s, blind, dsa->q, ctx)) ++ goto err; ++ + /* + * Redo if r or s is zero as required by FIPS 186-3: this is very + * unlikely. +@@ -226,13 +262,12 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) + BN_free(r); + BN_free(s); + } +- if (ctx != NULL) ++ if (ctx != NULL) { ++ BN_CTX_end(ctx); + BN_CTX_free(ctx); +- BN_clear_free(&m); +- BN_clear_free(&xr); +- if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ +- BN_clear_free(kinv); +- return (ret); ++ } ++ BN_clear_free(kinv); ++ return ret; + } + + static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, +diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c +index dd76960..2b8f169 100644 +--- a/crypto/ecdsa/ecs_ossl.c ++++ b/crypto/ecdsa/ecs_ossl.c +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include "bn_int.h" + + static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + const BIGNUM *, const BIGNUM *, +@@ -95,6 +96,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + EC_POINT *tmp_point = NULL; + const EC_GROUP *group; + int ret = 0; ++ int order_bits; + + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); +@@ -126,6 +128,13 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + goto err; + } + ++ /* Preallocate space */ ++ order_bits = BN_num_bits(order); ++ if (!BN_set_bit(k, order_bits) ++ || !BN_set_bit(r, order_bits) ++ || !BN_set_bit(X, order_bits)) ++ goto err; ++ + do { + /* get random k */ + do +@@ -139,13 +148,19 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + /* + * We do not want timing information to leak the length of k, so we + * compute G*k using an equivalent scalar of fixed bit-length. ++ * ++ * We unconditionally perform both of these additions to prevent a ++ * small timing information leakage. We then choose the sum that is ++ * one bit longer than the order. This guarantees the code ++ * path used in the constant time implementations elsewhere. ++ * ++ * TODO: revisit the BN_copy aiming for a memory access agnostic ++ * conditional copy. + */ +- +- if (!BN_add(k, k, order)) ++ if (!BN_add(r, k, order) ++ || !BN_add(X, r, order) ++ || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X)) + goto err; +- if (BN_num_bits(k) <= BN_num_bits(order)) +- if (!BN_add(k, k, order)) +- goto err; + + /* compute r the x-coordinate of generator * k */ + if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { +@@ -237,13 +252,14 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey) + { + int ok = 0, i; +- BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; ++ BIGNUM *kinv = NULL, *s, *m = NULL, *order = NULL; + const BIGNUM *ckinv; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + ECDSA_SIG *ret; + ECDSA_DATA *ecdsa; + const BIGNUM *priv_key; ++ BN_MONT_CTX *mont_data; + + ecdsa = ecdsa_check(eckey); + group = EC_KEY_get0_group(eckey); +@@ -262,7 +278,7 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + s = ret->s; + + if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || +- (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { ++ (m = BN_new()) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } +@@ -271,6 +287,8 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); + goto err; + } ++ mont_data = EC_GROUP_get_mont_data(group); ++ + i = BN_num_bits(order); + /* + * Need to truncate digest if it is too long: first truncate whole bytes. +@@ -301,21 +319,33 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + } + } + +- if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { +- ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); ++ /* ++ * With only one multiplicant being in Montgomery domain ++ * multiplication yields real result without post-conversion. ++ * Also note that all operations but last are performed with ++ * zero-padded vectors. Last operation, BN_mod_mul_montgomery ++ * below, returns user-visible value with removed zero padding. ++ */ ++ if (!bn_to_mont_fixed_top(s, ret->r, mont_data, ctx) ++ || !bn_mul_mont_fixed_top(s, s, priv_key, mont_data, ctx)) { + goto err; + } +- if (!BN_mod_add_quick(s, tmp, m, order)) { ++ if (!bn_mod_add_fixed_top(s, s, m, order)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } +- if (!BN_mod_mul(s, s, ckinv, order, ctx)) { ++ /* ++ * |s| can still be larger than modulus, because |m| can be. In ++ * such case we count on Montgomery reduction to tie it up. ++ */ ++ if (!bn_to_mont_fixed_top(s, s, mont_data, ctx) ++ || !BN_mod_mul_montgomery(s, s, ckinv, mont_data, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (BN_is_zero(s)) { + /* +- * if kinv and r have been supplied by the caller don't to ++ * if kinv and r have been supplied by the caller don't + * generate new kinv and r values + */ + if (in_kinv != NULL && in_r != NULL) { +@@ -339,8 +369,6 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + BN_CTX_free(ctx); + if (m) + BN_clear_free(m); +- if (tmp) +- BN_clear_free(tmp); + if (order) + BN_free(order); + if (kinv) diff --git a/openssl-1.0.2k-cve-2018-0732.patch b/openssl-1.0.2k-cve-2018-0732.patch new file mode 100644 index 0000000..1b8920f --- /dev/null +++ b/openssl-1.0.2k-cve-2018-0732.patch @@ -0,0 +1,24 @@ +diff -up openssl-1.0.2k/crypto/dh/dh_key.c.large-dh openssl-1.0.2k/crypto/dh/dh_key.c +--- openssl-1.0.2k/crypto/dh/dh_key.c.large-dh 2018-06-18 13:46:24.268137362 +0200 ++++ openssl-1.0.2k/crypto/dh/dh_key.c 2018-06-18 13:59:04.605497462 +0200 +@@ -133,7 +133,7 @@ static int generate_key(DH *dh) + int ok = 0; + int generate_new_key = 0; + unsigned l; +- BN_CTX *ctx; ++ BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + +@@ -145,6 +145,11 @@ static int generate_key(DH *dh) + } + #endif + ++ if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { ++ DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); ++ return 0; ++ } ++ + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; diff --git a/openssl-1.0.2k-cve-2018-0737.patch b/openssl-1.0.2k-cve-2018-0737.patch new file mode 100644 index 0000000..b0cdc35 --- /dev/null +++ b/openssl-1.0.2k-cve-2018-0737.patch @@ -0,0 +1,96 @@ +diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c +index c7f1dc3..aa8a7c0 100644 +--- a/crypto/rsa/rsa_gen.c ++++ b/crypto/rsa/rsa_gen.c +@@ -177,6 +177,17 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + BIGNUM *pr0, *d, *p; + int bitsp, bitsq, ok = -1, n = 0; + BN_CTX *ctx = NULL; ++ unsigned long error = 0; ++ ++ /* ++ * When generating ridiculously small keys, we can get stuck ++ * continually regenerating the same prime values. ++ */ ++ if (bits < 16) { ++ ok = 0; /* we set our own err */ ++ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); ++ goto err; ++ } + + #ifdef OPENSSL_FIPS + if (FIPS_module_mode()) { +@@ -233,45 +244,55 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + ++ BN_set_flags(rsa->p, BN_FLG_CONSTTIME); ++ BN_set_flags(rsa->q, BN_FLG_CONSTTIME); ++ BN_set_flags(r2, BN_FLG_CONSTTIME); + /* generate p and q */ + for (;;) { + if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2, rsa->p, BN_value_one())) + goto err; +- if (!BN_gcd(r1, r2, rsa->e, ctx)) +- goto err; +- if (BN_is_one(r1)) ++ ERR_set_mark(); ++ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { ++ /* GCD == 1 since inverse exists */ + break; ++ } ++ error = ERR_peek_last_error(); ++ if (ERR_GET_LIB(error) == ERR_LIB_BN ++ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { ++ /* GCD != 1 */ ++ ERR_pop_to_mark(); ++ } else { ++ goto err; ++ } + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + for (;;) { +- /* +- * When generating ridiculously small keys, we can get stuck +- * continually regenerating the same prime values. Check for this and +- * bail if it happens 3 times. +- */ +- unsigned int degenerate = 0; + do { + if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2, rsa->q, rsa->p)) + goto err; +- } while ((BN_ucmp(r2, r3) <= 0) && (++degenerate < 3)); +- if (degenerate == 3) { +- ok = 0; /* we set our own err */ +- RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); +- goto err; +- } ++ } while (BN_ucmp(r2, r3) <= 0); + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; +- if (!BN_gcd(r1, r2, rsa->e, ctx)) +- goto err; +- if (BN_is_one(r1)) ++ ERR_set_mark(); ++ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { ++ /* GCD == 1 since inverse exists */ + break; ++ } ++ error = ERR_peek_last_error(); ++ if (ERR_GET_LIB(error) == ERR_LIB_BN ++ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { ++ /* GCD != 1 */ ++ ERR_pop_to_mark(); ++ } else { ++ goto err; ++ } + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } diff --git a/openssl-1.0.2k-cve-2018-0739.patch b/openssl-1.0.2k-cve-2018-0739.patch new file mode 100644 index 0000000..14d5e0b --- /dev/null +++ b/openssl-1.0.2k-cve-2018-0739.patch @@ -0,0 +1,217 @@ +diff -up openssl-1.0.2k/crypto/asn1/asn1_err.c.asn1-recursive openssl-1.0.2k/crypto/asn1/asn1_err.c +--- openssl-1.0.2k/crypto/asn1/asn1_err.c.asn1-recursive 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/asn1/asn1_err.c 2018-06-18 15:08:18.333412753 +0200 +@@ -279,6 +279,7 @@ static ERR_STRING_DATA ASN1_str_reasons[ + {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"}, + {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"}, + {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"}, ++ {ERR_REASON(ASN1_R_NESTED_TOO_DEEP), "nested too deep"}, + {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"}, + {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"}, + {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"}, +diff -up openssl-1.0.2k/crypto/asn1/asn1.h.asn1-recursive openssl-1.0.2k/crypto/asn1/asn1.h +--- openssl-1.0.2k/crypto/asn1/asn1.h.asn1-recursive 2018-06-18 13:46:23.857127431 +0200 ++++ openssl-1.0.2k/crypto/asn1/asn1.h 2018-06-18 15:07:53.915826715 +0200 +@@ -1365,6 +1365,7 @@ void ERR_load_ASN1_strings(void); + # define ASN1_R_MSTRING_NOT_UNIVERSAL 139 + # define ASN1_R_MSTRING_WRONG_TAG 140 + # define ASN1_R_NESTED_ASN1_STRING 197 ++# define ASN1_R_NESTED_TOO_DEEP 219 + # define ASN1_R_NON_HEX_CHARACTERS 141 + # define ASN1_R_NOT_ASCII_FORMAT 190 + # define ASN1_R_NOT_ENOUGH_DATA 142 +diff -up openssl-1.0.2k/crypto/asn1/tasn_dec.c.asn1-recursive openssl-1.0.2k/crypto/asn1/tasn_dec.c +--- openssl-1.0.2k/crypto/asn1/tasn_dec.c.asn1-recursive 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/asn1/tasn_dec.c 2018-06-18 15:14:28.978308482 +0200 +@@ -4,7 +4,7 @@ + * 2000. + */ + /* ==================================================================== +- * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 2000-2018 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 +@@ -65,6 +65,14 @@ + #include + #include + ++/* ++ * Constructed types with a recursive definition (such as can be found in PKCS7) ++ * could eventually exceed the stack given malicious input with excessive ++ * recursion. Therefore we limit the stack depth. This is the maximum number of ++ * recursive invocations of asn1_item_embed_d2i(). ++ */ ++#define ASN1_MAX_CONSTRUCTED_NEST 30 ++ + static int asn1_check_eoc(const unsigned char **in, long len); + static int asn1_find_end(const unsigned char **in, long len, char inf); + +@@ -81,11 +89,11 @@ static int asn1_check_tlen(long *olen, i + static int asn1_template_ex_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx); ++ ASN1_TLC *ctx, int depth); + static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx); ++ ASN1_TLC *ctx, int depth); + static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, +@@ -154,17 +162,16 @@ int ASN1_template_d2i(ASN1_VALUE **pval, + { + ASN1_TLC c; + asn1_tlc_clear_nc(&c); +- return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); ++ return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0); + } + + /* + * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and + * tag mismatch return -1 to handle OPTIONAL + */ +- +-int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, +- const ASN1_ITEM *it, +- int tag, int aclass, char opt, ASN1_TLC *ctx) ++static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, ++ long len, const ASN1_ITEM *it, int tag, int aclass, ++ char opt, ASN1_TLC *ctx, int depth) + { + const ASN1_TEMPLATE *tt, *errtt = NULL; + const ASN1_COMPAT_FUNCS *cf; +@@ -189,6 +196,11 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + else + asn1_cb = 0; + ++ if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { ++ ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NESTED_TOO_DEEP); ++ goto err; ++ } ++ + switch (it->itype) { + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { +@@ -204,7 +216,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + goto err; + } + return asn1_template_ex_d2i(pval, in, len, +- it->templates, opt, ctx); ++ it->templates, opt, ctx, depth); + } + return asn1_d2i_ex_primitive(pval, in, len, it, + tag, aclass, opt, ctx); +@@ -326,7 +338,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + /* + * We mark field as OPTIONAL so its absence can be recognised. + */ +- ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); ++ ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); + /* If field not present, try the next one */ + if (ret == -1) + continue; +@@ -444,7 +456,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + * attempt to read in field, allowing each to be OPTIONAL + */ + +- ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); ++ ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, ++ depth); + if (!ret) { + errtt = seqtt; + goto err; +@@ -514,6 +527,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + return 0; + } + ++int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, ++ const ASN1_ITEM *it, ++ int tag, int aclass, char opt, ASN1_TLC *ctx) ++{ ++ return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); ++} ++ + /* + * Templates are handled with two separate functions. One handles any + * EXPLICIT tag and the other handles the rest. +@@ -522,7 +542,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + static int asn1_template_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long inlen, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx) ++ ASN1_TLC *ctx, int depth) + { + int flags, aclass; + int ret; +@@ -557,7 +577,7 @@ static int asn1_template_ex_d2i(ASN1_VAL + return 0; + } + /* We've found the field so it can't be OPTIONAL now */ +- ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); ++ ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; +@@ -581,7 +601,7 @@ static int asn1_template_ex_d2i(ASN1_VAL + } + } + } else +- return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); ++ return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); + + *in = p; + return 1; +@@ -594,7 +614,7 @@ static int asn1_template_ex_d2i(ASN1_VAL + static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, +- ASN1_TLC *ctx) ++ ASN1_TLC *ctx, int depth) + { + int flags, aclass; + int ret; +@@ -665,14 +685,15 @@ static int asn1_template_noexp_d2i(ASN1_ + break; + } + skfield = NULL; +- if (!ASN1_item_ex_d2i(&skfield, &p, len, +- ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { ++ if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), ++ -1, 0, 0, ctx, depth)) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); + goto err; + } + len -= p - q; + if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { ++ ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); + goto err; + } +@@ -683,9 +704,8 @@ static int asn1_template_noexp_d2i(ASN1_ + } + } else if (flags & ASN1_TFLG_IMPTAG) { + /* IMPLICIT tagging */ +- ret = ASN1_item_ex_d2i(val, &p, len, +- ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, +- ctx); ++ ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, ++ aclass, opt, ctx, depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; +@@ -693,8 +713,9 @@ static int asn1_template_noexp_d2i(ASN1_ + return -1; + } else { + /* Nothing special */ +- ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), +- -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); ++ ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), ++ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, ++ depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; diff --git a/openssl-1.0.2k-long-hello.patch b/openssl-1.0.2k-long-hello.patch new file mode 100644 index 0000000..358b027 --- /dev/null +++ b/openssl-1.0.2k-long-hello.patch @@ -0,0 +1,36 @@ +diff -up openssl-1.0.2k/ssl/s3_srvr.c.long-hello openssl-1.0.2k/ssl/s3_srvr.c +--- openssl-1.0.2k/ssl/s3_srvr.c.long-hello 2017-03-09 17:59:26.000000000 +0100 ++++ openssl-1.0.2k/ssl/s3_srvr.c 2017-03-30 09:11:35.639338753 +0200 +@@ -899,6 +899,23 @@ int ssl3_send_hello_request(SSL *s) + return ssl_do_write(s); + } + ++/* ++ * Maximum size (excluding the Handshake header) of a ClientHello message, ++ * calculated as follows: ++ * ++ * 2 + # client_version ++ * 32 + # only valid length for random ++ * 1 + # length of session_id ++ * 32 + # maximum size for session_id ++ * 2 + # length of cipher suites ++ * 2^16-2 + # maximum length of cipher suites array ++ * 1 + # length of compression_methods ++ * 2^8-1 + # maximum length of compression methods ++ * 2 + # length of extensions ++ * 2^16-1 # maximum length of extensions ++ */ ++#define CLIENT_HELLO_MAX_LENGTH 131396 ++ + int ssl3_get_client_hello(SSL *s) + { + int i, j, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1, cookie_valid = 0; +@@ -930,7 +947,7 @@ int ssl3_get_client_hello(SSL *s) + SSL3_ST_SR_CLNT_HELLO_B, + SSL3_ST_SR_CLNT_HELLO_C, + SSL3_MT_CLIENT_HELLO, +- SSL3_RT_MAX_PLAIN_LENGTH, &ok); ++ CLIENT_HELLO_MAX_LENGTH, &ok); + + if (!ok) + return ((int)n); diff --git a/openssl-1.0.2k-name-sensitive.patch b/openssl-1.0.2k-name-sensitive.patch new file mode 100644 index 0000000..909ce30 --- /dev/null +++ b/openssl-1.0.2k-name-sensitive.patch @@ -0,0 +1,57 @@ +diff -up openssl-1.0.2k/ssl/ssl_cert.c.name-sensitive openssl-1.0.2k/ssl/ssl_cert.c +--- openssl-1.0.2k/ssl/ssl_cert.c.name-sensitive 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/ssl/ssl_cert.c 2018-06-18 13:43:12.452502627 +0200 +@@ -855,9 +855,33 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx, + return (add_client_CA(&(ctx->client_CA), x)); + } + +-static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) ++static int xname_cmp(const X509_NAME *a, const X509_NAME *b) + { +- return (X509_NAME_cmp(*a, *b)); ++ unsigned char *abuf = NULL, *bbuf = NULL; ++ int alen, blen, ret; ++ ++ /* X509_NAME_cmp() itself casts away constness in this way, so ++ * assume it's safe: ++ */ ++ alen = i2d_X509_NAME((X509_NAME *)a, &abuf); ++ blen = i2d_X509_NAME((X509_NAME *)b, &bbuf); ++ ++ if (alen < 0 || blen < 0) ++ ret = -2; ++ else if (alen != blen) ++ ret = alen - blen; ++ else /* alen == blen */ ++ ret = memcmp(abuf, bbuf, alen); ++ ++ OPENSSL_free(abuf); ++ OPENSSL_free(bbuf); ++ ++ return ret; ++} ++ ++static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b) ++{ ++ return xname_cmp(*a, *b); + } + + #ifndef OPENSSL_NO_STDIO +@@ -876,7 +900,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_ + X509_NAME *xn = NULL; + STACK_OF(X509_NAME) *ret = NULL, *sk; + +- sk = sk_X509_NAME_new(xname_cmp); ++ sk = sk_X509_NAME_new(xname_sk_cmp); + + in = BIO_new(BIO_s_file_internal()); + +@@ -948,7 +972,7 @@ int SSL_add_file_cert_subjects_to_stack( + int ret = 1; + int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); + +- oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); ++ oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp); + + in = BIO_new(BIO_s_file_internal()); + diff --git a/openssl-1.0.2k-no-ssl2.patch b/openssl-1.0.2k-no-ssl2.patch new file mode 100644 index 0000000..c668417 --- /dev/null +++ b/openssl-1.0.2k-no-ssl2.patch @@ -0,0 +1,217 @@ +diff -up openssl-1.0.2k/apps/ciphers.c.no-ssl2 openssl-1.0.2k/apps/ciphers.c +--- openssl-1.0.2k/apps/ciphers.c.no-ssl2 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/apps/ciphers.c 2017-03-01 14:18:28.058046372 +0100 +@@ -73,7 +73,9 @@ static const char *ciphers_usage[] = { + "usage: ciphers args\n", + " -v - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n", + " -V - even more verbose\n", ++#ifndef OPENSSL_NO_SSL2 + " -ssl2 - SSL2 mode\n", ++#endif + " -ssl3 - SSL3 mode\n", + " -tls1 - TLS1 mode\n", + NULL +diff -up openssl-1.0.2k/apps/s_client.c.no-ssl2 openssl-1.0.2k/apps/s_client.c +--- openssl-1.0.2k/apps/s_client.c.no-ssl2 2017-03-01 14:04:57.000000000 +0100 ++++ openssl-1.0.2k/apps/s_client.c 2017-03-01 14:17:42.368974209 +0100 +@@ -380,7 +380,9 @@ static void sc_usage(void) + " -srp_strength int - minimal length in bits for N (default %d).\n", + SRP_MINIMAL_N); + #endif ++#ifndef OPENSSL_NO_SSL2 + BIO_printf(bio_err, " -ssl2 - just use SSLv2\n"); ++#endif + #ifndef OPENSSL_NO_SSL3_METHOD + BIO_printf(bio_err, " -ssl3 - just use SSLv3\n"); + #endif +diff -up openssl-1.0.2k/apps/s_server.c.no-ssl2 openssl-1.0.2k/apps/s_server.c +--- openssl-1.0.2k/apps/s_server.c.no-ssl2 2017-02-15 11:33:38.000000000 +0100 ++++ openssl-1.0.2k/apps/s_server.c 2017-03-01 14:13:54.154618822 +0100 +@@ -598,7 +598,9 @@ static void sv_usage(void) + BIO_printf(bio_err, + " -srpuserseed string - A seed string for a default user salt.\n"); + #endif ++#ifndef OPENSSL_NO_SSL2 + BIO_printf(bio_err, " -ssl2 - Just talk SSLv2\n"); ++#endif + #ifndef OPENSSL_NO_SSL3_METHOD + BIO_printf(bio_err, " -ssl3 - Just talk SSLv3\n"); + #endif +@@ -610,7 +612,7 @@ static void sv_usage(void) + BIO_printf(bio_err, " -timeout - Enable timeouts\n"); + BIO_printf(bio_err, " -mtu - Set link layer MTU\n"); + BIO_printf(bio_err, " -chain - Read a certificate chain\n"); +- BIO_printf(bio_err, " -no_ssl2 - Just disable SSLv2\n"); ++ BIO_printf(bio_err, " -no_ssl2 - No-op, SSLv2 is always disabled\n"); + BIO_printf(bio_err, " -no_ssl3 - Just disable SSLv3\n"); + BIO_printf(bio_err, " -no_tls1 - Just disable TLSv1\n"); + BIO_printf(bio_err, " -no_tls1_1 - Just disable TLSv1.1\n"); +diff -up openssl-1.0.2k/apps/s_time.c.no-ssl2 openssl-1.0.2k/apps/s_time.c +--- openssl-1.0.2k/apps/s_time.c.no-ssl2 2017-02-15 11:33:38.000000000 +0100 ++++ openssl-1.0.2k/apps/s_time.c 2017-03-01 14:20:15.708572549 +0100 +@@ -191,7 +191,9 @@ static void s_time_usage(void) + SSL_CONNECT_NAME); + #ifdef FIONBIO + printf("-nbio - Run with non-blocking IO\n"); ++#ifndef OPENSSL_NO_SSL2 + printf("-ssl2 - Just use SSLv2\n"); ++#endif + printf("-ssl3 - Just use SSLv3\n"); + printf("-bugs - Turn on SSL bug compatibility\n"); + printf("-new - Just time new connections\n"); +diff -up openssl-1.0.2k/doc/apps/ciphers.pod.no-ssl2 openssl-1.0.2k/doc/apps/ciphers.pod +--- openssl-1.0.2k/doc/apps/ciphers.pod.no-ssl2 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/doc/apps/ciphers.pod 2017-03-01 14:02:51.275041593 +0100 +@@ -9,7 +9,6 @@ ciphers - SSL cipher display and cipher + B B + [B<-v>] + [B<-V>] +-[B<-ssl2>] + [B<-ssl3>] + [B<-tls1>] + [B] +@@ -42,10 +41,6 @@ Like B<-v>, but include cipher suite cod + + This lists ciphers compatible with any of SSLv3, TLSv1, TLSv1.1 or TLSv1.2. + +-=item B<-ssl2> +- +-Only include SSLv2 ciphers. +- + =item B<-h>, B<-?> + + Print a brief usage message. +diff -up openssl-1.0.2k/doc/apps/s_client.pod.no-ssl2 openssl-1.0.2k/doc/apps/s_client.pod +--- openssl-1.0.2k/doc/apps/s_client.pod.no-ssl2 2017-03-01 14:04:57.000000000 +0100 ++++ openssl-1.0.2k/doc/apps/s_client.pod 2017-03-01 14:06:28.389146669 +0100 +@@ -33,13 +33,11 @@ B B + [B<-ign_eof>] + [B<-no_ign_eof>] + [B<-quiet>] +-[B<-ssl2>] + [B<-ssl3>] + [B<-tls1>] + [B<-tls1_1>] + [B<-tls1_2>] + [B<-dtls1>] +-[B<-no_ssl2>] + [B<-no_ssl3>] + [B<-no_tls1>] + [B<-no_tls1_1>] +@@ -207,7 +205,7 @@ Use the PSK key B when using a PSK + given as a hexadecimal number without leading 0x, for example -psk + 1a2b3c4d. + +-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-dtls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> ++=item B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-dtls1>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> + + These options require or disable the use of the specified SSL or TLS protocols. + By default the initial handshake uses a I method which will +@@ -326,8 +324,8 @@ would typically be used (https uses port + then an HTTP command can be given such as "GET /" to retrieve a web page. + + If the handshake fails then there are several possible causes, if it is +-nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>, +-B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> options can be tried ++nothing obvious like no client certificate then the B<-bugs>, ++B<-ssl3>, B<-tls1>, B<-no_ssl3>, B<-no_tls1> options can be tried + in case it is a buggy server. In particular you should play with these + options B submitting a bug report to an OpenSSL mailing list. + +@@ -349,10 +347,6 @@ on the command line is no guarantee that + If there are problems verifying a server certificate then the + B<-showcerts> option can be used to show the whole chain. + +-Since the SSLv23 client hello cannot include compression methods or extensions +-these will only be supported if its use is disabled, for example by using the +-B<-no_sslv2> option. +- + The B utility is a test tool and is designed to continue the + handshake after any certificate verification errors. As a result it will + accept any certificate chain (trusted or not) sent by the peer. None test +diff -up openssl-1.0.2k/doc/apps/s_server.pod.no-ssl2 openssl-1.0.2k/doc/apps/s_server.pod +--- openssl-1.0.2k/doc/apps/s_server.pod.no-ssl2 2017-03-01 14:04:57.000000000 +0100 ++++ openssl-1.0.2k/doc/apps/s_server.pod 2017-03-01 14:04:17.871077754 +0100 +@@ -42,12 +42,10 @@ B B + [B<-keytab filename>] + [B<-quiet>] + [B<-no_tmp_rsa>] +-[B<-ssl2>] + [B<-ssl3>] + [B<-tls1>] + [B<-tls1_1>] + [B<-tls1_2>] +-[B<-no_ssl2>] + [B<-no_ssl3>] + [B<-no_tls1>] + [B<-no_dhe>] +@@ -229,7 +227,7 @@ Use the PSK key B when using a PSK + given as a hexadecimal number without leading 0x, for example -psk + 1a2b3c4d. + +-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-dtls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> ++=item B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-dtls1>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> + + These options require or disable the use of the specified SSL or TLS protocols. + By default the initial handshake uses a I method which will +diff -up openssl-1.0.2k/doc/apps/s_time.pod.no-ssl2 openssl-1.0.2k/doc/apps/s_time.pod +--- openssl-1.0.2k/doc/apps/s_time.pod.no-ssl2 2017-02-15 11:33:38.000000000 +0100 ++++ openssl-1.0.2k/doc/apps/s_time.pod 2017-03-01 14:03:50.440432769 +0100 +@@ -20,7 +20,6 @@ B B + [B<-verify depth>] + [B<-nbio>] + [B<-time seconds>] +-[B<-ssl2>] + [B<-ssl3>] + [B<-bugs>] + [B<-cipher cipherlist>] +@@ -99,9 +98,9 @@ specified, they are both on by default a + + turns on non-blocking I/O. + +-=item B<-ssl2>, B<-ssl3> ++=item B<-ssl3> + +-these options disable the use of certain SSL or TLS protocols. By default ++this option disables the use of certain SSL or TLS protocols. By default + the initial handshake uses a method which should be compatible with all + servers and permit them to use SSL v3, SSL v2 or TLS as appropriate. + The timing program is not as rich in options to turn protocols on and off as +@@ -109,8 +108,7 @@ the L program a + + Unfortunately there are a lot of ancient and broken servers in use which + cannot handle this technique and will fail to connect. Some servers only +-work if TLS is turned off with the B<-ssl3> option; others +-will only support SSL v2 and may need the B<-ssl2> option. ++work if TLS is turned off with the B<-ssl3> option. + + =item B<-bugs> + +@@ -144,7 +142,7 @@ which both client and server can agree, + for details. + + If the handshake fails then there are several possible causes, if it is +-nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>, ++nothing obvious like no client certificate then the B<-bugs>, + B<-ssl3> options can be tried + in case it is a buggy server. In particular you should play with these + options B submitting a bug report to an OpenSSL mailing list. +diff -up openssl-1.0.2k/doc/ssl/SSL_CTX_new.pod.no-ssl2 openssl-1.0.2k/doc/ssl/SSL_CTX_new.pod +--- openssl-1.0.2k/doc/ssl/SSL_CTX_new.pod.no-ssl2 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/doc/ssl/SSL_CTX_new.pod 2017-03-01 14:09:12.981016773 +0100 +@@ -123,13 +123,8 @@ used. + + =item SSLv2_method(), SSLv2_server_method(), SSLv2_client_method() + +-A TLS/SSL connection established with these methods will only understand the +-SSLv2 protocol. A client will send out SSLv2 client hello messages and will +-also indicate that it only understand SSLv2. A server will only understand +-SSLv2 client hello messages. The SSLv2 protocol offers little to no security +-and should not be used. +-As of OpenSSL 1.0.2g, EXPORT ciphers and 56-bit DES are no longer available +-with SSLv2. ++These calls are provided only as stubs for keeping ABI compatibility. There ++is no support for SSLv2 built in the library. + + =item DTLS_method(), DTLS_server_method(), DTLS_client_method() + diff --git a/openssl-1.0.2k-ppc-update.patch b/openssl-1.0.2k-ppc-update.patch new file mode 100644 index 0000000..a5efdfa --- /dev/null +++ b/openssl-1.0.2k-ppc-update.patch @@ -0,0 +1,1932 @@ +diff -up openssl-1.0.2k/crypto/aes/asm/aesp8-ppc.pl.ppc-update openssl-1.0.2k/crypto/aes/asm/aesp8-ppc.pl +--- openssl-1.0.2k/crypto/aes/asm/aesp8-ppc.pl.ppc-update 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/aes/asm/aesp8-ppc.pl 2017-04-13 09:51:40.611133165 +0200 +@@ -20,6 +20,19 @@ + # instructions are interleaved. It's reckoned that eventual + # misalignment penalties at page boundaries are in average lower + # than additional overhead in pure AltiVec approach. ++# ++# May 2016 ++# ++# Add XTS subroutine, 9x on little- and 12x improvement on big-endian ++# systems were measured. ++# ++###################################################################### ++# Current large-block performance in cycles per byte processed with ++# 128-bit key (less is better). ++# ++# CBC en-/decrypt CTR XTS ++# POWER8[le] 3.96/0.72 0.74 1.1 ++# POWER8[be] 3.75/0.65 0.66 1.0 + + $flavour = shift; + +@@ -486,6 +499,8 @@ $code.=<<___; + .globl .${prefix}_cbc_encrypt + .align 5 + .${prefix}_cbc_encrypt: ++ li $idx,15 ++ andc $len,$len,$idx + ${UCMP}i $len,16 + bltlr- + +@@ -494,7 +509,6 @@ $code.=<<___; + mfspr $vrsave,256 + mtspr 256,r0 + +- li $idx,15 + vxor $rndkey0,$rndkey0,$rndkey0 + le?vspltisb $tmp,0x0f + +@@ -1887,6 +1901,1849 @@ Lctr32_enc8x_done: + ___ + }} }}} + ++######################################################################### ++{{{ # XTS procedures # ++# int aes_p8_xts_[en|de]crypt(const char *inp, char *out, size_t len, # ++# const AES_KEY *key1, const AES_KEY *key2, # ++# [const] unsigned char iv[16]); # ++# If $key2 is NULL, then a "tweak chaining" mode is engaged, in which # ++# input tweak value is assumed to be encrypted already, and last tweak # ++# value, one suitable for consecutive call on same chunk of data, is # ++# written back to original buffer. In addition, in "tweak chaining" # ++# mode only complete input blocks are processed. # ++ ++my ($inp,$out,$len,$key1,$key2,$ivp,$rounds,$idx) = map("r$_",(3..10)); ++my ($rndkey0,$rndkey1,$inout) = map("v$_",(0..2)); ++my ($output,$inptail,$inpperm,$leperm,$keyperm) = map("v$_",(3..7)); ++my ($tweak,$seven,$eighty7,$tmp,$tweak1) = map("v$_",(8..12)); ++my $taillen = $key2; ++ ++ ($inp,$idx) = ($idx,$inp); # reassign ++ ++$code.=<<___; ++.globl .${prefix}_xts_encrypt ++.align 5 ++.${prefix}_xts_encrypt: ++ mr $inp,r3 # reassign ++ li r3,-1 ++ ${UCMP}i $len,16 ++ bltlr- ++ ++ lis r0,0xfff0 ++ mfspr r12,256 # save vrsave ++ li r11,0 ++ mtspr 256,r0 ++ ++ vspltisb $seven,0x07 # 0x070707..07 ++ le?lvsl $leperm,r11,r11 ++ le?vspltisb $tmp,0x0f ++ le?vxor $leperm,$leperm,$seven ++ ++ li $idx,15 ++ lvx $tweak,0,$ivp # load [unaligned] iv ++ lvsl $inpperm,0,$ivp ++ lvx $inptail,$idx,$ivp ++ le?vxor $inpperm,$inpperm,$tmp ++ vperm $tweak,$tweak,$inptail,$inpperm ++ ++ neg r11,$inp ++ lvsr $inpperm,0,r11 # prepare for unaligned load ++ lvx $inout,0,$inp ++ addi $inp,$inp,15 # 15 is not typo ++ le?vxor $inpperm,$inpperm,$tmp ++ ++ ${UCMP}i $key2,0 # key2==NULL? ++ beq Lxts_enc_no_key2 ++ ++ ?lvsl $keyperm,0,$key2 # prepare for unaligned key ++ lwz $rounds,240($key2) ++ srwi $rounds,$rounds,1 ++ subi $rounds,$rounds,1 ++ li $idx,16 ++ ++ lvx $rndkey0,0,$key2 ++ lvx $rndkey1,$idx,$key2 ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $tweak,$tweak,$rndkey0 ++ lvx $rndkey0,$idx,$key2 ++ addi $idx,$idx,16 ++ mtctr $rounds ++ ++Ltweak_xts_enc: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $tweak,$tweak,$rndkey1 ++ lvx $rndkey1,$idx,$key2 ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipher $tweak,$tweak,$rndkey0 ++ lvx $rndkey0,$idx,$key2 ++ addi $idx,$idx,16 ++ bdnz Ltweak_xts_enc ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $tweak,$tweak,$rndkey1 ++ lvx $rndkey1,$idx,$key2 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipherlast $tweak,$tweak,$rndkey0 ++ ++ li $ivp,0 # don't chain the tweak ++ b Lxts_enc ++ ++Lxts_enc_no_key2: ++ li $idx,-16 ++ and $len,$len,$idx # in "tweak chaining" ++ # mode only complete ++ # blocks are processed ++Lxts_enc: ++ lvx $inptail,0,$inp ++ addi $inp,$inp,16 ++ ++ ?lvsl $keyperm,0,$key1 # prepare for unaligned key ++ lwz $rounds,240($key1) ++ srwi $rounds,$rounds,1 ++ subi $rounds,$rounds,1 ++ li $idx,16 ++ ++ vslb $eighty7,$seven,$seven # 0x808080..80 ++ vor $eighty7,$eighty7,$seven # 0x878787..87 ++ vspltisb $tmp,1 # 0x010101..01 ++ vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01 ++ ++ ${UCMP}i $len,96 ++ bge _aesp8_xts_encrypt6x ++ ++ andi. $taillen,$len,15 ++ subic r0,$len,32 ++ subi $taillen,$taillen,16 ++ subfe r0,r0,r0 ++ and r0,r0,$taillen ++ add $inp,$inp,r0 ++ ++ lvx $rndkey0,0,$key1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ vperm $inout,$inout,$inptail,$inpperm ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $inout,$inout,$tweak ++ vxor $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ mtctr $rounds ++ b Loop_xts_enc ++ ++.align 5 ++Loop_xts_enc: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipher $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ bdnz Loop_xts_enc ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key1 ++ li $idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $rndkey0,$rndkey0,$tweak ++ vcipherlast $output,$inout,$rndkey0 ++ ++ le?vperm $tmp,$output,$output,$leperm ++ be?nop ++ le?stvx_u $tmp,0,$out ++ be?stvx_u $output,0,$out ++ addi $out,$out,16 ++ ++ subic. $len,$len,16 ++ beq Lxts_enc_done ++ ++ vmr $inout,$inptail ++ lvx $inptail,0,$inp ++ addi $inp,$inp,16 ++ lvx $rndkey0,0,$key1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ ++ subic r0,$len,32 ++ subfe r0,r0,r0 ++ and r0,r0,$taillen ++ add $inp,$inp,r0 ++ ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vand $tmp,$tmp,$eighty7 ++ vxor $tweak,$tweak,$tmp ++ ++ vperm $inout,$inout,$inptail,$inpperm ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $inout,$inout,$tweak ++ vxor $output,$output,$rndkey0 # just in case $len<16 ++ vxor $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ ++ mtctr $rounds ++ ${UCMP}i $len,16 ++ bge Loop_xts_enc ++ ++ vxor $output,$output,$tweak ++ lvsr $inpperm,0,$len # $inpperm is no longer needed ++ vxor $inptail,$inptail,$inptail # $inptail is no longer needed ++ vspltisb $tmp,-1 ++ vperm $inptail,$inptail,$tmp,$inpperm ++ vsel $inout,$inout,$output,$inptail ++ ++ subi r11,$out,17 ++ subi $out,$out,16 ++ mtctr $len ++ li $len,16 ++Loop_xts_enc_steal: ++ lbzu r0,1(r11) ++ stb r0,16(r11) ++ bdnz Loop_xts_enc_steal ++ ++ mtctr $rounds ++ b Loop_xts_enc # one more time... ++ ++Lxts_enc_done: ++ ${UCMP}i $ivp,0 ++ beq Lxts_enc_ret ++ ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vand $tmp,$tmp,$eighty7 ++ vxor $tweak,$tweak,$tmp ++ ++ le?vperm $tweak,$tweak,$tweak,$leperm ++ stvx_u $tweak,0,$ivp ++ ++Lxts_enc_ret: ++ mtspr 256,r12 # restore vrsave ++ li r3,0 ++ blr ++ .long 0 ++ .byte 0,12,0x04,0,0x80,6,6,0 ++ .long 0 ++.size .${prefix}_xts_encrypt,.-.${prefix}_xts_encrypt ++ ++.globl .${prefix}_xts_decrypt ++.align 5 ++.${prefix}_xts_decrypt: ++ mr $inp,r3 # reassign ++ li r3,-1 ++ ${UCMP}i $len,16 ++ bltlr- ++ ++ lis r0,0xfff8 ++ mfspr r12,256 # save vrsave ++ li r11,0 ++ mtspr 256,r0 ++ ++ andi. r0,$len,15 ++ neg r0,r0 ++ andi. r0,r0,16 ++ sub $len,$len,r0 ++ ++ vspltisb $seven,0x07 # 0x070707..07 ++ le?lvsl $leperm,r11,r11 ++ le?vspltisb $tmp,0x0f ++ le?vxor $leperm,$leperm,$seven ++ ++ li $idx,15 ++ lvx $tweak,0,$ivp # load [unaligned] iv ++ lvsl $inpperm,0,$ivp ++ lvx $inptail,$idx,$ivp ++ le?vxor $inpperm,$inpperm,$tmp ++ vperm $tweak,$tweak,$inptail,$inpperm ++ ++ neg r11,$inp ++ lvsr $inpperm,0,r11 # prepare for unaligned load ++ lvx $inout,0,$inp ++ addi $inp,$inp,15 # 15 is not typo ++ le?vxor $inpperm,$inpperm,$tmp ++ ++ ${UCMP}i $key2,0 # key2==NULL? ++ beq Lxts_dec_no_key2 ++ ++ ?lvsl $keyperm,0,$key2 # prepare for unaligned key ++ lwz $rounds,240($key2) ++ srwi $rounds,$rounds,1 ++ subi $rounds,$rounds,1 ++ li $idx,16 ++ ++ lvx $rndkey0,0,$key2 ++ lvx $rndkey1,$idx,$key2 ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $tweak,$tweak,$rndkey0 ++ lvx $rndkey0,$idx,$key2 ++ addi $idx,$idx,16 ++ mtctr $rounds ++ ++Ltweak_xts_dec: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $tweak,$tweak,$rndkey1 ++ lvx $rndkey1,$idx,$key2 ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipher $tweak,$tweak,$rndkey0 ++ lvx $rndkey0,$idx,$key2 ++ addi $idx,$idx,16 ++ bdnz Ltweak_xts_dec ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $tweak,$tweak,$rndkey1 ++ lvx $rndkey1,$idx,$key2 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipherlast $tweak,$tweak,$rndkey0 ++ ++ li $ivp,0 # don't chain the tweak ++ b Lxts_dec ++ ++Lxts_dec_no_key2: ++ neg $idx,$len ++ andi. $idx,$idx,15 ++ add $len,$len,$idx # in "tweak chaining" ++ # mode only complete ++ # blocks are processed ++Lxts_dec: ++ lvx $inptail,0,$inp ++ addi $inp,$inp,16 ++ ++ ?lvsl $keyperm,0,$key1 # prepare for unaligned key ++ lwz $rounds,240($key1) ++ srwi $rounds,$rounds,1 ++ subi $rounds,$rounds,1 ++ li $idx,16 ++ ++ vslb $eighty7,$seven,$seven # 0x808080..80 ++ vor $eighty7,$eighty7,$seven # 0x878787..87 ++ vspltisb $tmp,1 # 0x010101..01 ++ vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01 ++ ++ ${UCMP}i $len,96 ++ bge _aesp8_xts_decrypt6x ++ ++ lvx $rndkey0,0,$key1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ vperm $inout,$inout,$inptail,$inpperm ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $inout,$inout,$tweak ++ vxor $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ mtctr $rounds ++ ++ ${UCMP}i $len,16 ++ blt Ltail_xts_dec ++ be?b Loop_xts_dec ++ ++.align 5 ++Loop_xts_dec: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vncipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vncipher $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ bdnz Loop_xts_dec ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vncipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key1 ++ li $idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $rndkey0,$rndkey0,$tweak ++ vncipherlast $output,$inout,$rndkey0 ++ ++ le?vperm $tmp,$output,$output,$leperm ++ be?nop ++ le?stvx_u $tmp,0,$out ++ be?stvx_u $output,0,$out ++ addi $out,$out,16 ++ ++ subic. $len,$len,16 ++ beq Lxts_dec_done ++ ++ vmr $inout,$inptail ++ lvx $inptail,0,$inp ++ addi $inp,$inp,16 ++ lvx $rndkey0,0,$key1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vand $tmp,$tmp,$eighty7 ++ vxor $tweak,$tweak,$tmp ++ ++ vperm $inout,$inout,$inptail,$inpperm ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $inout,$inout,$tweak ++ vxor $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ ++ mtctr $rounds ++ ${UCMP}i $len,16 ++ bge Loop_xts_dec ++ ++Ltail_xts_dec: ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak1,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vand $tmp,$tmp,$eighty7 ++ vxor $tweak1,$tweak1,$tmp ++ ++ subi $inp,$inp,16 ++ add $inp,$inp,$len ++ ++ vxor $inout,$inout,$tweak # :-( ++ vxor $inout,$inout,$tweak1 # :-) ++ ++Loop_xts_dec_short: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vncipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vncipher $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ bdnz Loop_xts_dec_short ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vncipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key1 ++ li $idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $rndkey0,$rndkey0,$tweak1 ++ vncipherlast $output,$inout,$rndkey0 ++ ++ le?vperm $tmp,$output,$output,$leperm ++ be?nop ++ le?stvx_u $tmp,0,$out ++ be?stvx_u $output,0,$out ++ ++ vmr $inout,$inptail ++ lvx $inptail,0,$inp ++ #addi $inp,$inp,16 ++ lvx $rndkey0,0,$key1 ++ lvx $rndkey1,$idx,$key1 ++ addi $idx,$idx,16 ++ vperm $inout,$inout,$inptail,$inpperm ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ ++ lvsr $inpperm,0,$len # $inpperm is no longer needed ++ vxor $inptail,$inptail,$inptail # $inptail is no longer needed ++ vspltisb $tmp,-1 ++ vperm $inptail,$inptail,$tmp,$inpperm ++ vsel $inout,$inout,$output,$inptail ++ ++ vxor $rndkey0,$rndkey0,$tweak ++ vxor $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key1 ++ addi $idx,$idx,16 ++ ++ subi r11,$out,1 ++ mtctr $len ++ li $len,16 ++Loop_xts_dec_steal: ++ lbzu r0,1(r11) ++ stb r0,16(r11) ++ bdnz Loop_xts_dec_steal ++ ++ mtctr $rounds ++ b Loop_xts_dec # one more time... ++ ++Lxts_dec_done: ++ ${UCMP}i $ivp,0 ++ beq Lxts_dec_ret ++ ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vand $tmp,$tmp,$eighty7 ++ vxor $tweak,$tweak,$tmp ++ ++ le?vperm $tweak,$tweak,$tweak,$leperm ++ stvx_u $tweak,0,$ivp ++ ++Lxts_dec_ret: ++ mtspr 256,r12 # restore vrsave ++ li r3,0 ++ blr ++ .long 0 ++ .byte 0,12,0x04,0,0x80,6,6,0 ++ .long 0 ++.size .${prefix}_xts_decrypt,.-.${prefix}_xts_decrypt ++___ ++######################################################################### ++{{ # Optimized XTS procedures # ++my $key_=$key2; ++my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31)); ++ $x00=0 if ($flavour =~ /osx/); ++my ($in0, $in1, $in2, $in3, $in4, $in5 )=map("v$_",(0..5)); ++my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16)); ++my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22)); ++my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys ++ # v26-v31 last 6 round keys ++my ($keyperm)=($out0); # aliases with "caller", redundant assignment ++my $taillen=$x70; ++ ++$code.=<<___; ++.align 5 ++_aesp8_xts_encrypt6x: ++ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) ++ mflr r11 ++ li r7,`$FRAME+8*16+15` ++ li r3,`$FRAME+8*16+31` ++ $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp) ++ stvx v20,r7,$sp # ABI says so ++ addi r7,r7,32 ++ stvx v21,r3,$sp ++ addi r3,r3,32 ++ stvx v22,r7,$sp ++ addi r7,r7,32 ++ stvx v23,r3,$sp ++ addi r3,r3,32 ++ stvx v24,r7,$sp ++ addi r7,r7,32 ++ stvx v25,r3,$sp ++ addi r3,r3,32 ++ stvx v26,r7,$sp ++ addi r7,r7,32 ++ stvx v27,r3,$sp ++ addi r3,r3,32 ++ stvx v28,r7,$sp ++ addi r7,r7,32 ++ stvx v29,r3,$sp ++ addi r3,r3,32 ++ stvx v30,r7,$sp ++ stvx v31,r3,$sp ++ li r0,-1 ++ stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave ++ li $x10,0x10 ++ $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) ++ li $x20,0x20 ++ $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) ++ li $x30,0x30 ++ $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) ++ li $x40,0x40 ++ $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) ++ li $x50,0x50 ++ $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) ++ li $x60,0x60 ++ $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) ++ li $x70,0x70 ++ mtspr 256,r0 ++ ++ subi $rounds,$rounds,3 # -4 in total ++ ++ lvx $rndkey0,$x00,$key1 # load key schedule ++ lvx v30,$x10,$key1 ++ addi $key1,$key1,0x20 ++ lvx v31,$x00,$key1 ++ ?vperm $rndkey0,$rndkey0,v30,$keyperm ++ addi $key_,$sp,$FRAME+15 ++ mtctr $rounds ++ ++Load_xts_enc_key: ++ ?vperm v24,v30,v31,$keyperm ++ lvx v30,$x10,$key1 ++ addi $key1,$key1,0x20 ++ stvx v24,$x00,$key_ # off-load round[1] ++ ?vperm v25,v31,v30,$keyperm ++ lvx v31,$x00,$key1 ++ stvx v25,$x10,$key_ # off-load round[2] ++ addi $key_,$key_,0x20 ++ bdnz Load_xts_enc_key ++ ++ lvx v26,$x10,$key1 ++ ?vperm v24,v30,v31,$keyperm ++ lvx v27,$x20,$key1 ++ stvx v24,$x00,$key_ # off-load round[3] ++ ?vperm v25,v31,v26,$keyperm ++ lvx v28,$x30,$key1 ++ stvx v25,$x10,$key_ # off-load round[4] ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ ?vperm v26,v26,v27,$keyperm ++ lvx v29,$x40,$key1 ++ ?vperm v27,v27,v28,$keyperm ++ lvx v30,$x50,$key1 ++ ?vperm v28,v28,v29,$keyperm ++ lvx v31,$x60,$key1 ++ ?vperm v29,v29,v30,$keyperm ++ lvx $twk5,$x70,$key1 # borrow $twk5 ++ ?vperm v30,v30,v31,$keyperm ++ lvx v24,$x00,$key_ # pre-load round[1] ++ ?vperm v31,v31,$twk5,$keyperm ++ lvx v25,$x10,$key_ # pre-load round[2] ++ ++ vperm $in0,$inout,$inptail,$inpperm ++ subi $inp,$inp,31 # undo "caller" ++ vxor $twk0,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vand $tmp,$tmp,$eighty7 ++ vxor $out0,$in0,$twk0 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in1,$x10,$inp ++ vxor $twk1,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in1,$in1,$in1,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out1,$in1,$twk1 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in2,$x20,$inp ++ andi. $taillen,$len,15 ++ vxor $twk2,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in2,$in2,$in2,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out2,$in2,$twk2 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in3,$x30,$inp ++ sub $len,$len,$taillen ++ vxor $twk3,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in3,$in3,$in3,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out3,$in3,$twk3 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in4,$x40,$inp ++ subi $len,$len,0x60 ++ vxor $twk4,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in4,$in4,$in4,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out4,$in4,$twk4 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in5,$x50,$inp ++ addi $inp,$inp,0x60 ++ vxor $twk5,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in5,$in5,$in5,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out5,$in5,$twk5 ++ vxor $tweak,$tweak,$tmp ++ ++ vxor v31,v31,$rndkey0 ++ mtctr $rounds ++ b Loop_xts_enc6x ++ ++.align 5 ++Loop_xts_enc6x: ++ vcipher $out0,$out0,v24 ++ vcipher $out1,$out1,v24 ++ vcipher $out2,$out2,v24 ++ vcipher $out3,$out3,v24 ++ vcipher $out4,$out4,v24 ++ vcipher $out5,$out5,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vcipher $out0,$out0,v25 ++ vcipher $out1,$out1,v25 ++ vcipher $out2,$out2,v25 ++ vcipher $out3,$out3,v25 ++ vcipher $out4,$out4,v25 ++ vcipher $out5,$out5,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Loop_xts_enc6x ++ ++ subic $len,$len,96 # $len-=96 ++ vxor $in0,$twk0,v31 # xor with last round key ++ vcipher $out0,$out0,v24 ++ vcipher $out1,$out1,v24 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk0,$tweak,$rndkey0 ++ vaddubm $tweak,$tweak,$tweak ++ vcipher $out2,$out2,v24 ++ vcipher $out3,$out3,v24 ++ vsldoi $tmp,$tmp,$tmp,15 ++ vcipher $out4,$out4,v24 ++ vcipher $out5,$out5,v24 ++ ++ subfe. r0,r0,r0 # borrow?-1:0 ++ vand $tmp,$tmp,$eighty7 ++ vcipher $out0,$out0,v25 ++ vcipher $out1,$out1,v25 ++ vxor $tweak,$tweak,$tmp ++ vcipher $out2,$out2,v25 ++ vcipher $out3,$out3,v25 ++ vxor $in1,$twk1,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk1,$tweak,$rndkey0 ++ vcipher $out4,$out4,v25 ++ vcipher $out5,$out5,v25 ++ ++ and r0,r0,$len ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vcipher $out0,$out0,v26 ++ vcipher $out1,$out1,v26 ++ vand $tmp,$tmp,$eighty7 ++ vcipher $out2,$out2,v26 ++ vcipher $out3,$out3,v26 ++ vxor $tweak,$tweak,$tmp ++ vcipher $out4,$out4,v26 ++ vcipher $out5,$out5,v26 ++ ++ add $inp,$inp,r0 # $inp is adjusted in such ++ # way that at exit from the ++ # loop inX-in5 are loaded ++ # with last "words" ++ vxor $in2,$twk2,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk2,$tweak,$rndkey0 ++ vaddubm $tweak,$tweak,$tweak ++ vcipher $out0,$out0,v27 ++ vcipher $out1,$out1,v27 ++ vsldoi $tmp,$tmp,$tmp,15 ++ vcipher $out2,$out2,v27 ++ vcipher $out3,$out3,v27 ++ vand $tmp,$tmp,$eighty7 ++ vcipher $out4,$out4,v27 ++ vcipher $out5,$out5,v27 ++ ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vxor $tweak,$tweak,$tmp ++ vcipher $out0,$out0,v28 ++ vcipher $out1,$out1,v28 ++ vxor $in3,$twk3,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk3,$tweak,$rndkey0 ++ vcipher $out2,$out2,v28 ++ vcipher $out3,$out3,v28 ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vcipher $out4,$out4,v28 ++ vcipher $out5,$out5,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ vand $tmp,$tmp,$eighty7 ++ ++ vcipher $out0,$out0,v29 ++ vcipher $out1,$out1,v29 ++ vxor $tweak,$tweak,$tmp ++ vcipher $out2,$out2,v29 ++ vcipher $out3,$out3,v29 ++ vxor $in4,$twk4,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk4,$tweak,$rndkey0 ++ vcipher $out4,$out4,v29 ++ vcipher $out5,$out5,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ ++ vcipher $out0,$out0,v30 ++ vcipher $out1,$out1,v30 ++ vand $tmp,$tmp,$eighty7 ++ vcipher $out2,$out2,v30 ++ vcipher $out3,$out3,v30 ++ vxor $tweak,$tweak,$tmp ++ vcipher $out4,$out4,v30 ++ vcipher $out5,$out5,v30 ++ vxor $in5,$twk5,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk5,$tweak,$rndkey0 ++ ++ vcipherlast $out0,$out0,$in0 ++ lvx_u $in0,$x00,$inp # load next input block ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vcipherlast $out1,$out1,$in1 ++ lvx_u $in1,$x10,$inp ++ vcipherlast $out2,$out2,$in2 ++ le?vperm $in0,$in0,$in0,$leperm ++ lvx_u $in2,$x20,$inp ++ vand $tmp,$tmp,$eighty7 ++ vcipherlast $out3,$out3,$in3 ++ le?vperm $in1,$in1,$in1,$leperm ++ lvx_u $in3,$x30,$inp ++ vcipherlast $out4,$out4,$in4 ++ le?vperm $in2,$in2,$in2,$leperm ++ lvx_u $in4,$x40,$inp ++ vxor $tweak,$tweak,$tmp ++ vcipherlast $tmp,$out5,$in5 # last block might be needed ++ # in stealing mode ++ le?vperm $in3,$in3,$in3,$leperm ++ lvx_u $in5,$x50,$inp ++ addi $inp,$inp,0x60 ++ le?vperm $in4,$in4,$in4,$leperm ++ le?vperm $in5,$in5,$in5,$leperm ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ vxor $out0,$in0,$twk0 ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ vxor $out1,$in1,$twk1 ++ le?vperm $out3,$out3,$out3,$leperm ++ stvx_u $out2,$x20,$out ++ vxor $out2,$in2,$twk2 ++ le?vperm $out4,$out4,$out4,$leperm ++ stvx_u $out3,$x30,$out ++ vxor $out3,$in3,$twk3 ++ le?vperm $out5,$tmp,$tmp,$leperm ++ stvx_u $out4,$x40,$out ++ vxor $out4,$in4,$twk4 ++ le?stvx_u $out5,$x50,$out ++ be?stvx_u $tmp, $x50,$out ++ vxor $out5,$in5,$twk5 ++ addi $out,$out,0x60 ++ ++ mtctr $rounds ++ beq Loop_xts_enc6x # did $len-=96 borrow? ++ ++ addic. $len,$len,0x60 ++ beq Lxts_enc6x_zero ++ cmpwi $len,0x20 ++ blt Lxts_enc6x_one ++ nop ++ beq Lxts_enc6x_two ++ cmpwi $len,0x40 ++ blt Lxts_enc6x_three ++ nop ++ beq Lxts_enc6x_four ++ ++Lxts_enc6x_five: ++ vxor $out0,$in1,$twk0 ++ vxor $out1,$in2,$twk1 ++ vxor $out2,$in3,$twk2 ++ vxor $out3,$in4,$twk3 ++ vxor $out4,$in5,$twk4 ++ ++ bl _aesp8_xts_enc5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk5 # unused tweak ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$leperm ++ stvx_u $out2,$x20,$out ++ vxor $tmp,$out4,$twk5 # last block prep for stealing ++ le?vperm $out4,$out4,$out4,$leperm ++ stvx_u $out3,$x30,$out ++ stvx_u $out4,$x40,$out ++ addi $out,$out,0x50 ++ bne Lxts_enc6x_steal ++ b Lxts_enc6x_done ++ ++.align 4 ++Lxts_enc6x_four: ++ vxor $out0,$in2,$twk0 ++ vxor $out1,$in3,$twk1 ++ vxor $out2,$in4,$twk2 ++ vxor $out3,$in5,$twk3 ++ vxor $out4,$out4,$out4 ++ ++ bl _aesp8_xts_enc5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk4 # unused tweak ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ vxor $tmp,$out3,$twk4 # last block prep for stealing ++ le?vperm $out3,$out3,$out3,$leperm ++ stvx_u $out2,$x20,$out ++ stvx_u $out3,$x30,$out ++ addi $out,$out,0x40 ++ bne Lxts_enc6x_steal ++ b Lxts_enc6x_done ++ ++.align 4 ++Lxts_enc6x_three: ++ vxor $out0,$in3,$twk0 ++ vxor $out1,$in4,$twk1 ++ vxor $out2,$in5,$twk2 ++ vxor $out3,$out3,$out3 ++ vxor $out4,$out4,$out4 ++ ++ bl _aesp8_xts_enc5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk3 # unused tweak ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ vxor $tmp,$out2,$twk3 # last block prep for stealing ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ stvx_u $out2,$x20,$out ++ addi $out,$out,0x30 ++ bne Lxts_enc6x_steal ++ b Lxts_enc6x_done ++ ++.align 4 ++Lxts_enc6x_two: ++ vxor $out0,$in4,$twk0 ++ vxor $out1,$in5,$twk1 ++ vxor $out2,$out2,$out2 ++ vxor $out3,$out3,$out3 ++ vxor $out4,$out4,$out4 ++ ++ bl _aesp8_xts_enc5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk2 # unused tweak ++ vxor $tmp,$out1,$twk2 # last block prep for stealing ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ stvx_u $out1,$x10,$out ++ addi $out,$out,0x20 ++ bne Lxts_enc6x_steal ++ b Lxts_enc6x_done ++ ++.align 4 ++Lxts_enc6x_one: ++ vxor $out0,$in5,$twk0 ++ nop ++Loop_xts_enc1x: ++ vcipher $out0,$out0,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vcipher $out0,$out0,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Loop_xts_enc1x ++ ++ add $inp,$inp,$taillen ++ cmpwi $taillen,0 ++ vcipher $out0,$out0,v24 ++ ++ subi $inp,$inp,16 ++ vcipher $out0,$out0,v25 ++ ++ lvsr $inpperm,0,$taillen ++ vcipher $out0,$out0,v26 ++ ++ lvx_u $in0,0,$inp ++ vcipher $out0,$out0,v27 ++ ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vcipher $out0,$out0,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ ++ vcipher $out0,$out0,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ vxor $twk0,$twk0,v31 ++ ++ le?vperm $in0,$in0,$in0,$leperm ++ vcipher $out0,$out0,v30 ++ ++ vperm $in0,$in0,$in0,$inpperm ++ vcipherlast $out0,$out0,$twk0 ++ ++ vmr $twk0,$twk1 # unused tweak ++ vxor $tmp,$out0,$twk1 # last block prep for stealing ++ le?vperm $out0,$out0,$out0,$leperm ++ stvx_u $out0,$x00,$out # store output ++ addi $out,$out,0x10 ++ bne Lxts_enc6x_steal ++ b Lxts_enc6x_done ++ ++.align 4 ++Lxts_enc6x_zero: ++ cmpwi $taillen,0 ++ beq Lxts_enc6x_done ++ ++ add $inp,$inp,$taillen ++ subi $inp,$inp,16 ++ lvx_u $in0,0,$inp ++ lvsr $inpperm,0,$taillen # $in5 is no more ++ le?vperm $in0,$in0,$in0,$leperm ++ vperm $in0,$in0,$in0,$inpperm ++ vxor $tmp,$tmp,$twk0 ++Lxts_enc6x_steal: ++ vxor $in0,$in0,$twk0 ++ vxor $out0,$out0,$out0 ++ vspltisb $out1,-1 ++ vperm $out0,$out0,$out1,$inpperm ++ vsel $out0,$in0,$tmp,$out0 # $tmp is last block, remember? ++ ++ subi r30,$out,17 ++ subi $out,$out,16 ++ mtctr $taillen ++Loop_xts_enc6x_steal: ++ lbzu r0,1(r30) ++ stb r0,16(r30) ++ bdnz Loop_xts_enc6x_steal ++ ++ li $taillen,0 ++ mtctr $rounds ++ b Loop_xts_enc1x # one more time... ++ ++.align 4 ++Lxts_enc6x_done: ++ ${UCMP}i $ivp,0 ++ beq Lxts_enc6x_ret ++ ++ vxor $tweak,$twk0,$rndkey0 ++ le?vperm $tweak,$tweak,$tweak,$leperm ++ stvx_u $tweak,0,$ivp ++ ++Lxts_enc6x_ret: ++ mtlr r11 ++ li r10,`$FRAME+15` ++ li r11,`$FRAME+31` ++ stvx $seven,r10,$sp # wipe copies of round keys ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ stvx $seven,r10,$sp ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ stvx $seven,r10,$sp ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ stvx $seven,r10,$sp ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ ++ mtspr 256,$vrsave ++ lvx v20,r10,$sp # ABI says so ++ addi r10,r10,32 ++ lvx v21,r11,$sp ++ addi r11,r11,32 ++ lvx v22,r10,$sp ++ addi r10,r10,32 ++ lvx v23,r11,$sp ++ addi r11,r11,32 ++ lvx v24,r10,$sp ++ addi r10,r10,32 ++ lvx v25,r11,$sp ++ addi r11,r11,32 ++ lvx v26,r10,$sp ++ addi r10,r10,32 ++ lvx v27,r11,$sp ++ addi r11,r11,32 ++ lvx v28,r10,$sp ++ addi r10,r10,32 ++ lvx v29,r11,$sp ++ addi r11,r11,32 ++ lvx v30,r10,$sp ++ lvx v31,r11,$sp ++ $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) ++ $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) ++ $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) ++ $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) ++ $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) ++ $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) ++ addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` ++ blr ++ .long 0 ++ .byte 0,12,0x04,1,0x80,6,6,0 ++ .long 0 ++ ++.align 5 ++_aesp8_xts_enc5x: ++ vcipher $out0,$out0,v24 ++ vcipher $out1,$out1,v24 ++ vcipher $out2,$out2,v24 ++ vcipher $out3,$out3,v24 ++ vcipher $out4,$out4,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vcipher $out0,$out0,v25 ++ vcipher $out1,$out1,v25 ++ vcipher $out2,$out2,v25 ++ vcipher $out3,$out3,v25 ++ vcipher $out4,$out4,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz _aesp8_xts_enc5x ++ ++ add $inp,$inp,$taillen ++ cmpwi $taillen,0 ++ vcipher $out0,$out0,v24 ++ vcipher $out1,$out1,v24 ++ vcipher $out2,$out2,v24 ++ vcipher $out3,$out3,v24 ++ vcipher $out4,$out4,v24 ++ ++ subi $inp,$inp,16 ++ vcipher $out0,$out0,v25 ++ vcipher $out1,$out1,v25 ++ vcipher $out2,$out2,v25 ++ vcipher $out3,$out3,v25 ++ vcipher $out4,$out4,v25 ++ vxor $twk0,$twk0,v31 ++ ++ vcipher $out0,$out0,v26 ++ lvsr $inpperm,r0,$taillen # $in5 is no more ++ vcipher $out1,$out1,v26 ++ vcipher $out2,$out2,v26 ++ vcipher $out3,$out3,v26 ++ vcipher $out4,$out4,v26 ++ vxor $in1,$twk1,v31 ++ ++ vcipher $out0,$out0,v27 ++ lvx_u $in0,0,$inp ++ vcipher $out1,$out1,v27 ++ vcipher $out2,$out2,v27 ++ vcipher $out3,$out3,v27 ++ vcipher $out4,$out4,v27 ++ vxor $in2,$twk2,v31 ++ ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vcipher $out0,$out0,v28 ++ vcipher $out1,$out1,v28 ++ vcipher $out2,$out2,v28 ++ vcipher $out3,$out3,v28 ++ vcipher $out4,$out4,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ vxor $in3,$twk3,v31 ++ ++ vcipher $out0,$out0,v29 ++ le?vperm $in0,$in0,$in0,$leperm ++ vcipher $out1,$out1,v29 ++ vcipher $out2,$out2,v29 ++ vcipher $out3,$out3,v29 ++ vcipher $out4,$out4,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ vxor $in4,$twk4,v31 ++ ++ vcipher $out0,$out0,v30 ++ vperm $in0,$in0,$in0,$inpperm ++ vcipher $out1,$out1,v30 ++ vcipher $out2,$out2,v30 ++ vcipher $out3,$out3,v30 ++ vcipher $out4,$out4,v30 ++ ++ vcipherlast $out0,$out0,$twk0 ++ vcipherlast $out1,$out1,$in1 ++ vcipherlast $out2,$out2,$in2 ++ vcipherlast $out3,$out3,$in3 ++ vcipherlast $out4,$out4,$in4 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++.align 5 ++_aesp8_xts_decrypt6x: ++ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) ++ mflr r11 ++ li r7,`$FRAME+8*16+15` ++ li r3,`$FRAME+8*16+31` ++ $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp) ++ stvx v20,r7,$sp # ABI says so ++ addi r7,r7,32 ++ stvx v21,r3,$sp ++ addi r3,r3,32 ++ stvx v22,r7,$sp ++ addi r7,r7,32 ++ stvx v23,r3,$sp ++ addi r3,r3,32 ++ stvx v24,r7,$sp ++ addi r7,r7,32 ++ stvx v25,r3,$sp ++ addi r3,r3,32 ++ stvx v26,r7,$sp ++ addi r7,r7,32 ++ stvx v27,r3,$sp ++ addi r3,r3,32 ++ stvx v28,r7,$sp ++ addi r7,r7,32 ++ stvx v29,r3,$sp ++ addi r3,r3,32 ++ stvx v30,r7,$sp ++ stvx v31,r3,$sp ++ li r0,-1 ++ stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave ++ li $x10,0x10 ++ $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp) ++ li $x20,0x20 ++ $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp) ++ li $x30,0x30 ++ $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp) ++ li $x40,0x40 ++ $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp) ++ li $x50,0x50 ++ $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp) ++ li $x60,0x60 ++ $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp) ++ li $x70,0x70 ++ mtspr 256,r0 ++ ++ subi $rounds,$rounds,3 # -4 in total ++ ++ lvx $rndkey0,$x00,$key1 # load key schedule ++ lvx v30,$x10,$key1 ++ addi $key1,$key1,0x20 ++ lvx v31,$x00,$key1 ++ ?vperm $rndkey0,$rndkey0,v30,$keyperm ++ addi $key_,$sp,$FRAME+15 ++ mtctr $rounds ++ ++Load_xts_dec_key: ++ ?vperm v24,v30,v31,$keyperm ++ lvx v30,$x10,$key1 ++ addi $key1,$key1,0x20 ++ stvx v24,$x00,$key_ # off-load round[1] ++ ?vperm v25,v31,v30,$keyperm ++ lvx v31,$x00,$key1 ++ stvx v25,$x10,$key_ # off-load round[2] ++ addi $key_,$key_,0x20 ++ bdnz Load_xts_dec_key ++ ++ lvx v26,$x10,$key1 ++ ?vperm v24,v30,v31,$keyperm ++ lvx v27,$x20,$key1 ++ stvx v24,$x00,$key_ # off-load round[3] ++ ?vperm v25,v31,v26,$keyperm ++ lvx v28,$x30,$key1 ++ stvx v25,$x10,$key_ # off-load round[4] ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ ?vperm v26,v26,v27,$keyperm ++ lvx v29,$x40,$key1 ++ ?vperm v27,v27,v28,$keyperm ++ lvx v30,$x50,$key1 ++ ?vperm v28,v28,v29,$keyperm ++ lvx v31,$x60,$key1 ++ ?vperm v29,v29,v30,$keyperm ++ lvx $twk5,$x70,$key1 # borrow $twk5 ++ ?vperm v30,v30,v31,$keyperm ++ lvx v24,$x00,$key_ # pre-load round[1] ++ ?vperm v31,v31,$twk5,$keyperm ++ lvx v25,$x10,$key_ # pre-load round[2] ++ ++ vperm $in0,$inout,$inptail,$inpperm ++ subi $inp,$inp,31 # undo "caller" ++ vxor $twk0,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vand $tmp,$tmp,$eighty7 ++ vxor $out0,$in0,$twk0 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in1,$x10,$inp ++ vxor $twk1,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in1,$in1,$in1,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out1,$in1,$twk1 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in2,$x20,$inp ++ andi. $taillen,$len,15 ++ vxor $twk2,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in2,$in2,$in2,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out2,$in2,$twk2 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in3,$x30,$inp ++ sub $len,$len,$taillen ++ vxor $twk3,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in3,$in3,$in3,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out3,$in3,$twk3 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in4,$x40,$inp ++ subi $len,$len,0x60 ++ vxor $twk4,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in4,$in4,$in4,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out4,$in4,$twk4 ++ vxor $tweak,$tweak,$tmp ++ ++ lvx_u $in5,$x50,$inp ++ addi $inp,$inp,0x60 ++ vxor $twk5,$tweak,$rndkey0 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ le?vperm $in5,$in5,$in5,$leperm ++ vand $tmp,$tmp,$eighty7 ++ vxor $out5,$in5,$twk5 ++ vxor $tweak,$tweak,$tmp ++ ++ vxor v31,v31,$rndkey0 ++ mtctr $rounds ++ b Loop_xts_dec6x ++ ++.align 5 ++Loop_xts_dec6x: ++ vncipher $out0,$out0,v24 ++ vncipher $out1,$out1,v24 ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vncipher $out4,$out4,v24 ++ vncipher $out5,$out5,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vncipher $out0,$out0,v25 ++ vncipher $out1,$out1,v25 ++ vncipher $out2,$out2,v25 ++ vncipher $out3,$out3,v25 ++ vncipher $out4,$out4,v25 ++ vncipher $out5,$out5,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Loop_xts_dec6x ++ ++ subic $len,$len,96 # $len-=96 ++ vxor $in0,$twk0,v31 # xor with last round key ++ vncipher $out0,$out0,v24 ++ vncipher $out1,$out1,v24 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk0,$tweak,$rndkey0 ++ vaddubm $tweak,$tweak,$tweak ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vsldoi $tmp,$tmp,$tmp,15 ++ vncipher $out4,$out4,v24 ++ vncipher $out5,$out5,v24 ++ ++ subfe. r0,r0,r0 # borrow?-1:0 ++ vand $tmp,$tmp,$eighty7 ++ vncipher $out0,$out0,v25 ++ vncipher $out1,$out1,v25 ++ vxor $tweak,$tweak,$tmp ++ vncipher $out2,$out2,v25 ++ vncipher $out3,$out3,v25 ++ vxor $in1,$twk1,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk1,$tweak,$rndkey0 ++ vncipher $out4,$out4,v25 ++ vncipher $out5,$out5,v25 ++ ++ and r0,r0,$len ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vncipher $out0,$out0,v26 ++ vncipher $out1,$out1,v26 ++ vand $tmp,$tmp,$eighty7 ++ vncipher $out2,$out2,v26 ++ vncipher $out3,$out3,v26 ++ vxor $tweak,$tweak,$tmp ++ vncipher $out4,$out4,v26 ++ vncipher $out5,$out5,v26 ++ ++ add $inp,$inp,r0 # $inp is adjusted in such ++ # way that at exit from the ++ # loop inX-in5 are loaded ++ # with last "words" ++ vxor $in2,$twk2,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk2,$tweak,$rndkey0 ++ vaddubm $tweak,$tweak,$tweak ++ vncipher $out0,$out0,v27 ++ vncipher $out1,$out1,v27 ++ vsldoi $tmp,$tmp,$tmp,15 ++ vncipher $out2,$out2,v27 ++ vncipher $out3,$out3,v27 ++ vand $tmp,$tmp,$eighty7 ++ vncipher $out4,$out4,v27 ++ vncipher $out5,$out5,v27 ++ ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vxor $tweak,$tweak,$tmp ++ vncipher $out0,$out0,v28 ++ vncipher $out1,$out1,v28 ++ vxor $in3,$twk3,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk3,$tweak,$rndkey0 ++ vncipher $out2,$out2,v28 ++ vncipher $out3,$out3,v28 ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vncipher $out4,$out4,v28 ++ vncipher $out5,$out5,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ vand $tmp,$tmp,$eighty7 ++ ++ vncipher $out0,$out0,v29 ++ vncipher $out1,$out1,v29 ++ vxor $tweak,$tweak,$tmp ++ vncipher $out2,$out2,v29 ++ vncipher $out3,$out3,v29 ++ vxor $in4,$twk4,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk4,$tweak,$rndkey0 ++ vncipher $out4,$out4,v29 ++ vncipher $out5,$out5,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ ++ vncipher $out0,$out0,v30 ++ vncipher $out1,$out1,v30 ++ vand $tmp,$tmp,$eighty7 ++ vncipher $out2,$out2,v30 ++ vncipher $out3,$out3,v30 ++ vxor $tweak,$tweak,$tmp ++ vncipher $out4,$out4,v30 ++ vncipher $out5,$out5,v30 ++ vxor $in5,$twk5,v31 ++ vsrab $tmp,$tweak,$seven # next tweak value ++ vxor $twk5,$tweak,$rndkey0 ++ ++ vncipherlast $out0,$out0,$in0 ++ lvx_u $in0,$x00,$inp # load next input block ++ vaddubm $tweak,$tweak,$tweak ++ vsldoi $tmp,$tmp,$tmp,15 ++ vncipherlast $out1,$out1,$in1 ++ lvx_u $in1,$x10,$inp ++ vncipherlast $out2,$out2,$in2 ++ le?vperm $in0,$in0,$in0,$leperm ++ lvx_u $in2,$x20,$inp ++ vand $tmp,$tmp,$eighty7 ++ vncipherlast $out3,$out3,$in3 ++ le?vperm $in1,$in1,$in1,$leperm ++ lvx_u $in3,$x30,$inp ++ vncipherlast $out4,$out4,$in4 ++ le?vperm $in2,$in2,$in2,$leperm ++ lvx_u $in4,$x40,$inp ++ vxor $tweak,$tweak,$tmp ++ vncipherlast $out5,$out5,$in5 ++ le?vperm $in3,$in3,$in3,$leperm ++ lvx_u $in5,$x50,$inp ++ addi $inp,$inp,0x60 ++ le?vperm $in4,$in4,$in4,$leperm ++ le?vperm $in5,$in5,$in5,$leperm ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ vxor $out0,$in0,$twk0 ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ vxor $out1,$in1,$twk1 ++ le?vperm $out3,$out3,$out3,$leperm ++ stvx_u $out2,$x20,$out ++ vxor $out2,$in2,$twk2 ++ le?vperm $out4,$out4,$out4,$leperm ++ stvx_u $out3,$x30,$out ++ vxor $out3,$in3,$twk3 ++ le?vperm $out5,$out5,$out5,$leperm ++ stvx_u $out4,$x40,$out ++ vxor $out4,$in4,$twk4 ++ stvx_u $out5,$x50,$out ++ vxor $out5,$in5,$twk5 ++ addi $out,$out,0x60 ++ ++ mtctr $rounds ++ beq Loop_xts_dec6x # did $len-=96 borrow? ++ ++ addic. $len,$len,0x60 ++ beq Lxts_dec6x_zero ++ cmpwi $len,0x20 ++ blt Lxts_dec6x_one ++ nop ++ beq Lxts_dec6x_two ++ cmpwi $len,0x40 ++ blt Lxts_dec6x_three ++ nop ++ beq Lxts_dec6x_four ++ ++Lxts_dec6x_five: ++ vxor $out0,$in1,$twk0 ++ vxor $out1,$in2,$twk1 ++ vxor $out2,$in3,$twk2 ++ vxor $out3,$in4,$twk3 ++ vxor $out4,$in5,$twk4 ++ ++ bl _aesp8_xts_dec5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk5 # unused tweak ++ vxor $twk1,$tweak,$rndkey0 ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ vxor $out0,$in0,$twk1 ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$leperm ++ stvx_u $out2,$x20,$out ++ le?vperm $out4,$out4,$out4,$leperm ++ stvx_u $out3,$x30,$out ++ stvx_u $out4,$x40,$out ++ addi $out,$out,0x50 ++ bne Lxts_dec6x_steal ++ b Lxts_dec6x_done ++ ++.align 4 ++Lxts_dec6x_four: ++ vxor $out0,$in2,$twk0 ++ vxor $out1,$in3,$twk1 ++ vxor $out2,$in4,$twk2 ++ vxor $out3,$in5,$twk3 ++ vxor $out4,$out4,$out4 ++ ++ bl _aesp8_xts_dec5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk4 # unused tweak ++ vmr $twk1,$twk5 ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ vxor $out0,$in0,$twk5 ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$leperm ++ stvx_u $out2,$x20,$out ++ stvx_u $out3,$x30,$out ++ addi $out,$out,0x40 ++ bne Lxts_dec6x_steal ++ b Lxts_dec6x_done ++ ++.align 4 ++Lxts_dec6x_three: ++ vxor $out0,$in3,$twk0 ++ vxor $out1,$in4,$twk1 ++ vxor $out2,$in5,$twk2 ++ vxor $out3,$out3,$out3 ++ vxor $out4,$out4,$out4 ++ ++ bl _aesp8_xts_dec5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk3 # unused tweak ++ vmr $twk1,$twk4 ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ vxor $out0,$in0,$twk4 ++ le?vperm $out2,$out2,$out2,$leperm ++ stvx_u $out1,$x10,$out ++ stvx_u $out2,$x20,$out ++ addi $out,$out,0x30 ++ bne Lxts_dec6x_steal ++ b Lxts_dec6x_done ++ ++.align 4 ++Lxts_dec6x_two: ++ vxor $out0,$in4,$twk0 ++ vxor $out1,$in5,$twk1 ++ vxor $out2,$out2,$out2 ++ vxor $out3,$out3,$out3 ++ vxor $out4,$out4,$out4 ++ ++ bl _aesp8_xts_dec5x ++ ++ le?vperm $out0,$out0,$out0,$leperm ++ vmr $twk0,$twk2 # unused tweak ++ vmr $twk1,$twk3 ++ le?vperm $out1,$out1,$out1,$leperm ++ stvx_u $out0,$x00,$out # store output ++ vxor $out0,$in0,$twk3 ++ stvx_u $out1,$x10,$out ++ addi $out,$out,0x20 ++ bne Lxts_dec6x_steal ++ b Lxts_dec6x_done ++ ++.align 4 ++Lxts_dec6x_one: ++ vxor $out0,$in5,$twk0 ++ nop ++Loop_xts_dec1x: ++ vncipher $out0,$out0,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vncipher $out0,$out0,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Loop_xts_dec1x ++ ++ subi r0,$taillen,1 ++ vncipher $out0,$out0,v24 ++ ++ andi. r0,r0,16 ++ cmpwi $taillen,0 ++ vncipher $out0,$out0,v25 ++ ++ sub $inp,$inp,r0 ++ vncipher $out0,$out0,v26 ++ ++ lvx_u $in0,0,$inp ++ vncipher $out0,$out0,v27 ++ ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vncipher $out0,$out0,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ ++ vncipher $out0,$out0,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ vxor $twk0,$twk0,v31 ++ ++ le?vperm $in0,$in0,$in0,$leperm ++ vncipher $out0,$out0,v30 ++ ++ mtctr $rounds ++ vncipherlast $out0,$out0,$twk0 ++ ++ vmr $twk0,$twk1 # unused tweak ++ vmr $twk1,$twk2 ++ le?vperm $out0,$out0,$out0,$leperm ++ stvx_u $out0,$x00,$out # store output ++ addi $out,$out,0x10 ++ vxor $out0,$in0,$twk2 ++ bne Lxts_dec6x_steal ++ b Lxts_dec6x_done ++ ++.align 4 ++Lxts_dec6x_zero: ++ cmpwi $taillen,0 ++ beq Lxts_dec6x_done ++ ++ lvx_u $in0,0,$inp ++ le?vperm $in0,$in0,$in0,$leperm ++ vxor $out0,$in0,$twk1 ++Lxts_dec6x_steal: ++ vncipher $out0,$out0,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vncipher $out0,$out0,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Lxts_dec6x_steal ++ ++ add $inp,$inp,$taillen ++ vncipher $out0,$out0,v24 ++ ++ cmpwi $taillen,0 ++ vncipher $out0,$out0,v25 ++ ++ lvx_u $in0,0,$inp ++ vncipher $out0,$out0,v26 ++ ++ lvsr $inpperm,0,$taillen # $in5 is no more ++ vncipher $out0,$out0,v27 ++ ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vncipher $out0,$out0,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ ++ vncipher $out0,$out0,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ vxor $twk1,$twk1,v31 ++ ++ le?vperm $in0,$in0,$in0,$leperm ++ vncipher $out0,$out0,v30 ++ ++ vperm $in0,$in0,$in0,$inpperm ++ vncipherlast $tmp,$out0,$twk1 ++ ++ le?vperm $out0,$tmp,$tmp,$leperm ++ le?stvx_u $out0,0,$out ++ be?stvx_u $tmp,0,$out ++ ++ vxor $out0,$out0,$out0 ++ vspltisb $out1,-1 ++ vperm $out0,$out0,$out1,$inpperm ++ vsel $out0,$in0,$tmp,$out0 ++ vxor $out0,$out0,$twk0 ++ ++ subi r30,$out,1 ++ mtctr $taillen ++Loop_xts_dec6x_steal: ++ lbzu r0,1(r30) ++ stb r0,16(r30) ++ bdnz Loop_xts_dec6x_steal ++ ++ li $taillen,0 ++ mtctr $rounds ++ b Loop_xts_dec1x # one more time... ++ ++.align 4 ++Lxts_dec6x_done: ++ ${UCMP}i $ivp,0 ++ beq Lxts_dec6x_ret ++ ++ vxor $tweak,$twk0,$rndkey0 ++ le?vperm $tweak,$tweak,$tweak,$leperm ++ stvx_u $tweak,0,$ivp ++ ++Lxts_dec6x_ret: ++ mtlr r11 ++ li r10,`$FRAME+15` ++ li r11,`$FRAME+31` ++ stvx $seven,r10,$sp # wipe copies of round keys ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ stvx $seven,r10,$sp ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ stvx $seven,r10,$sp ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ stvx $seven,r10,$sp ++ addi r10,r10,32 ++ stvx $seven,r11,$sp ++ addi r11,r11,32 ++ ++ mtspr 256,$vrsave ++ lvx v20,r10,$sp # ABI says so ++ addi r10,r10,32 ++ lvx v21,r11,$sp ++ addi r11,r11,32 ++ lvx v22,r10,$sp ++ addi r10,r10,32 ++ lvx v23,r11,$sp ++ addi r11,r11,32 ++ lvx v24,r10,$sp ++ addi r10,r10,32 ++ lvx v25,r11,$sp ++ addi r11,r11,32 ++ lvx v26,r10,$sp ++ addi r10,r10,32 ++ lvx v27,r11,$sp ++ addi r11,r11,32 ++ lvx v28,r10,$sp ++ addi r10,r10,32 ++ lvx v29,r11,$sp ++ addi r11,r11,32 ++ lvx v30,r10,$sp ++ lvx v31,r11,$sp ++ $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp) ++ $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp) ++ $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp) ++ $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp) ++ $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp) ++ $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp) ++ addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T` ++ blr ++ .long 0 ++ .byte 0,12,0x04,1,0x80,6,6,0 ++ .long 0 ++ ++.align 5 ++_aesp8_xts_dec5x: ++ vncipher $out0,$out0,v24 ++ vncipher $out1,$out1,v24 ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vncipher $out4,$out4,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vncipher $out0,$out0,v25 ++ vncipher $out1,$out1,v25 ++ vncipher $out2,$out2,v25 ++ vncipher $out3,$out3,v25 ++ vncipher $out4,$out4,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz _aesp8_xts_dec5x ++ ++ subi r0,$taillen,1 ++ vncipher $out0,$out0,v24 ++ vncipher $out1,$out1,v24 ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vncipher $out4,$out4,v24 ++ ++ andi. r0,r0,16 ++ cmpwi $taillen,0 ++ vncipher $out0,$out0,v25 ++ vncipher $out1,$out1,v25 ++ vncipher $out2,$out2,v25 ++ vncipher $out3,$out3,v25 ++ vncipher $out4,$out4,v25 ++ vxor $twk0,$twk0,v31 ++ ++ sub $inp,$inp,r0 ++ vncipher $out0,$out0,v26 ++ vncipher $out1,$out1,v26 ++ vncipher $out2,$out2,v26 ++ vncipher $out3,$out3,v26 ++ vncipher $out4,$out4,v26 ++ vxor $in1,$twk1,v31 ++ ++ vncipher $out0,$out0,v27 ++ lvx_u $in0,0,$inp ++ vncipher $out1,$out1,v27 ++ vncipher $out2,$out2,v27 ++ vncipher $out3,$out3,v27 ++ vncipher $out4,$out4,v27 ++ vxor $in2,$twk2,v31 ++ ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vncipher $out0,$out0,v28 ++ vncipher $out1,$out1,v28 ++ vncipher $out2,$out2,v28 ++ vncipher $out3,$out3,v28 ++ vncipher $out4,$out4,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ vxor $in3,$twk3,v31 ++ ++ vncipher $out0,$out0,v29 ++ le?vperm $in0,$in0,$in0,$leperm ++ vncipher $out1,$out1,v29 ++ vncipher $out2,$out2,v29 ++ vncipher $out3,$out3,v29 ++ vncipher $out4,$out4,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ vxor $in4,$twk4,v31 ++ ++ vncipher $out0,$out0,v30 ++ vncipher $out1,$out1,v30 ++ vncipher $out2,$out2,v30 ++ vncipher $out3,$out3,v30 ++ vncipher $out4,$out4,v30 ++ ++ vncipherlast $out0,$out0,$twk0 ++ vncipherlast $out1,$out1,$in1 ++ vncipherlast $out2,$out2,$in2 ++ vncipherlast $out3,$out3,$in3 ++ vncipherlast $out4,$out4,$in4 ++ mtctr $rounds ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++___ ++}} }}} ++ + my $consts=1; + foreach(split("\n",$code)) { + s/\`([^\`]*)\`/eval($1)/geo; +diff -up openssl-1.0.2k/crypto/evp/e_aes.c.ppc-update openssl-1.0.2k/crypto/evp/e_aes.c +--- openssl-1.0.2k/crypto/evp/e_aes.c.ppc-update 2017-03-09 17:59:26.303232439 +0100 ++++ openssl-1.0.2k/crypto/evp/e_aes.c 2017-03-09 17:59:26.314232696 +0100 +@@ -172,6 +172,8 @@ void AES_xts_decrypt(const unsigned char + # define HWAES_decrypt aes_p8_decrypt + # define HWAES_cbc_encrypt aes_p8_cbc_encrypt + # define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks ++# define HWAES_xts_encrypt aes_p8_xts_encrypt ++# define HWAES_xts_decrypt aes_p8_xts_decrypt + # endif + + # if defined(AES_ASM) && !defined(I386_ONLY) && ( \ +@@ -911,6 +913,12 @@ void HWAES_cbc_encrypt(const unsigned ch + void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + const unsigned char ivec[16]); ++void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out, ++ size_t len, const AES_KEY *key1, ++ const AES_KEY *key2, const unsigned char iv[16]); ++void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out, ++ size_t len, const AES_KEY *key1, ++ const AES_KEY *key2, const unsigned char iv[16]); + # endif + + # define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ +@@ -1664,10 +1672,16 @@ static int aes_xts_init_key(EVP_CIPHER_C + HWAES_set_encrypt_key(key, ctx->key_len * 4, + &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) HWAES_encrypt; ++# ifdef HWAES_xts_encrypt ++ xctx->stream = HWAES_xts_encrypt; ++# endif + } else { + HWAES_set_decrypt_key(key, ctx->key_len * 4, + &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) HWAES_decrypt; ++# ifdef HWAES_xts_decrypt ++ xctx->stream = HWAES_xts_decrypt; ++#endif + } + + HWAES_set_encrypt_key(key + ctx->key_len / 2, diff --git a/openssl-1.0.2k-req-x509.patch b/openssl-1.0.2k-req-x509.patch new file mode 100644 index 0000000..0be9167 --- /dev/null +++ b/openssl-1.0.2k-req-x509.patch @@ -0,0 +1,30 @@ +diff -up openssl-1.0.2k/apps/req.c.req-x509 openssl-1.0.2k/apps/req.c +--- openssl-1.0.2k/apps/req.c.req-x509 2017-03-09 17:59:26.269231647 +0100 ++++ openssl-1.0.2k/apps/req.c 2017-05-17 13:23:31.236556216 +0200 +@@ -331,7 +331,6 @@ int MAIN(int argc, char **argv) + else if (strcmp(*argv, "-text") == 0) + text = 1; + else if (strcmp(*argv, "-x509") == 0) { +- newreq = 1; + x509 = 1; + } else if (strcmp(*argv, "-asn1-kludge") == 0) + kludge = 1; +@@ -447,6 +446,9 @@ int MAIN(int argc, char **argv) + goto end; + } + ++ if (x509 && infile == NULL) ++ newreq = 1; ++ + ERR_load_crypto_strings(); + if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { + BIO_printf(bio_err, "Error getting passwords\n"); +@@ -753,7 +755,7 @@ int MAIN(int argc, char **argv) + } + } + +- if (newreq) { ++ if (newreq || x509) { + if (pkey == NULL) { + BIO_printf(bio_err, "you need to specify a private key\n"); + goto end; diff --git a/openssl-1.0.2k-s390x-update.patch b/openssl-1.0.2k-s390x-update.patch new file mode 100644 index 0000000..8712de5 --- /dev/null +++ b/openssl-1.0.2k-s390x-update.patch @@ -0,0 +1,1368 @@ +diff -up openssl-1.0.2k/crypto/aes/asm/aes-s390x.pl.s390x-update openssl-1.0.2k/crypto/aes/asm/aes-s390x.pl +--- openssl-1.0.2k/crypto/aes/asm/aes-s390x.pl.s390x-update 2018-06-18 12:20:47.197994636 +0200 ++++ openssl-1.0.2k/crypto/aes/asm/aes-s390x.pl 2018-06-18 13:27:37.109817203 +0200 +@@ -122,6 +122,8 @@ sub _data_word() + } + + $code=<<___; ++#include "s390x_arch.h" ++ + .text + + .type AES_Te,\@object +@@ -814,13 +816,10 @@ $code.=<<___ if (!$softonly); + ar %r5,%r0 + + larl %r1,OPENSSL_s390xcap_P +- lg %r0,0(%r1) +- tmhl %r0,0x4000 # check for message-security assist +- jz .Lekey_internal +- + llihh %r0,0x8000 + srlg %r0,%r0,0(%r5) +- ng %r0,48(%r1) # check kmc capability vector ++ ng %r0,S390X_KM(%r1) # check availability of both km... ++ ng %r0,S390X_KMC(%r1) # ...and kmc support for given key length + jz .Lekey_internal + + lmg %r0,%r1,0($inp) # just copy 128 bits... +@@ -1443,7 +1442,7 @@ $code.=<<___ if (0); ######### kmctr cod + larl %r1,OPENSSL_s390xcap_P + llihh %r0,0x8000 # check if kmctr supports the function code + srlg %r0,%r0,0($s0) +- ng %r0,64(%r1) # check kmctr capability vector ++ ng %r0,S390X_KMCTR(%r1) # check kmctr capability vector + lgr %r0,$s0 + lgr %r1,$s1 + jz .Lctr32_km_loop +@@ -1593,7 +1592,7 @@ $code.=<<___ if(1); + larl %r1,OPENSSL_s390xcap_P + llihh %r0,0x8000 + srlg %r0,%r0,32($s1) # check for 32+function code +- ng %r0,32(%r1) # check km capability vector ++ ng %r0,S390X_KM(%r1) # check km capability vector + lgr %r0,$s0 # restore the function code + la %r1,0($key1) # restore $key1 + jz .Lxts_km_vanilla +@@ -2220,7 +2219,6 @@ ___ + } + $code.=<<___; + .string "AES for s390x, CRYPTOGAMS by " +-.comm OPENSSL_s390xcap_P,80,8 + ___ + + $code =~ s/\`([^\`]*)\`/eval $1/gem; +diff -up openssl-1.0.2k/crypto/aes/Makefile.s390x-update openssl-1.0.2k/crypto/aes/Makefile +--- openssl-1.0.2k/crypto/aes/Makefile.s390x-update 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/aes/Makefile 2018-06-18 13:27:37.108817179 +0200 +@@ -92,6 +92,8 @@ aesv8-armx.S: asm/aesv8-armx.pl + $(PERL) asm/aesv8-armx.pl $(PERLASM_SCHEME) $@ + aesv8-armx.o: aesv8-armx.S + ++aes-s390x.o: aes-s390x.S ++ + # GNU make "catch all" + aes-%.S: asm/aes-%.pl; $(PERL) $< $(PERLASM_SCHEME) > $@ + aes-armv4.o: aes-armv4.S +diff -up openssl-1.0.2k/crypto/evp/e_aes.c.s390x-update openssl-1.0.2k/crypto/evp/e_aes.c +--- openssl-1.0.2k/crypto/evp/e_aes.c.s390x-update 2018-06-18 12:20:47.104992361 +0200 ++++ openssl-1.0.2k/crypto/evp/e_aes.c 2018-06-18 13:28:07.033543735 +0200 +@@ -854,6 +854,723 @@ static const EVP_CIPHER aes_##keylen##_# + const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ + { return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; } + ++#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__) ++/* ++ * IBM S390X support ++ */ ++# include "s390x_arch.h" ++ ++typedef struct { ++ union { ++ double align; ++ /*- ++ * KMA-GCM-AES parameter block ++ * (see z/Architecture Principles of Operation SA22-7832-11) ++ */ ++ struct { ++ unsigned char reserved[12]; ++ union { ++ unsigned int w; ++ unsigned char b[4]; ++ } cv; ++ union { ++ unsigned long long g[2]; ++ unsigned char b[16]; ++ } t; ++ unsigned char h[16]; ++ unsigned long long taadl; ++ unsigned long long tpcl; ++ union { ++ unsigned long long g[2]; ++ unsigned int w[4]; ++ } j0; ++ unsigned char k[32]; ++ } param; ++ } kma; ++ unsigned int fc; ++ int key_set; ++ ++ unsigned char *iv; ++ int ivlen; ++ int iv_set; ++ int iv_gen; ++ ++ int taglen; ++ ++ unsigned char ares[16]; ++ unsigned char mres[16]; ++ unsigned char kres[16]; ++ int areslen; ++ int mreslen; ++ int kreslen; ++ ++ int tls_aad_len; ++} S390X_AES_GCM_CTX; ++ ++# define S390X_aes_128_CAPABLE ((OPENSSL_s390xcap_P.km[0] & \ ++ S390X_CAPBIT(S390X_AES_128)) &&\ ++ (OPENSSL_s390xcap_P.kmc[0] & \ ++ S390X_CAPBIT(S390X_AES_128))) ++# define S390X_aes_192_CAPABLE ((OPENSSL_s390xcap_P.km[0] & \ ++ S390X_CAPBIT(S390X_AES_192)) &&\ ++ (OPENSSL_s390xcap_P.kmc[0] & \ ++ S390X_CAPBIT(S390X_AES_192))) ++# define S390X_aes_256_CAPABLE ((OPENSSL_s390xcap_P.km[0] & \ ++ S390X_CAPBIT(S390X_AES_256)) &&\ ++ (OPENSSL_s390xcap_P.kmc[0] & \ ++ S390X_CAPBIT(S390X_AES_256))) ++ ++# define s390x_aes_init_key aes_init_key ++static int s390x_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc); ++ ++# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */ ++# define S390X_aes_192_cbc_CAPABLE 1 ++# define S390X_aes_256_cbc_CAPABLE 1 ++ ++# define s390x_aes_cbc_cipher aes_cbc_cipher ++static int s390x_aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++ ++# define S390X_aes_128_ecb_CAPABLE 0 ++# define S390X_aes_192_ecb_CAPABLE 0 ++# define S390X_aes_256_ecb_CAPABLE 0 ++ ++# define s390x_aes_ecb_cipher aes_ecb_cipher ++static int s390x_aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++ ++# define S390X_aes_128_ofb_CAPABLE 0 ++# define S390X_aes_192_ofb_CAPABLE 0 ++# define S390X_aes_256_ofb_CAPABLE 0 ++ ++# define s390x_aes_ofb_cipher aes_ofb_cipher ++static int s390x_aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++ ++# define S390X_aes_128_cfb_CAPABLE 0 ++# define S390X_aes_192_cfb_CAPABLE 0 ++# define S390X_aes_256_cfb_CAPABLE 0 ++ ++# define s390x_aes_cfb_cipher aes_cfb_cipher ++static int s390x_aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++ ++# define S390X_aes_128_cfb8_CAPABLE 0 ++# define S390X_aes_192_cfb8_CAPABLE 0 ++# define S390X_aes_256_cfb8_CAPABLE 0 ++ ++# define s390x_aes_cfb8_cipher aes_cfb8_cipher ++static int s390x_aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++ ++# define S390X_aes_128_cfb1_CAPABLE 0 ++# define S390X_aes_192_cfb1_CAPABLE 0 ++# define S390X_aes_256_cfb1_CAPABLE 0 ++ ++# define s390x_aes_cfb1_cipher aes_cfb1_cipher ++static int s390x_aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++ ++# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */ ++# define S390X_aes_192_ctr_CAPABLE 1 ++# define S390X_aes_256_ctr_CAPABLE 1 ++ ++# define s390x_aes_ctr_cipher aes_ctr_cipher ++static int s390x_aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++ ++# define S390X_aes_128_gcm_CAPABLE (S390X_aes_128_CAPABLE && \ ++ (OPENSSL_s390xcap_P.kma[0] & \ ++ S390X_CAPBIT(S390X_AES_128))) ++# define S390X_aes_192_gcm_CAPABLE (S390X_aes_192_CAPABLE && \ ++ (OPENSSL_s390xcap_P.kma[0] & \ ++ S390X_CAPBIT(S390X_AES_192))) ++# define S390X_aes_256_gcm_CAPABLE (S390X_aes_256_CAPABLE && \ ++ (OPENSSL_s390xcap_P.kma[0] & \ ++ S390X_CAPBIT(S390X_AES_256))) ++ ++/* iv + padding length for iv lenghts != 12 */ ++# define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16) ++ ++static int s390x_aes_gcm_aad(S390X_AES_GCM_CTX *ctx, const unsigned char *aad, ++ size_t len) ++{ ++ unsigned long long alen; ++ int n, rem; ++ ++ if (ctx->kma.param.tpcl) ++ return -2; ++ ++ alen = ctx->kma.param.taadl + len; ++ if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len)) ++ return -1; ++ ctx->kma.param.taadl = alen; ++ ++ n = ctx->areslen; ++ if (n) { ++ while (n && len) { ++ ctx->ares[n] = *aad; ++ n = (n + 1) & 0xf; ++ ++aad; ++ --len; ++ } ++ /* ctx->ares contains a complete block if offset has wrapped around */ ++ if (!n) { ++ s390x_kma(ctx->ares, 16, NULL, 0, NULL, ctx->fc, &ctx->kma.param); ++ ctx->fc |= S390X_KMA_HS; ++ } ++ ctx->areslen = n; ++ } ++ ++ rem = len & 0xf; ++ ++ len &= ~0xf; ++ if (len) { ++ s390x_kma(aad, len, NULL, 0, NULL, ctx->fc, &ctx->kma.param); ++ aad += len; ++ ctx->fc |= S390X_KMA_HS; ++ } ++ ++ if (rem) { ++ ctx->areslen = rem; ++ ++ do { ++ --rem; ++ ctx->ares[rem] = aad[rem]; ++ } while (rem); ++ } ++ return 0; ++} ++ ++static int s390x_aes_gcm(S390X_AES_GCM_CTX *ctx, const unsigned char *in, ++ unsigned char *out, size_t len) ++{ ++ const unsigned char *inptr; ++ unsigned long long mlen; ++ union { ++ unsigned int w[4]; ++ unsigned char b[16]; ++ } buf; ++ size_t inlen; ++ int n, rem, i; ++ ++ mlen = ctx->kma.param.tpcl + len; ++ if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) ++ return -1; ++ ctx->kma.param.tpcl = mlen; ++ ++ n = ctx->mreslen; ++ if (n) { ++ inptr = in; ++ inlen = len; ++ while (n && inlen) { ++ ctx->mres[n] = *inptr; ++ n = (n + 1) & 0xf; ++ ++inptr; ++ --inlen; ++ } ++ /* ctx->mres contains a complete block if offset has wrapped around */ ++ if (!n) { ++ s390x_kma(ctx->ares, ctx->areslen, ctx->mres, 16, buf.b, ++ ctx->fc | S390X_KMA_LAAD, &ctx->kma.param); ++ ctx->fc |= S390X_KMA_HS; ++ ctx->areslen = 0; ++ ++ /* previous call already encrypted/decrypted its remainder, ++ * see comment below */ ++ n = ctx->mreslen; ++ while (n) { ++ *out = buf.b[n]; ++ n = (n + 1) & 0xf; ++ ++out; ++ ++in; ++ --len; ++ } ++ ctx->mreslen = 0; ++ } ++ } ++ ++ rem = len & 0xf; ++ ++ len &= ~0xf; ++ if (len) { ++ s390x_kma(ctx->ares, ctx->areslen, in, len, out, ++ ctx->fc | S390X_KMA_LAAD, &ctx->kma.param); ++ in += len; ++ out += len; ++ ctx->fc |= S390X_KMA_HS; ++ ctx->areslen = 0; ++ } ++ ++ /*- ++ * If there is a remainder, it has to be saved such that it can be ++ * processed by kma later. However, we also have to do the for-now ++ * unauthenticated encryption/decryption part here and now... ++ */ ++ if (rem) { ++ if (!ctx->mreslen) { ++ buf.w[0] = ctx->kma.param.j0.w[0]; ++ buf.w[1] = ctx->kma.param.j0.w[1]; ++ buf.w[2] = ctx->kma.param.j0.w[2]; ++ buf.w[3] = ctx->kma.param.cv.w + 1; ++ s390x_km(buf.b, 16, ctx->kres, ctx->fc & 0x1f, &ctx->kma.param.k); ++ } ++ ++ n = ctx->mreslen; ++ for (i = 0; i < rem; i++) { ++ ctx->mres[n + i] = in[i]; ++ out[i] = in[i] ^ ctx->kres[n + i]; ++ } ++ ++ ctx->mreslen += rem; ++ } ++ return 0; ++} ++ ++static void s390x_aes_gcm_setiv(S390X_AES_GCM_CTX *ctx, ++ const unsigned char *iv) ++{ ++ ctx->kma.param.t.g[0] = 0; ++ ctx->kma.param.t.g[1] = 0; ++ ctx->kma.param.tpcl = 0; ++ ctx->kma.param.taadl = 0; ++ ctx->mreslen = 0; ++ ctx->areslen = 0; ++ ctx->kreslen = 0; ++ ++ if (ctx->ivlen == 12) { ++ memcpy(&ctx->kma.param.j0, iv, ctx->ivlen); ++ ctx->kma.param.j0.w[3] = 1; ++ ctx->kma.param.cv.w = 1; ++ } else { ++ /* ctx->iv has the right size and is already padded. */ ++ memcpy(ctx->iv, iv, ctx->ivlen); ++ s390x_kma(ctx->iv, S390X_gcm_ivpadlen(ctx->ivlen), NULL, 0, NULL, ++ ctx->fc, &ctx->kma.param); ++ ctx->fc |= S390X_KMA_HS; ++ ++ ctx->kma.param.j0.g[0] = ctx->kma.param.t.g[0]; ++ ctx->kma.param.j0.g[1] = ctx->kma.param.t.g[1]; ++ ctx->kma.param.cv.w = ctx->kma.param.j0.w[3]; ++ ctx->kma.param.t.g[0] = 0; ++ ctx->kma.param.t.g[1] = 0; ++ } ++} ++ ++static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) ++{ ++ S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, c); ++ S390X_AES_GCM_CTX *gctx_out; ++ EVP_CIPHER_CTX *out; ++ unsigned char *buf, *iv; ++ int ivlen, enc, len; ++ ++ switch (type) { ++ case EVP_CTRL_INIT: ++ ivlen = c->cipher->iv_len;; ++ iv = c->iv; ++ gctx->key_set = 0; ++ gctx->iv_set = 0; ++ gctx->ivlen = ivlen; ++ gctx->iv = iv; ++ gctx->taglen = -1; ++ gctx->iv_gen = 0; ++ gctx->tls_aad_len = -1; ++ return 1; ++ ++ case EVP_CTRL_GCM_SET_IVLEN: ++ if (arg <= 0) ++ return 0; ++ ++ if (arg != 12) { ++ iv = c->iv; ++ len = S390X_gcm_ivpadlen(arg); ++ ++ /* Allocate memory for iv if needed. */ ++ if (gctx->ivlen == 12 || len > S390X_gcm_ivpadlen(gctx->ivlen)) { ++ if (gctx->iv != iv) ++ OPENSSL_free(gctx->iv); ++ ++ gctx->iv = OPENSSL_malloc(len); ++ if (gctx->iv == NULL) ++ return 0; ++ } ++ /* Add padding. */ ++ memset(gctx->iv + arg, 0, len - arg - 8); ++ *((unsigned long long *)(gctx->iv + len - 8)) = arg << 3; ++ } ++ gctx->ivlen = arg; ++ return 1; ++ ++ case EVP_CTRL_GCM_SET_TAG: ++ buf = c->buf; ++ enc = c->encrypt; ++ if (arg <= 0 || arg > 16 || enc) ++ return 0; ++ ++ memcpy(buf, ptr, arg); ++ gctx->taglen = arg; ++ return 1; ++ ++ case EVP_CTRL_GCM_GET_TAG: ++ enc = c->encrypt; ++ if (arg <= 0 || arg > 16 || !enc || gctx->taglen < 0) ++ return 0; ++ ++ memcpy(ptr, gctx->kma.param.t.b, arg); ++ return 1; ++ ++ case EVP_CTRL_GCM_SET_IV_FIXED: ++ /* Special case: -1 length restores whole iv */ ++ if (arg == -1) { ++ memcpy(gctx->iv, ptr, gctx->ivlen); ++ gctx->iv_gen = 1; ++ return 1; ++ } ++ /* ++ * Fixed field must be at least 4 bytes and invocation field at least ++ * 8. ++ */ ++ if ((arg < 4) || (gctx->ivlen - arg) < 8) ++ return 0; ++ ++ if (arg) ++ memcpy(gctx->iv, ptr, arg); ++ ++ enc = c->encrypt; ++ if (enc && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) ++ return 0; ++ ++ gctx->iv_gen = 1; ++ return 1; ++ ++ case EVP_CTRL_GCM_IV_GEN: ++ if (gctx->iv_gen == 0 || gctx->key_set == 0) ++ return 0; ++ ++ s390x_aes_gcm_setiv(gctx, gctx->iv); ++ ++ if (arg <= 0 || arg > gctx->ivlen) ++ arg = gctx->ivlen; ++ ++ memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); ++ /* ++ * Invocation field will be at least 8 bytes in size and so no need ++ * to check wrap around or increment more than last 8 bytes. ++ */ ++ (*(unsigned long long *)(gctx->iv + gctx->ivlen - 8))++; ++ gctx->iv_set = 1; ++ return 1; ++ ++ case EVP_CTRL_GCM_SET_IV_INV: ++ enc = c->encrypt; ++ if (gctx->iv_gen == 0 || gctx->key_set == 0 || enc) ++ return 0; ++ ++ memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); ++ s390x_aes_gcm_setiv(gctx, gctx->iv); ++ gctx->iv_set = 1; ++ return 1; ++ ++ case EVP_CTRL_AEAD_TLS1_AAD: ++ /* Save the aad for later use. */ ++ if (arg != EVP_AEAD_TLS1_AAD_LEN) ++ return 0; ++ ++ buf = c->buf; ++ memcpy(buf, ptr, arg); ++ gctx->tls_aad_len = arg; ++ ++ len = buf[arg - 2] << 8 | buf[arg - 1]; ++ /* Correct length for explicit iv. */ ++ if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN) ++ return 0; ++ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; ++ ++ /* If decrypting correct for tag too. */ ++ enc = c->encrypt; ++ if (!enc) { ++ if (len < EVP_GCM_TLS_TAG_LEN) ++ return 0; ++ len -= EVP_GCM_TLS_TAG_LEN; ++ } ++ buf[arg - 2] = len >> 8; ++ buf[arg - 1] = len & 0xff; ++ /* Extra padding: tag appended to record. */ ++ return EVP_GCM_TLS_TAG_LEN; ++ ++ case EVP_CTRL_COPY: ++ out = ptr; ++ gctx_out = EVP_C_DATA(S390X_AES_GCM_CTX, out); ++ iv = c->iv; ++ ++ if (gctx->iv == iv) { ++ gctx_out->iv = out->iv; ++ } else { ++ len = S390X_gcm_ivpadlen(gctx->ivlen); ++ ++ gctx_out->iv = OPENSSL_malloc(len); ++ if (gctx_out->iv == NULL) ++ return 0; ++ ++ memcpy(gctx_out->iv, gctx->iv, len); ++ } ++ return 1; ++ ++ default: ++ return -1; ++ } ++} ++ ++static int s390x_aes_gcm_init_key(EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, ++ const unsigned char *iv, int enc) ++{ ++ S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, ctx); ++ int keylen; ++ ++ if (iv == NULL && key == NULL) ++ return 1; ++ ++ if (key != NULL) { ++ keylen = EVP_CIPHER_CTX_key_length(ctx); ++ memcpy(&gctx->kma.param.k, key, keylen); ++ ++ /* Convert key size to function code. */ ++ gctx->fc = S390X_AES_128 + (((keylen << 3) - 128) >> 6); ++ if (!enc) ++ gctx->fc |= S390X_DECRYPT; ++ ++ if (iv == NULL && gctx->iv_set) ++ iv = gctx->iv; ++ ++ if (iv != NULL) { ++ s390x_aes_gcm_setiv(gctx, iv); ++ gctx->iv_set = 1; ++ } ++ gctx->key_set = 1; ++ } else { ++ if (gctx->key_set) ++ s390x_aes_gcm_setiv(gctx, iv); ++ else ++ memcpy(gctx->iv, iv, gctx->ivlen); ++ ++ gctx->iv_set = 1; ++ gctx->iv_gen = 0; ++ } ++ return 1; ++} ++ ++static int s390x_aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) ++{ ++ S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, ctx); ++ const unsigned char *buf = ctx->buf; ++ const int enc = ctx->encrypt; ++ int rv = -1; ++ ++ if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) ++ return -1; ++ ++ if (EVP_CIPHER_CTX_ctrl(ctx, enc ? EVP_CTRL_GCM_IV_GEN ++ : EVP_CTRL_GCM_SET_IV_INV, ++ EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) ++ goto err; ++ ++ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; ++ out += EVP_GCM_TLS_EXPLICIT_IV_LEN; ++ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; ++ ++ gctx->kma.param.taadl = gctx->tls_aad_len << 3; ++ gctx->kma.param.tpcl = len << 3; ++ s390x_kma(buf, gctx->tls_aad_len, in, len, out, ++ gctx->fc | S390X_KMA_LAAD | S390X_KMA_LPC, &gctx->kma.param); ++ ++ if (enc) { ++ memcpy(out + len, gctx->kma.param.t.b, EVP_GCM_TLS_TAG_LEN); ++ rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; ++ } else { ++ if (CRYPTO_memcmp(gctx->kma.param.t.b, in + len, ++ EVP_GCM_TLS_TAG_LEN)) { ++ OPENSSL_cleanse(out, len); ++ goto err; ++ } ++ rv = len; ++ } ++err: ++ gctx->iv_set = 0; ++ gctx->tls_aad_len = -1; ++ return rv; ++} ++ ++static int s390x_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len) ++{ ++ S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, ctx); ++ unsigned char *buf, tmp[16]; ++ int enc; ++ ++ if (!gctx->key_set) ++ return -1; ++ ++ if (gctx->tls_aad_len >= 0) ++ return s390x_aes_gcm_tls_cipher(ctx, out, in, len); ++ ++ if (!gctx->iv_set) ++ return -1; ++ ++ if (in != NULL) { ++ if (out == NULL) { ++ if (s390x_aes_gcm_aad(gctx, in, len)) ++ return -1; ++ } else { ++ if (s390x_aes_gcm(gctx, in, out, len)) ++ return -1; ++ } ++ return len; ++ } else { ++ gctx->kma.param.taadl <<= 3; ++ gctx->kma.param.tpcl <<= 3; ++ s390x_kma(gctx->ares, gctx->areslen, gctx->mres, gctx->mreslen, tmp, ++ gctx->fc | S390X_KMA_LAAD | S390X_KMA_LPC, &gctx->kma.param); ++ /* recall that we already did en-/decrypt gctx->mres ++ * and returned it to caller... */ ++ OPENSSL_cleanse(tmp, gctx->mreslen); ++ gctx->iv_set = 0; ++ ++ enc = ctx->encrypt; ++ if (enc) { ++ gctx->taglen = 16; ++ } else { ++ if (gctx->taglen < 0) ++ return -1; ++ ++ buf = ctx->buf; ++ if (CRYPTO_memcmp(buf, gctx->kma.param.t.b, gctx->taglen)) ++ return -1; ++ } ++ return 0; ++ } ++} ++ ++static int s390x_aes_gcm_cleanup(EVP_CIPHER_CTX *c) ++{ ++ S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, c); ++ const unsigned char *iv; ++ ++ if (gctx == NULL) ++ return 0; ++ ++ iv = c->iv; ++ if (iv != gctx->iv) ++ OPENSSL_free(gctx->iv); ++ ++ OPENSSL_cleanse(gctx, sizeof(*gctx)); ++ return 1; ++} ++ ++# define S390X_AES_XTS_CTX EVP_AES_XTS_CTX ++# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */ ++# define S390X_aes_256_xts_CAPABLE 1 ++ ++# define s390x_aes_xts_init_key aes_xts_init_key ++static int s390x_aes_xts_init_key(EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, ++ const unsigned char *iv, int enc); ++# define s390x_aes_xts_cipher aes_xts_cipher ++static int s390x_aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++# define s390x_aes_xts_ctrl aes_xts_ctrl ++static int s390x_aes_xts_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr); ++# define s390x_aes_xts_cleanup aes_xts_cleanup ++ ++# define S390X_AES_CCM_CTX EVP_AES_CCM_CTX ++# define S390X_aes_128_ccm_CAPABLE 0 ++# define S390X_aes_192_ccm_CAPABLE 0 ++# define S390X_aes_256_ccm_CAPABLE 0 ++ ++# define s390x_aes_ccm_init_key aes_ccm_init_key ++static int s390x_aes_ccm_init_key(EVP_CIPHER_CTX *ctx, ++ const unsigned char *key, ++ const unsigned char *iv, int enc); ++# define s390x_aes_ccm_cipher aes_ccm_cipher ++static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t len); ++# define s390x_aes_ccm_ctrl aes_ccm_ctrl ++static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *, int type, int arg, void *ptr); ++# define s390x_aes_ccm_cleanup aes_ccm_cleanup ++ ++# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode, \ ++ MODE,flags) \ ++static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ ++ nid##_##keylen##_##nmode,blocksize, \ ++ keylen / 8, \ ++ ivlen, \ ++ flags | EVP_CIPH_##MODE##_MODE, \ ++ s390x_aes_init_key, \ ++ s390x_aes_##mode##_cipher, \ ++ NULL, \ ++ sizeof(EVP_AES_KEY), \ ++ NULL, \ ++ NULL, \ ++ NULL, \ ++ NULL \ ++}; \ ++static const EVP_CIPHER aes_##keylen##_##mode = { \ ++ nid##_##keylen##_##nmode, \ ++ blocksize, \ ++ keylen / 8, \ ++ ivlen, \ ++ flags | EVP_CIPH_##MODE##_MODE, \ ++ aes_init_key, \ ++ aes_##mode##_cipher, \ ++ NULL, \ ++ sizeof(EVP_AES_KEY), \ ++ NULL,NULL,NULL,NULL \ ++}; \ ++const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ ++{ \ ++ return S390X_aes_##keylen##_##mode##_CAPABLE ? \ ++ &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ ++} ++ ++# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags)\ ++static const EVP_CIPHER s390x_aes_##keylen##_##mode = { \ ++ nid##_##keylen##_##mode, \ ++ blocksize, \ ++ (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) * keylen / 8, \ ++ ivlen, \ ++ flags | EVP_CIPH_##MODE##_MODE, \ ++ s390x_aes_##mode##_init_key, \ ++ s390x_aes_##mode##_cipher, \ ++ s390x_aes_##mode##_cleanup, \ ++ sizeof(S390X_AES_##MODE##_CTX), \ ++ NULL, \ ++ NULL, \ ++ s390x_aes_##mode##_ctrl, \ ++ NULL \ ++}; \ ++static const EVP_CIPHER aes_##keylen##_##mode = { \ ++ nid##_##keylen##_##mode,blocksize, \ ++ (EVP_CIPH_##MODE##_MODE == EVP_CIPH_XTS_MODE ? 2 : 1) * keylen / 8, \ ++ ivlen, \ ++ flags | EVP_CIPH_##MODE##_MODE, \ ++ aes_##mode##_init_key, \ ++ aes_##mode##_cipher, \ ++ aes_##mode##_cleanup, \ ++ sizeof(EVP_AES_##MODE##_CTX), \ ++ NULL, \ ++ NULL, \ ++ aes_##mode##_ctrl, \ ++ NULL \ ++}; \ ++const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ ++{ \ ++ return S390X_aes_##keylen##_##mode##_CAPABLE ? \ ++ &s390x_aes_##keylen##_##mode : &aes_##keylen##_##mode; \ ++} ++ + # else + + # define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +diff -up openssl-1.0.2k/crypto/Makefile.s390x-update openssl-1.0.2k/crypto/Makefile +--- openssl-1.0.2k/crypto/Makefile.s390x-update 2018-06-18 12:20:49.079040659 +0200 ++++ openssl-1.0.2k/crypto/Makefile 2018-06-18 13:27:53.065204592 +0200 +@@ -77,6 +77,7 @@ alphacpuid.s: alphacpuid.pl + (preproc=$$$$.$@.S; trap "rm $$preproc" INT; \ + $(PERL) alphacpuid.pl > $$preproc && \ + $(CC) -E -P $$preproc > $@ && rm $$preproc) ++s390xcpuid.S: s390xcpuid.pl; $(PERL) s390xcpuid.pl $(PERLASM_SCHEME) $@ + + testapps: + [ -z "$(THIS)" ] || ( if echo $(SDIRS) | fgrep ' des '; \ +diff -up openssl-1.0.2k/crypto/modes/asm/ghash-s390x.pl.s390x-update openssl-1.0.2k/crypto/modes/asm/ghash-s390x.pl +--- openssl-1.0.2k/crypto/modes/asm/ghash-s390x.pl.s390x-update 2018-06-18 12:20:47.170993976 +0200 ++++ openssl-1.0.2k/crypto/modes/asm/ghash-s390x.pl 2018-06-18 13:27:37.110817228 +0200 +@@ -73,6 +73,8 @@ $rem_4bit="%r14"; + $sp="%r15"; + + $code.=<<___; ++#include "s390x_arch.h" ++ + .text + + .globl gcm_gmult_4bit +@@ -85,12 +87,13 @@ $code.=<<___ if(!$softonly && 0); # hard + tmhl %r0,0x4000 # check for message-security-assist + jz .Lsoft_gmult + lghi %r0,0 +- lg %r1,24(%r1) # load second word of kimd capabilities vector ++ lg %r1,S390X_KIMD+8(%r1) # load second word of kimd capabilities ++ # vector + tmhh %r1,0x4000 # check for function 65 + jz .Lsoft_gmult + stg %r0,16($sp) # arrange 16 bytes of zero input + stg %r0,24($sp) +- lghi %r0,65 # function 65 ++ lghi %r0,S390X_GHASH # function 65 + la %r1,0($Xi) # H lies right after Xi in gcm128_context + la $inp,16($sp) + lghi $len,16 +@@ -119,16 +122,11 @@ gcm_ghash_4bit: + ___ + $code.=<<___ if(!$softonly); + larl %r1,OPENSSL_s390xcap_P +- lg %r0,0(%r1) +- tmhl %r0,0x4000 # check for message-security-assist +- jz .Lsoft_ghash +- lghi %r0,0 +- la %r1,16($sp) +- .long 0xb93e0004 # kimd %r0,%r4 +- lg %r1,24($sp) +- tmhh %r1,0x4000 # check for function 65 ++ lg %r0,S390X_KIMD+8(%r1) # load second word of kimd capabilities ++ # vector ++ tmhh %r0,0x4000 # check for function 65 + jz .Lsoft_ghash +- lghi %r0,65 # function 65 ++ lghi %r0,S390X_GHASH # function 65 + la %r1,0($Xi) # H lies right after Xi in gcm128_context + .long 0xb93e0004 # kimd %r0,$inp + brc 1,.-4 # pay attention to "partial completion" +diff -up openssl-1.0.2k/crypto/modes/Makefile.s390x-update openssl-1.0.2k/crypto/modes/Makefile +--- openssl-1.0.2k/crypto/modes/Makefile.s390x-update 2018-06-18 12:20:47.020990305 +0200 ++++ openssl-1.0.2k/crypto/modes/Makefile 2018-06-18 13:27:37.110817228 +0200 +@@ -71,6 +71,8 @@ ghash-%.S: asm/ghash-%.pl; $(PERL) $< $( + ghash-armv4.o: ghash-armv4.S + ghashv8-armx.o: ghashv8-armx.S + ++ghash-s390x.o: ghash-s390x.S ++ + files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +diff -up openssl-1.0.2k/crypto/sha/asm/sha1-s390x.pl.s390x-update openssl-1.0.2k/crypto/sha/asm/sha1-s390x.pl +--- openssl-1.0.2k/crypto/sha/asm/sha1-s390x.pl.s390x-update 2018-06-18 12:20:47.174994073 +0200 ++++ openssl-1.0.2k/crypto/sha/asm/sha1-s390x.pl 2018-06-18 13:27:37.112817276 +0200 +@@ -152,6 +152,8 @@ ___ + } + + $code.=<<___; ++#include "s390x_arch.h" ++ + .text + .align 64 + .type Ktable,\@object +@@ -164,10 +166,7 @@ sha1_block_data_order: + ___ + $code.=<<___ if ($kimdfunc); + larl %r1,OPENSSL_s390xcap_P +- lg %r0,0(%r1) +- tmhl %r0,0x4000 # check for message-security assist +- jz .Lsoftware +- lg %r0,16(%r1) # check kimd capabilities ++ lg %r0,S390X_KIMD(%r1) # check kimd capabilities + tmhh %r0,`0x8000>>$kimdfunc` + jz .Lsoftware + lghi %r0,$kimdfunc +@@ -234,7 +233,6 @@ $code.=<<___; + br %r14 + .size sha1_block_data_order,.-sha1_block_data_order + .string "SHA1 block transform for s390x, CRYPTOGAMS by " +-.comm OPENSSL_s390xcap_P,80,8 + ___ + + $code =~ s/\`([^\`]*)\`/eval $1/gem; +diff -up openssl-1.0.2k/crypto/sha/asm/sha512-s390x.pl.s390x-update openssl-1.0.2k/crypto/sha/asm/sha512-s390x.pl +--- openssl-1.0.2k/crypto/sha/asm/sha512-s390x.pl.s390x-update 2018-06-18 12:20:47.179994196 +0200 ++++ openssl-1.0.2k/crypto/sha/asm/sha512-s390x.pl 2018-06-18 13:27:37.112817276 +0200 +@@ -163,6 +163,8 @@ ___ + } + + $code.=<<___; ++#include "s390x_arch.h" ++ + .text + .align 64 + .type $Table,\@object +@@ -237,10 +239,7 @@ $Func: + ___ + $code.=<<___ if ($kimdfunc); + larl %r1,OPENSSL_s390xcap_P +- lg %r0,0(%r1) +- tmhl %r0,0x4000 # check for message-security assist +- jz .Lsoftware +- lg %r0,16(%r1) # check kimd capabilities ++ lg %r0,S390X_KIMD(%r1) # check kimd capabilities + tmhh %r0,`0x8000>>$kimdfunc` + jz .Lsoftware + lghi %r0,$kimdfunc +@@ -308,7 +307,6 @@ $code.=<<___; + br %r14 + .size $Func,.-$Func + .string "SHA${label} block transform for s390x, CRYPTOGAMS by " +-.comm OPENSSL_s390xcap_P,80,8 + ___ + + $code =~ s/\`([^\`]*)\`/eval $1/gem; +diff -up openssl-1.0.2k/crypto/sha/Makefile.s390x-update openssl-1.0.2k/crypto/sha/Makefile +--- openssl-1.0.2k/crypto/sha/Makefile.s390x-update 2018-06-18 12:20:49.482050519 +0200 ++++ openssl-1.0.2k/crypto/sha/Makefile 2018-06-18 13:27:37.112817276 +0200 +@@ -100,6 +100,10 @@ sha1-armv8.o: sha1-armv8.S + sha256-armv8.o: sha256-armv8.S + sha512-armv8.o: sha512-armv8.S + ++sha1-s390x.o: sha1-s390x.S ++sha256-s390x.o: sha256-s390x.S ++sha512-s390x.o: sha512-s390x.S ++ + files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +diff -up openssl-1.0.2k/crypto/s390x_arch.h.s390x-update openssl-1.0.2k/crypto/s390x_arch.h +--- openssl-1.0.2k/crypto/s390x_arch.h.s390x-update 2018-06-18 13:27:37.110817228 +0200 ++++ openssl-1.0.2k/crypto/s390x_arch.h 2018-06-18 13:27:53.066204616 +0200 +@@ -0,0 +1,93 @@ ++/* ++ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. ++ * ++ * Licensed under the OpenSSL license (the "License"). You may not use ++ * this file except in compliance with the License. You can obtain a copy ++ * in the file LICENSE in the source distribution or at ++ * https://www.openssl.org/source/license.html ++ */ ++ ++#ifndef S390X_ARCH_H ++# define S390X_ARCH_H ++ ++# ifndef __ASSEMBLER__ ++ ++void s390x_km(const unsigned char *in, size_t len, unsigned char *out, ++ unsigned int fc, void *param); ++void s390x_kma(const unsigned char *aad, size_t alen, const unsigned char *in, ++ size_t len, unsigned char *out, unsigned int fc, void *param); ++ ++/* ++ * The field elements of OPENSSL_s390xcap_P are the 64-bit words returned by ++ * the STFLE instruction followed by the 64-bit word pairs returned by ++ * instructions' QUERY functions. If STFLE returns fewer data or an instruction ++ * is not supported, the corresponding field elements are zero. ++ */ ++struct OPENSSL_s390xcap_st { ++ unsigned long long stfle[4]; ++ unsigned long long kimd[2]; ++ unsigned long long klmd[2]; ++ unsigned long long km[2]; ++ unsigned long long kmc[2]; ++ unsigned long long kmac[2]; ++ unsigned long long kmctr[2]; ++ unsigned long long kmo[2]; ++ unsigned long long kmf[2]; ++ unsigned long long prno[2]; ++ unsigned long long kma[2]; ++}; ++ ++extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; ++ ++/* convert facility bit number or function code to bit mask */ ++# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64)) ++ ++# endif ++ ++/* OPENSSL_s390xcap_P offsets [bytes] */ ++# define S390X_STFLE 0x00 ++# define S390X_KIMD 0x20 ++# define S390X_KLMD 0x30 ++# define S390X_KM 0x40 ++# define S390X_KMC 0x50 ++# define S390X_KMAC 0x60 ++# define S390X_KMCTR 0x70 ++# define S390X_KMO 0x80 ++# define S390X_KMF 0x90 ++# define S390X_PRNO 0xa0 ++# define S390X_KMA 0xb0 ++ ++/* Facility Bit Numbers */ ++# define S390X_VX 129 ++# define S390X_VXD 134 ++# define S390X_VXE 135 ++ ++/* Function Codes */ ++ ++/* all instructions */ ++# define S390X_QUERY 0 ++ ++/* kimd/klmd */ ++# define S390X_SHA3_224 32 ++# define S390X_SHA3_256 33 ++# define S390X_SHA3_384 34 ++# define S390X_SHA3_512 35 ++# define S390X_SHAKE_128 36 ++# define S390X_SHAKE_256 37 ++# define S390X_GHASH 65 ++ ++/* km/kmc/kmac/kmctr/kmo/kmf/kma */ ++# define S390X_AES_128 18 ++# define S390X_AES_192 19 ++# define S390X_AES_256 20 ++ ++/* prno */ ++# define S390X_TRNG 114 ++ ++/* Register 0 Flags */ ++# define S390X_DECRYPT 0x80 ++# define S390X_KMA_LPC 0x100 ++# define S390X_KMA_LAAD 0x200 ++# define S390X_KMA_HS 0x400 ++ ++#endif +diff -up openssl-1.0.2k/crypto/s390xcap.c.s390x-update openssl-1.0.2k/crypto/s390xcap.c +--- openssl-1.0.2k/crypto/s390xcap.c.s390x-update 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/s390xcap.c 2018-06-18 13:27:37.111817252 +0200 +@@ -4,8 +4,7 @@ + #include + #include + #include "cryptlib.h" +- +-extern unsigned long OPENSSL_s390xcap_P[]; ++#include "s390x_arch.h" + + static sigjmp_buf ill_jmp; + static void ill_handler(int sig) +@@ -13,30 +12,48 @@ static void ill_handler(int sig) + siglongjmp(ill_jmp, sig); + } + +-unsigned long OPENSSL_s390x_facilities(void); ++void OPENSSL_s390x_facilities(void); ++void OPENSSL_vx_probe(void); ++ ++struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; + + void OPENSSL_cpuid_setup(void) + { + sigset_t oset; + struct sigaction ill_act, oact; + +- if (OPENSSL_s390xcap_P[0]) ++ if (OPENSSL_s390xcap_P.stfle[0]) + return; + +- OPENSSL_s390xcap_P[0] = 1UL << (8 * sizeof(unsigned long) - 1); ++ /* set a bit that will not be tested later */ ++ OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0); + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + sigfillset(&ill_act.sa_mask); + sigdelset(&ill_act.sa_mask, SIGILL); ++ sigdelset(&ill_act.sa_mask, SIGFPE); + sigdelset(&ill_act.sa_mask, SIGTRAP); + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &oact); ++ sigaction(SIGFPE, &ill_act, &oact); + + /* protection against missing store-facility-list-extended */ + if (sigsetjmp(ill_jmp, 1) == 0) + OPENSSL_s390x_facilities(); + ++ /* protection against disabled vector facility */ ++ if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) ++ && (sigsetjmp(ill_jmp, 1) == 0)) { ++ OPENSSL_vx_probe(); ++ } else { ++ OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) ++ | S390X_CAPBIT(S390X_VXD) ++ | S390X_CAPBIT(S390X_VXE)); ++ } ++ ++ sigaction(SIGFPE, &oact, NULL); ++ + sigaction(SIGILL, &oact, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + } +diff -up openssl-1.0.2k/crypto/s390xcpuid.pl.s390x-update openssl-1.0.2k/crypto/s390xcpuid.pl +--- openssl-1.0.2k/crypto/s390xcpuid.pl.s390x-update 2018-06-18 13:27:53.067204641 +0200 ++++ openssl-1.0.2k/crypto/s390xcpuid.pl 2018-06-18 13:27:53.067204641 +0200 +@@ -0,0 +1,259 @@ ++#! /usr/bin/env perl ++ ++$flavour = shift; ++ ++if ($flavour =~ /3[12]/) { ++ $SIZE_T=4; ++ $g=""; ++} else { ++ $SIZE_T=8; ++ $g="g"; ++} ++ ++while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} ++open STDOUT,">$output"; ++ ++$ra="%r14"; ++$sp="%r15"; ++$stdframe=16*$SIZE_T+4*8; ++ ++$code=<<___; ++#include "s390x_arch.h" ++ ++.text ++ ++.globl OPENSSL_s390x_facilities ++.type OPENSSL_s390x_facilities,\@function ++.align 16 ++OPENSSL_s390x_facilities: ++ lghi %r0,0 ++ larl %r4,OPENSSL_s390xcap_P ++ ++ stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors ++ stg %r0,S390X_STFLE+16(%r4) ++ stg %r0,S390X_STFLE+24(%r4) ++ stg %r0,S390X_KIMD(%r4) ++ stg %r0,S390X_KIMD+8(%r4) ++ stg %r0,S390X_KLMD(%r4) ++ stg %r0,S390X_KLMD+8(%r4) ++ stg %r0,S390X_KM(%r4) ++ stg %r0,S390X_KM+8(%r4) ++ stg %r0,S390X_KMC(%r4) ++ stg %r0,S390X_KMC+8(%r4) ++ stg %r0,S390X_KMAC(%r4) ++ stg %r0,S390X_KMAC+8(%r4) ++ stg %r0,S390X_KMCTR(%r4) ++ stg %r0,S390X_KMCTR+8(%r4) ++ stg %r0,S390X_KMO(%r4) ++ stg %r0,S390X_KMO+8(%r4) ++ stg %r0,S390X_KMF(%r4) ++ stg %r0,S390X_KMF+8(%r4) ++ stg %r0,S390X_PRNO(%r4) ++ stg %r0,S390X_PRNO+8(%r4) ++ stg %r0,S390X_KMA(%r4) ++ stg %r0,S390X_KMA+8(%r4) ++ ++ .long 0xb2b04000 # stfle 0(%r4) ++ brc 8,.Ldone ++ lghi %r0,1 ++ .long 0xb2b04000 # stfle 0(%r4) ++ brc 8,.Ldone ++ lghi %r0,2 ++ .long 0xb2b04000 # stfle 0(%r4) ++.Ldone: ++ lmg %r2,%r3,S390X_STFLE(%r4) ++ tmhl %r2,0x4000 # check for message-security-assist ++ jz .Lret ++ ++ lghi %r0,S390X_QUERY # query kimd capabilities ++ la %r1,S390X_KIMD(%r4) ++ .long 0xb93e0002 # kimd %r0,%r2 ++ ++ lghi %r0,S390X_QUERY # query klmd capabilities ++ la %r1,S390X_KLMD(%r4) ++ .long 0xb93f0002 # klmd %r0,%r2 ++ ++ lghi %r0,S390X_QUERY # query km capability vector ++ la %r1,S390X_KM(%r4) ++ .long 0xb92e0042 # km %r4,%r2 ++ ++ lghi %r0,S390X_QUERY # query kmc capability vector ++ la %r1,S390X_KMC(%r4) ++ .long 0xb92f0042 # kmc %r4,%r2 ++ ++ lghi %r0,S390X_QUERY # query kmac capability vector ++ la %r1,S390X_KMAC(%r4) ++ .long 0xb91e0042 # kmac %r4,%r2 ++ ++ tmhh %r3,0x0004 # check for message-security-assist-4 ++ jz .Lret ++ ++ lghi %r0,S390X_QUERY # query kmctr capability vector ++ la %r1,S390X_KMCTR(%r4) ++ .long 0xb92d2042 # kmctr %r4,%r2,%r2 ++ ++ lghi %r0,S390X_QUERY # query kmo capability vector ++ la %r1,S390X_KMO(%r4) ++ .long 0xb92b0042 # kmo %r4,%r2 ++ ++ lghi %r0,S390X_QUERY # query kmf capability vector ++ la %r1,S390X_KMF(%r4) ++ .long 0xb92a0042 # kmf %r4,%r2 ++ ++ tml %r2,0x40 # check for message-security-assist-5 ++ jz .Lret ++ ++ lghi %r0,S390X_QUERY # query prno capability vector ++ la %r1,S390X_PRNO(%r4) ++ .long 0xb93c0042 # prno %r4,%r2 ++ ++ lg %r2,S390X_STFLE+16(%r4) ++ tmhl %r2,0x2000 # check for message-security-assist-8 ++ jz .Lret ++ ++ lghi %r0,S390X_QUERY # query kma capability vector ++ la %r1,S390X_KMA(%r4) ++ .long 0xb9294022 # kma %r2,%r4,%r2 ++ ++.Lret: ++ br $ra ++.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities ++ ++.globl OPENSSL_rdtsc ++.type OPENSSL_rdtsc,\@function ++.align 16 ++OPENSSL_rdtsc: ++ stck 16($sp) ++ lg %r2,16($sp) ++ br $ra ++.size OPENSSL_rdtsc,.-OPENSSL_rdtsc ++ ++.globl OPENSSL_atomic_add ++.type OPENSSL_atomic_add,\@function ++.align 16 ++OPENSSL_atomic_add: ++ l %r1,0(%r2) ++.Lspin: lr %r0,%r1 ++ ar %r0,%r3 ++ cs %r1,%r0,0(%r2) ++ brc 4,.Lspin ++ lgfr %r2,%r0 # OpenSSL expects the new value ++ br $ra ++.size OPENSSL_atomic_add,.-OPENSSL_atomic_add ++ ++.globl OPENSSL_wipe_cpu ++.type OPENSSL_wipe_cpu,\@function ++.align 16 ++OPENSSL_wipe_cpu: ++ xgr %r0,%r0 ++ xgr %r1,%r1 ++ lgr %r2,$sp ++ xgr %r3,%r3 ++ xgr %r4,%r4 ++ lzdr %f0 ++ lzdr %f1 ++ lzdr %f2 ++ lzdr %f3 ++ lzdr %f4 ++ lzdr %f5 ++ lzdr %f6 ++ lzdr %f7 ++ br $ra ++.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu ++ ++.globl OPENSSL_cleanse ++.type OPENSSL_cleanse,\@function ++.align 16 ++OPENSSL_cleanse: ++#if !defined(__s390x__) && !defined(__s390x) ++ llgfr %r3,%r3 ++#endif ++ lghi %r4,15 ++ lghi %r0,0 ++ clgr %r3,%r4 ++ jh .Lot ++ clgr %r3,%r0 ++ bcr 8,%r14 ++.Little: ++ stc %r0,0(%r2) ++ la %r2,1(%r2) ++ brctg %r3,.Little ++ br %r14 ++.align 4 ++.Lot: tmll %r2,7 ++ jz .Laligned ++ stc %r0,0(%r2) ++ la %r2,1(%r2) ++ brctg %r3,.Lot ++.Laligned: ++ srlg %r4,%r3,3 ++.Loop: stg %r0,0(%r2) ++ la %r2,8(%r2) ++ brctg %r4,.Loop ++ lghi %r4,7 ++ ngr %r3,%r4 ++ jnz .Little ++ br $ra ++.size OPENSSL_cleanse,.-OPENSSL_cleanse ++ ++.globl OPENSSL_vx_probe ++.type OPENSSL_vx_probe,\@function ++.align 16 ++OPENSSL_vx_probe: ++ .word 0xe700,0x0000,0x0044 # vzero %v0 ++ br $ra ++.size OPENSSL_vx_probe,.-OPENSSL_vx_probe ++___ ++ ++################ ++# void s390x_km(const unsigned char *in, size_t len, unsigned char *out, ++# unsigned int fc, void *param) ++{ ++my ($in,$len,$out,$fc,$param) = map("%r$_",(2..6)); ++$code.=<<___; ++.globl s390x_km ++.type s390x_km,\@function ++.align 16 ++s390x_km: ++ lr %r0,$fc ++ l${g}r %r1,$param ++ ++ .long 0xb92e0042 # km $out,$in ++ brc 1,.-4 # pay attention to "partial completion" ++ ++ br $ra ++.size s390x_km,.-s390x_km ++___ ++} ++ ++################ ++# void s390x_kma(const unsigned char *aad, size_t alen, ++# const unsigned char *in, size_t len, ++# unsigned char *out, unsigned int fc, void *param) ++{ ++my ($aad,$alen,$in,$len,$out) = map("%r$_",(2..6)); ++$code.=<<___; ++.globl s390x_kma ++.type s390x_kma,\@function ++.align 16 ++s390x_kma: ++ st${g} $out,6*$SIZE_T($sp) ++ lm${g} %r0,%r1,$stdframe($sp) ++ ++ .long 0xb9292064 # kma $out,$aad,$in ++ brc 1,.-4 # pay attention to "partial completion" ++ ++ l${g} $out,6*$SIZE_T($sp) ++ br $ra ++.size s390x_kma,.-s390x_kma ++___ ++} ++ ++$code.=<<___; ++.section .init ++ brasl $ra,OPENSSL_cpuid_setup ++___ ++ ++$code =~ s/\`([^\`]*)\`/eval $1/gem; ++print $code; ++close STDOUT; # force flush diff --git a/openssl-dont-include-winsock-h.patch b/openssl-dont-include-winsock-h.patch new file mode 100644 index 0000000..a5082e4 --- /dev/null +++ b/openssl-dont-include-winsock-h.patch @@ -0,0 +1,11 @@ +--- ssl/dtls1.h.orig 2014-12-22 19:03:22.442338471 +0100 ++++ ssl/dtls1.h 2014-12-22 19:03:44.061694335 +0100 +@@ -68,7 +68,7 @@ + # endif + # ifdef OPENSSL_SYS_WIN32 + /* Needed for struct timeval */ +-# include ++# include + # elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) + # include + # else diff --git a/openssl-mingw64-dont-use-secure-getenv.patch b/openssl-mingw64-dont-use-secure-getenv.patch new file mode 100644 index 0000000..515d44b --- /dev/null +++ b/openssl-mingw64-dont-use-secure-getenv.patch @@ -0,0 +1,26 @@ +diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c +index 23271be..f57ca72 100644 +--- a/crypto/asn1/a_verify.c ++++ b/crypto/asn1/a_verify.c +@@ -143,7 +143,7 @@ static int is_md_legacy_disallowed(int mdnid) + { + int i; + +- if (mdnid == NID_md5 && secure_getenv("OPENSSL_ENABLE_MD5_VERIFY") != NULL) ++ if (mdnid == NID_md5 && getenv("OPENSSL_ENABLE_MD5_VERIFY") != NULL) + return 0; + + for (i = 0; legacy_mds[i] != 0; ++i) { +diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c +index 732804f..8f845f7 100644 +--- a/ssl/ssl_ciph.c ++++ b/ssl/ssl_ciph.c +@@ -486,7 +486,7 @@ static void load_builtin_compressions(void) + MemCheck_off(); + ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp); + if (ssl_comp_methods != NULL +- && secure_getenv("OPENSSL_DEFAULT_ZLIB") != NULL) { ++ && getenv("OPENSSL_DEFAULT_ZLIB") != NULL) { + comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp != NULL) { + comp->method = COMP_zlib(); diff --git a/openssl-thread-test.c b/openssl-thread-test.c new file mode 100644 index 0000000..3b90285 --- /dev/null +++ b/openssl-thread-test.c @@ -0,0 +1,400 @@ +/* Test program to verify that RSA signing is thread-safe in OpenSSL. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Just assume we want to do engine stuff if we're using 0.9.6b or + * higher. This assumption is only valid for versions bundled with RHL. */ +#if OPENSSL_VERSION_NUMBER >= 0x0090602fL +#include +#define USE_ENGINE +#endif + +#define MAX_THREAD_COUNT 10000 +#define ITERATION_COUNT 10 +#define MAIN_COUNT 100 + +/* OpenSSL requires us to provide thread ID and locking primitives. */ +pthread_mutex_t *mutex_locks = NULL; +static unsigned long +thread_id_cb(void) +{ + return (unsigned long) pthread_self(); +} +static void +lock_cb(int mode, int n, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&mutex_locks[n]); + } else { + pthread_mutex_unlock(&mutex_locks[n]); + } +} + +struct thread_args { + RSA *rsa; + int digest_type; + unsigned char *digest; + unsigned int digest_len; + unsigned char *signature; + unsigned int signature_len; + pthread_t main_thread; +}; + +static int print = 0; + +pthread_mutex_t sign_lock = PTHREAD_MUTEX_INITIALIZER; +static int locked_sign = 0; +static void SIGN_LOCK() {if (locked_sign) pthread_mutex_lock(&sign_lock);} +static void SIGN_UNLOCK() {if (locked_sign) pthread_mutex_unlock(&sign_lock);} + +pthread_mutex_t verify_lock = PTHREAD_MUTEX_INITIALIZER; +static int locked_verify = 0; +static void VERIFY_LOCK() {if (locked_verify) pthread_mutex_lock(&verify_lock);} +static void VERIFY_UNLOCK() {if (locked_verify) pthread_mutex_unlock(&verify_lock);} + +pthread_mutex_t failure_count_lock = PTHREAD_MUTEX_INITIALIZER; +long failure_count = 0; +static void +failure() +{ + pthread_mutex_lock(&failure_count_lock); + failure_count++; + pthread_mutex_unlock(&failure_count_lock); +} + +static void * +thread_main(void *argp) +{ + struct thread_args *args = argp; + unsigned char *signature; + unsigned int signature_len, signature_alloc_len; + int ret, i; + + signature_alloc_len = args->signature_len; + if (RSA_size(args->rsa) > signature_alloc_len) { + signature_alloc_len = RSA_size(args->rsa); + } + signature = malloc(signature_alloc_len); + if (signature == NULL) { + fprintf(stderr, "Skipping checks in thread %lu -- %s.\n", + (unsigned long) pthread_self(), strerror(errno)); + pthread_exit(0); + return NULL; + } + for (i = 0; i < ITERATION_COUNT; i++) { + signature_len = signature_alloc_len; + SIGN_LOCK(); + ret = RSA_check_key(args->rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + break; + } + ret = RSA_sign(args->digest_type, + args->digest, + args->digest_len, + signature, &signature_len, + args->rsa); + SIGN_UNLOCK(); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + break; + } + + VERIFY_LOCK(); + ret = RSA_verify(args->digest_type, + args->digest, + args->digest_len, + signature, signature_len, + args->rsa); + VERIFY_UNLOCK(); + if (ret != 1) { + fprintf(stderr, + "Signature from thread %lu(%d) fails " + "verification (passed in thread #%lu)!\n", + (long) pthread_self(), i, + (long) args->main_thread); + ERR_print_errors_fp(stdout); + failure(); + continue; + } + if (print) { + fprintf(stderr, ">%d\n", i); + } + } + free(signature); + + pthread_exit(0); + + return NULL; +} + +unsigned char * +xmemdup(unsigned char *s, size_t len) +{ + unsigned char *r; + r = malloc(len); + if (r == NULL) { + fprintf(stderr, "Out of memory.\n"); + ERR_print_errors_fp(stdout); + assert(r != NULL); + } + memcpy(r, s, len); + return r; +} + +int +main(int argc, char **argv) +{ + RSA *rsa; + MD5_CTX md5; + int fd, i; + pthread_t threads[MAX_THREAD_COUNT]; + int thread_count = 1000; + unsigned char *message, *digest; + unsigned int message_len, digest_len; + unsigned char *correct_signature; + unsigned int correct_siglen, ret; + struct thread_args master_args, *args; + int sync = 0, seed = 0; + int again = 1; +#ifdef USE_ENGINE + char *engine = NULL; + ENGINE *e = NULL; +#endif + + pthread_mutex_init(&failure_count_lock, NULL); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--seed") == 0) { + printf("Seeding PRNG.\n"); + seed++; + } else + if (strcmp(argv[i], "--sync") == 0) { + printf("Running synchronized.\n"); + sync++; + } else + if ((strcmp(argv[i], "--threads") == 0) && (i < argc - 1)) { + i++; + thread_count = atol(argv[i]); + if (thread_count > MAX_THREAD_COUNT) { + thread_count = MAX_THREAD_COUNT; + } + printf("Starting %d threads.\n", thread_count); + sync++; + } else + if (strcmp(argv[i], "--sign") == 0) { + printf("Locking signing.\n"); + locked_sign++; + } else + if (strcmp(argv[i], "--verify") == 0) { + printf("Locking verifies.\n"); + locked_verify++; + } else + if (strcmp(argv[i], "--print") == 0) { + printf("Tracing.\n"); + print++; +#ifdef USE_ENGINE + } else + if ((strcmp(argv[i], "--engine") == 0) && (i < argc - 1)) { + printf("Using engine \"%s\".\n", argv[i + 1]); + engine = argv[i + 1]; + i++; +#endif + } else { + printf("Bad argument: %s\n", argv[i]); + return 1; + } + } + + /* Get some random data to sign. */ + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) { + fprintf(stderr, "Error opening /dev/urandom: %s\n", + strerror(errno)); + } + + if (print) { + fprintf(stderr, "Reading random data.\n"); + } + message = malloc(message_len = 9371); + read(fd, message, message_len); + close(fd); + + /* Initialize the SSL library and set up thread-safe locking. */ + ERR_load_crypto_strings(); + SSL_library_init(); + mutex_locks = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks()); + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_init(&mutex_locks[i], NULL); + } + CRYPTO_set_id_callback(thread_id_cb); + CRYPTO_set_locking_callback(lock_cb); + ERR_print_errors_fp(stdout); + + /* Seed the PRNG if we were asked to do so. */ + if (seed) { + if (print) { + fprintf(stderr, "Seeding PRNG.\n"); + } + RAND_add(message, message_len, message_len); + ERR_print_errors_fp(stdout); + } + + /* Turn on a hardware crypto device if asked to do so. */ +#ifdef USE_ENGINE + if (engine) { +#if OPENSSL_VERSION_NUMBER >= 0x0090700fL + ENGINE_load_builtin_engines(); +#endif + if (print) { + fprintf(stderr, "Initializing \"%s\" engine.\n", + engine); + } + e = ENGINE_by_id(engine); + ERR_print_errors_fp(stdout); + if (e) { + i = ENGINE_init(e); + ERR_print_errors_fp(stdout); + i = ENGINE_set_default_RSA(e); + ERR_print_errors_fp(stdout); + } + } +#endif + + /* Compute the digest for the signature. */ + if (print) { + fprintf(stderr, "Computing digest.\n"); + } + digest = malloc(digest_len = MD5_DIGEST_LENGTH); + MD5_Init(&md5); + MD5_Update(&md5, message, message_len); + MD5_Final(digest, &md5); + + /* Generate a signing key. */ + if (print) { + fprintf(stderr, "Generating key.\n"); + } + rsa = RSA_generate_key(4096, 3, NULL, NULL); + ERR_print_errors_fp(stdout); + if (rsa == NULL) { + _exit(1); + } + + /* Sign the data. */ + correct_siglen = RSA_size(rsa); + correct_signature = malloc(correct_siglen); + for (i = 0; i < MAIN_COUNT; i++) { + if (print) { + fprintf(stderr, "Signing data (%d).\n", i); + } + ret = RSA_check_key(rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + failure(); + } + correct_siglen = RSA_size(rsa); + ret = RSA_sign(NID_md5, digest, digest_len, + correct_signature, &correct_siglen, + rsa); + ERR_print_errors_fp(stdout); + if (ret != 1) { + _exit(2); + } + if (print) { + fprintf(stderr, "Verifying data (%d).\n", i); + } + ret = RSA_verify(NID_md5, digest, digest_len, + correct_signature, correct_siglen, + rsa); + if (ret != 1) { + _exit(2); + } + } + + /* Collect up the inforamtion which other threads will need for + * comparing their signature results with ours. */ + master_args.rsa = rsa; + master_args.digest_type = NID_md5; + master_args.digest = digest; + master_args.digest_len = digest_len; + master_args.signature = correct_signature; + master_args.signature_len = correct_siglen; + master_args.main_thread = pthread_self(); + + fprintf(stdout, "Performing %d signatures in each of %d threads " + "(%d, %d).\n", ITERATION_COUNT, thread_count, + digest_len, correct_siglen); + fflush(NULL); + + /* Start up all of the threads. */ + for (i = 0; i < thread_count; i++) { + args = malloc(sizeof(struct thread_args)); + args->rsa = RSAPrivateKey_dup(master_args.rsa); + args->digest_type = master_args.digest_type; + args->digest_len = master_args.digest_len; + args->digest = xmemdup(master_args.digest, args->digest_len); + args->signature_len = master_args.signature_len; + args->signature = xmemdup(master_args.signature, + args->signature_len); + args->main_thread = pthread_self(); + ret = pthread_create(&threads[i], NULL, thread_main, args); + while ((ret != 0) && (errno == EAGAIN)) { + ret = pthread_create(&threads[i], NULL, + thread_main, &args); + fprintf(stderr, "Thread limit hit at %d.\n", i); + } + if (ret != 0) { + fprintf(stderr, "Unable to create thread %d: %s.\n", + i, strerror(errno)); + threads[i] = -1; + } else { + if (sync) { + ret = pthread_join(threads[i], NULL); + assert(ret == 0); + } + if (print) { + fprintf(stderr, "%d\n", i); + } + } + } + + /* Wait for all threads to complete. So long as we can find an + * unjoined thread, keep joining threads. */ + do { + again = 0; + for (i = 0; i < thread_count; i++) { + /* If we have an unterminated thread, join it. */ + if (threads[i] != -1) { + again = 1; + if (print) { + fprintf(stderr, "Joining thread %d.\n", + i); + } + pthread_join(threads[i], NULL); + threads[i] = -1; + break; + } + } + } while (again == 1); + + fprintf(stderr, "%ld failures\n", failure_count); + + return (failure_count != 0); +} diff --git a/openssl_mingw64_install_fix.patch b/openssl_mingw64_install_fix.patch new file mode 100644 index 0000000..d226f7f --- /dev/null +++ b/openssl_mingw64_install_fix.patch @@ -0,0 +1,11 @@ +--- engines/Makefile.orig 2010-05-15 21:24:54.986089920 +0200 ++++ engines/Makefile 2010-05-15 21:26:51.409085467 +0200 +@@ -111,7 +111,7 @@ + for l in $(LIBNAMES); do \ + ( echo installing $$l; \ + pfx=lib; \ +- if [ "$(PLATFORM)" = "mingw" ]; then \ ++ if [ "$(PLATFORM)" = "mingw" -o "$(PLATFORM)" = "mingw64" ]; then \ + sfx=.dll; \ + cp $$pfx$$l$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/$$pfx$$l$$sfx.new; \ + elif expr "$(PLATFORM)" : "Cygwin" >/dev/null; then \ diff --git a/opensslconf-new-warning.h b/opensslconf-new-warning.h new file mode 100644 index 0000000..de091c8 --- /dev/null +++ b/opensslconf-new-warning.h @@ -0,0 +1,7 @@ +/* Prepended at openssl package build-time. Don't include this file directly, + * use instead. */ + +#ifndef openssl_opensslconf_multilib_redirection_h +#error "Don't include this file directly, use instead!" +#endif + diff --git a/opensslconf-new.h b/opensslconf-new.h new file mode 100644 index 0000000..04363c3 --- /dev/null +++ b/opensslconf-new.h @@ -0,0 +1,47 @@ +/* This file is here to prevent a file conflict on multiarch systems. A + * conflict will frequently occur because arch-specific build-time + * configuration options are stored (and used, so they can't just be stripped + * out) in opensslconf.h. The original opensslconf.h has been renamed. + * DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */ + +#ifdef openssl_opensslconf_multilib_redirection_h +#error "Do not define openssl_opensslconf_multilib_redirection_h!" +#endif +#define openssl_opensslconf_multilib_redirection_h + +#if defined(__i386__) +#include "opensslconf-i386.h" +#elif defined(__ia64__) +#include "opensslconf-ia64.h" +#elif defined(__mips64) && defined(__MIPSEL__) +#include "opensslconf-mips64el.h" +#elif defined(__mips64) +#include "opensslconf-mips64.h" +#elif defined(__mips) && defined(__MIPSEL__) +#include "opensslconf-mipsel.h" +#elif defined(__mips) +#include "opensslconf-mips.h" +#elif defined(__powerpc64__) +#include +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#include "opensslconf-ppc64.h" +#else +#include "opensslconf-ppc64le.h" +#endif +#elif defined(__powerpc__) +#include "opensslconf-ppc.h" +#elif defined(__s390x__) +#include "opensslconf-s390x.h" +#elif defined(__s390__) +#include "opensslconf-s390.h" +#elif defined(__sparc__) && defined(__arch64__) +#include "opensslconf-sparc64.h" +#elif defined(__sparc__) +#include "opensslconf-sparc.h" +#elif defined(__x86_64__) +#include "opensslconf-x86_64.h" +#else +#error "This openssl-devel package does not work your architecture?" +#endif + +#undef openssl_opensslconf_multilib_redirection_h diff --git a/renew-dummy-cert b/renew-dummy-cert new file mode 100755 index 0000000..50f9931 --- /dev/null +++ b/renew-dummy-cert @@ -0,0 +1,42 @@ +#!/bin/bash + +if [ $# -eq 0 ]; then + echo $"Usage: `basename $0` filename" 1>&2 + exit 1 +fi + +PEM=$1 +REQ=`/bin/mktemp /tmp/openssl.XXXXXX` +KEY=`/bin/mktemp /tmp/openssl.XXXXXX` +CRT=`/bin/mktemp /tmp/openssl.XXXXXX` +NEW=${PEM}_ + +trap "rm -f $REQ $KEY $CRT $NEW" SIGINT + +if [ ! -f $PEM ]; then + echo "$PEM: file not found" 1>&2 + exit 1 +fi + +let -a SERIAL=0x$(openssl x509 -in $PEM -noout -serial | cut -d= -f2) +let SERIAL++ + +umask 077 + +OWNER=`ls -l $PEM | awk '{ printf "%s.%s", $3, $4; }'` + +openssl rsa -inform pem -in $PEM -out $KEY +openssl x509 -x509toreq -in $PEM -signkey $KEY -out $REQ +openssl x509 -req -in $REQ -signkey $KEY -set_serial $SERIAL -days 365 \ + -extfile /etc/pki/tls/openssl.cnf -extensions v3_ca -out $CRT + +(cat $KEY ; echo "" ; cat $CRT) > $NEW + +chown $OWNER $NEW + +mv -f $NEW $PEM + +rm -f $REQ $KEY $CRT + +exit 0 + diff --git a/sources b/sources new file mode 100644 index 0000000..e752fef --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (openssl-1.0.2k-hobbled.tar.xz) = f702b9a18f4500f0263e0c1fc09985a8caf72c8bcb744b8d3683a49ec889120b1b595db42f2a66cae722312736b09236a0911548590d318382a2981f35fed533