diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01ff985 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/openssl-1.0.2k-hobbled.tar.xz diff --git a/.openssl.metadata b/.openssl.metadata new file mode 100644 index 0000000..d7cb582 --- /dev/null +++ b/.openssl.metadata @@ -0,0 +1 @@ +06ae179d01fcde6a4594bf4023f863290a7f050c SOURCES/openssl-1.0.2k-hobbled.tar.xz diff --git a/SOURCES/Makefile.certificate b/SOURCES/Makefile.certificate new file mode 100644 index 0000000..cc88c52 --- /dev/null +++ b/SOURCES/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/SOURCES/README.FIPS b/SOURCES/README.FIPS new file mode 100644 index 0000000..bf3229b --- /dev/null +++ b/SOURCES/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/SOURCES/README.legacy-settings b/SOURCES/README.legacy-settings new file mode 100644 index 0000000..cf7068e --- /dev/null +++ b/SOURCES/README.legacy-settings @@ -0,0 +1,53 @@ +Guide for legacy support enablement +=================================== + +To improve security provided by use of OpenSSL especially in context of +TLS connections we regularly review and deprecate algorithms and algorithm +settings which are no longer viewed as secure. + +For some of these deprecated algorithms we provide a way for the +system administrator to reenable them. + +Deprecated algorithms, protocols and settings in OpenSSL +======================================================== + +Previous Red Hat Enterprise Linux 7 update releases: + +* SSL2 protocol disabled by default. +* Minimum DH group size accepted by SSL/TLS client 768 bits. +* Verification of certificates and signatures using MD5 hash + disabled. + +Red Hat Enterprise Linux 7.4: + +* SSL2 protocol support completely disabled (cannot be re-enabled). +* All SSL/TLS export ciphers disabled. +* All SSL/TLS ciphersuites with keys smaller than 128 bits disabled. +* Minimum DH group size accepted by SSL/TLS client 1024 bits. +* Disabled support for verification of certificates and signatures + using MD2, MD4, MD5, and SHA0 hashes. + +Legacy support enablement +========================= + +The OpenSSL now supports /etc/pki/tls/legacy-settings configuration file +which can be created by the system administrator which contains lines with +simple Key Value pairs. + +The library recognizes the following possible configuration settings in +that file: + +LegacySigningMDs md2 md5 +MinimumDHBits 512 + +The LegacySigningMDs option allows reenabling support for verification of +signatures with the specified hash algorithms. These can be any combination +of md2, md4, md5 and sha. (sha represents SHA0 algorithm, not SHA1.) Any +unrecognized algorithms are ignored. + +The MinimumDHBits option allows setting of the minimum bit size of DH group +accepted by SSL/TLS client. It can be any value between 512 and 10000. + +If the configuration file is not present the built-in defaults (that is the +secure defaults) are used. Any unrecognized lines (with other parameter +names or comments) are ignored. diff --git a/SOURCES/ec_curve.c b/SOURCES/ec_curve.c new file mode 100644 index 0000000..ea3a479 --- /dev/null +++ b/SOURCES/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/SOURCES/ectest.c b/SOURCES/ectest.c new file mode 100644 index 0000000..701e706 --- /dev/null +++ b/SOURCES/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/SOURCES/hobble-openssl b/SOURCES/hobble-openssl new file mode 100755 index 0000000..8750ad6 --- /dev/null +++ b/SOURCES/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/SOURCES/make-dummy-cert b/SOURCES/make-dummy-cert new file mode 100755 index 0000000..f5f0453 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.0-beta4-ca-dir.patch b/SOURCES/openssl-1.0.0-beta4-ca-dir.patch new file mode 100644 index 0000000..751cabd --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.0-timezone.patch b/SOURCES/openssl-1.0.0-timezone.patch new file mode 100644 index 0000000..b1d6682 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.1c-aliasing.patch b/SOURCES/openssl-1.0.1c-aliasing.patch new file mode 100644 index 0000000..582418c --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.1c-perlfind.patch b/SOURCES/openssl-1.0.1c-perlfind.patch new file mode 100644 index 0000000..956afd6 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.1i-algo-doc.patch b/SOURCES/openssl-1.0.1i-algo-doc.patch new file mode 100644 index 0000000..a19877d --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-apps-dgst.patch b/SOURCES/openssl-1.0.2a-apps-dgst.patch new file mode 100644 index 0000000..2bb8327 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-compat-symbols.patch b/SOURCES/openssl-1.0.2a-compat-symbols.patch new file mode 100644 index 0000000..1e0993e --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-defaults.patch b/SOURCES/openssl-1.0.2a-defaults.patch new file mode 100644 index 0000000..315a9b0 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-dtls1-abi.patch b/SOURCES/openssl-1.0.2a-dtls1-abi.patch new file mode 100644 index 0000000..a6a79d7 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-env-zlib.patch b/SOURCES/openssl-1.0.2a-env-zlib.patch new file mode 100644 index 0000000..328079b --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-fips-ctor.patch b/SOURCES/openssl-1.0.2a-fips-ctor.patch new file mode 100644 index 0000000..65f652c --- /dev/null +++ b/SOURCES/openssl-1.0.2a-fips-ctor.patch @@ -0,0 +1,174 @@ +diff -up openssl-1.0.2a/crypto/fips/fips.c.fips-ctor openssl-1.0.2a/crypto/fips/fips.c +--- openssl-1.0.2a/crypto/fips/fips.c.fips-ctor 2015-04-21 17:42:18.702765856 +0200 ++++ openssl-1.0.2a/crypto/fips/fips.c 2015-04-21 17:42:18.742766794 +0200 +@@ -60,6 +60,8 @@ + #include + #include + #include ++#include ++#include + #include "fips_locl.h" + + #ifdef OPENSSL_FIPS +@@ -201,7 +203,9 @@ static char *bin2hex(void *buf, size_t l + } + + # define HMAC_PREFIX "." +-# define HMAC_SUFFIX ".hmac" ++# ifndef HMAC_SUFFIX ++# define HMAC_SUFFIX ".hmac" ++# endif + # define READ_BUFFER_LENGTH 16384 + + static char *make_hmac_path(const char *origpath) +@@ -279,20 +283,14 @@ static int compute_file_hmac(const char + return rv; + } + +-static int FIPSCHECK_verify(const char *libname, const char *symbolname) ++static int FIPSCHECK_verify(const char *path) + { +- char path[PATH_MAX + 1]; +- int rv; ++ int rv = 0; + 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; +@@ -343,6 +341,51 @@ static int FIPSCHECK_verify(const char * + return 1; + } + ++static int verify_checksums(void) ++{ ++ int rv; ++ char path[PATH_MAX + 1]; ++ char *p; ++ ++ /* we need to avoid dlopening libssl, assume both libcrypto and libssl ++ are in the same directory */ ++ ++ rv = get_library_path("libcrypto.so." SHLIB_VERSION_NUMBER, ++ "FIPS_mode_set", path, sizeof(path)); ++ if (rv < 0) ++ return 0; ++ ++ rv = FIPSCHECK_verify(path); ++ if (!rv) ++ return 0; ++ ++ /* replace libcrypto with libssl */ ++ while ((p = strstr(path, "libcrypto.so")) != NULL) { ++ p = stpcpy(p, "libssl"); ++ memmove(p, p + 3, strlen(p + 2)); ++ } ++ ++ rv = FIPSCHECK_verify(path); ++ if (!rv) ++ return 0; ++ return 1; ++} ++ ++# ifndef FIPS_MODULE_PATH ++# define FIPS_MODULE_PATH "/etc/system-fips" ++# endif ++ ++int FIPS_module_installed(void) ++{ ++ int rv; ++ rv = access(FIPS_MODULE_PATH, F_OK); ++ if (rv < 0 && errno != ENOENT) ++ rv = 0; ++ ++ /* Installed == true */ ++ return !rv; ++} ++ + int FIPS_module_mode_set(int onoff, const char *auth) + { + int ret = 0; +@@ -380,17 +423,7 @@ int FIPS_module_mode_set(int onoff, cons + } + # 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")) { ++ if (!verify_checksums()) { + FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, + FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; +diff -up openssl-1.0.2a/crypto/fips/fips.h.fips-ctor openssl-1.0.2a/crypto/fips/fips.h +--- openssl-1.0.2a/crypto/fips/fips.h.fips-ctor 2015-04-21 17:42:18.739766724 +0200 ++++ openssl-1.0.2a/crypto/fips/fips.h 2015-04-21 17:42:18.743766818 +0200 +@@ -74,6 +74,7 @@ extern "C" { + + int FIPS_module_mode_set(int onoff, const char *auth); + int FIPS_module_mode(void); ++ int FIPS_module_installed(void); + const void *FIPS_rand_check(void); + int FIPS_selftest(void); + int FIPS_selftest_failed(void); +diff -up openssl-1.0.2a/crypto/o_init.c.fips-ctor openssl-1.0.2a/crypto/o_init.c +--- openssl-1.0.2a/crypto/o_init.c.fips-ctor 2015-04-21 17:42:18.732766559 +0200 ++++ openssl-1.0.2a/crypto/o_init.c 2015-04-21 17:45:02.662613173 +0200 +@@ -74,6 +74,9 @@ static void init_fips_mode(void) + char buf[2] = "0"; + int fd; + ++ /* Ensure the selftests always run */ ++ FIPS_mode_set(1); ++ + if (secure_getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) { + buf[0] = '1'; + } else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) { +@@ -85,8 +88,12 @@ static void init_fips_mode(void) + * otherwise.. + */ + +- if (buf[0] == '1') { +- FIPS_mode_set(1); ++ if (buf[0] != '1') { ++ /* drop down to non-FIPS mode if it is not requested */ ++ FIPS_mode_set(0); ++ } else { ++ /* abort if selftest failed */ ++ FIPS_selftest_check(); + } + } + #endif +@@ -96,13 +103,16 @@ static void init_fips_mode(void) + * sets FIPS callbacks + */ + +-void OPENSSL_init_library(void) ++void __attribute__ ((constructor)) OPENSSL_init_library(void) + { + static int done = 0; + if (done) + return; + done = 1; + #ifdef OPENSSL_FIPS ++ if (!FIPS_module_installed()) { ++ return; ++ } + RAND_init_fips(); + init_fips_mode(); + if (!FIPS_mode()) { diff --git a/SOURCES/openssl-1.0.2a-fips-ec.patch b/SOURCES/openssl-1.0.2a-fips-ec.patch new file mode 100644 index 0000000..e42f4a1 --- /dev/null +++ b/SOURCES/openssl-1.0.2a-fips-ec.patch @@ -0,0 +1,1929 @@ +diff -up openssl-1.0.2a/crypto/ecdh/ecdhtest.c.fips-ec openssl-1.0.2a/crypto/ecdh/ecdhtest.c +--- openssl-1.0.2a/crypto/ecdh/ecdhtest.c.fips-ec 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/crypto/ecdh/ecdhtest.c 2015-04-22 19:00:19.721884512 +0200 +@@ -501,11 +501,13 @@ int main(int argc, char *argv[]) + goto err; + + /* NIST PRIME CURVES TESTS */ ++# if 0 + if (!test_ecdh_curve + (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) + goto err; ++# endif + if (!test_ecdh_curve + (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) + goto err; +@@ -536,13 +538,14 @@ int main(int argc, char *argv[]) + if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) + goto err; + # endif ++# if 0 + if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP256r1", 256)) + goto err; + if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP384r1", 384)) + goto err; + if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP512r1", 512)) + goto err; +- ++# endif + ret = 0; + + err: +diff -up openssl-1.0.2a/crypto/ecdh/ech_lib.c.fips-ec openssl-1.0.2a/crypto/ecdh/ech_lib.c +--- openssl-1.0.2a/crypto/ecdh/ech_lib.c.fips-ec 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/crypto/ecdh/ech_lib.c 2015-04-22 19:00:19.721884512 +0200 +@@ -93,14 +93,7 @@ void ECDH_set_default_method(const ECDH_ + const ECDH_METHOD *ECDH_get_default_method(void) + { + if (!default_ECDH_method) { +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ecdh_openssl(); +- else +- return ECDH_OpenSSL(); +-#else + default_ECDH_method = ECDH_OpenSSL(); +-#endif + } + return default_ECDH_method; + } +diff -up openssl-1.0.2a/crypto/ecdh/ech_ossl.c.fips-ec openssl-1.0.2a/crypto/ecdh/ech_ossl.c +--- openssl-1.0.2a/crypto/ecdh/ech_ossl.c.fips-ec 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/crypto/ecdh/ech_ossl.c 2015-04-22 19:00:19.722884536 +0200 +@@ -78,6 +78,10 @@ + #include + #include + ++#ifdef OPENSSL_FIPS ++# include ++#endif ++ + static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, +@@ -90,7 +94,7 @@ static ECDH_METHOD openssl_ecdh_meth = { + NULL, /* init */ + NULL, /* finish */ + #endif +- 0, /* flags */ ++ ECDH_FLAG_FIPS_METHOD, /* flags */ + NULL /* app_data */ + }; + +@@ -119,6 +123,13 @@ static int ecdh_compute_key(void *out, s + size_t buflen, len; + unsigned char *buf = NULL; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_ECDH_COMPUTE_KEY, FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++#endif ++ + if (outlen > INT_MAX) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); /* sort of, + * anyway */ +diff -up openssl-1.0.2a/crypto/ecdsa/ecdsatest.c.fips-ec openssl-1.0.2a/crypto/ecdsa/ecdsatest.c +--- openssl-1.0.2a/crypto/ecdsa/ecdsatest.c.fips-ec 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/crypto/ecdsa/ecdsatest.c 2015-04-22 19:00:19.722884536 +0200 +@@ -138,11 +138,14 @@ int restore_rand(void) + } + + static int fbytes_counter = 0; +-static const char *numbers[8] = { ++static const char *numbers[10] = { ++ "651056770906015076056810763456358567190100156695615665659", + "651056770906015076056810763456358567190100156695615665659", + "6140507067065001063065065565667405560006161556565665656654", + "8763001015071075675010661307616710783570106710677817767166" + "71676178726717", ++ "8763001015071075675010661307616710783570106710677817767166" ++ "71676178726717", + "7000000175690566466555057817571571075705015757757057795755" + "55657156756655", + "1275552191113212300012030439187146164646146646466749494799", +@@ -158,7 +161,7 @@ int fbytes(unsigned char *buf, int num) + int ret; + BIGNUM *tmp = NULL; + +- if (fbytes_counter >= 8) ++ if (fbytes_counter >= 10) + return 0; + tmp = BN_new(); + if (!tmp) +@@ -532,8 +535,10 @@ int main(void) + RAND_seed(rnd_seed, sizeof(rnd_seed)); + + /* the tests */ ++# if 0 + if (!x9_62_tests(out)) + goto err; ++# endif + if (!test_builtin(out)) + goto err; + +diff -up openssl-1.0.2a/crypto/ecdsa/ecs_lib.c.fips-ec openssl-1.0.2a/crypto/ecdsa/ecs_lib.c +--- openssl-1.0.2a/crypto/ecdsa/ecs_lib.c.fips-ec 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/crypto/ecdsa/ecs_lib.c 2015-04-22 19:00:19.722884536 +0200 +@@ -80,14 +80,7 @@ void ECDSA_set_default_method(const ECDS + const ECDSA_METHOD *ECDSA_get_default_method(void) + { + if (!default_ECDSA_method) { +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ecdsa_openssl(); +- else +- return ECDSA_OpenSSL(); +-#else + default_ECDSA_method = ECDSA_OpenSSL(); +-#endif + } + return default_ECDSA_method; + } +diff -up openssl-1.0.2a/crypto/ecdsa/ecs_ossl.c.fips-ec openssl-1.0.2a/crypto/ecdsa/ecs_ossl.c +--- openssl-1.0.2a/crypto/ecdsa/ecs_ossl.c.fips-ec 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/crypto/ecdsa/ecs_ossl.c 2015-04-22 19:00:19.722884536 +0200 +@@ -60,6 +60,9 @@ + #include + #include + #include ++#ifdef OPENSSL_FIPS ++# include ++#endif + + static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + const BIGNUM *, const BIGNUM *, +@@ -78,7 +81,7 @@ static ECDSA_METHOD openssl_ecdsa_meth = + NULL, /* init */ + NULL, /* finish */ + #endif +- 0, /* flags */ ++ ECDSA_FLAG_FIPS_METHOD, /* flags */ + NULL /* app_data */ + }; + +@@ -245,6 +248,13 @@ static ECDSA_SIG *ecdsa_do_sign(const un + ECDSA_DATA *ecdsa; + const BIGNUM *priv_key; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_ECDSA_DO_SIGN, FIPS_R_FIPS_SELFTEST_FAILED); ++ return NULL; ++ } ++#endif ++ + ecdsa = ecdsa_check(eckey); + group = EC_KEY_get0_group(eckey); + priv_key = EC_KEY_get0_private_key(eckey); +@@ -358,6 +368,13 @@ static int ecdsa_do_verify(const unsigne + const EC_GROUP *group; + const EC_POINT *pub_key; + ++#ifdef OPENSSL_FIPS ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_ECDSA_DO_VERIFY, FIPS_R_FIPS_SELFTEST_FAILED); ++ return -1; ++ } ++#endif ++ + /* check input values */ + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || + (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { +diff -up openssl-1.0.2a/crypto/ec/ec_cvt.c.fips-ec openssl-1.0.2a/crypto/ec/ec_cvt.c +--- openssl-1.0.2a/crypto/ec/ec_cvt.c.fips-ec 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/crypto/ec/ec_cvt.c 2015-04-22 19:01:08.703040756 +0200 +@@ -82,10 +82,6 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const B + const EC_METHOD *meth; + EC_GROUP *ret; + +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ec_group_new_curve_gfp(p, a, b, ctx); +-#endif + #if defined(OPENSSL_BN_ASM_MONT) + /* + * This might appear controversial, but the fact is that generic +@@ -160,10 +156,6 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const + const EC_METHOD *meth; + EC_GROUP *ret; + +-# ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ec_group_new_curve_gf2m(p, a, b, ctx); +-# endif + meth = EC_GF2m_simple_method(); + + ret = EC_GROUP_new(meth); +diff -up openssl-1.0.2a/crypto/ec/ec_key.c.fips-ec openssl-1.0.2a/crypto/ec/ec_key.c +--- openssl-1.0.2a/crypto/ec/ec_key.c.fips-ec 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/crypto/ec/ec_key.c 2015-04-22 19:00:19.722884536 +0200 +@@ -64,9 +64,6 @@ + #include + #include "ec_lcl.h" + #include +-#ifdef OPENSSL_FIPS +-# include +-#endif + + EC_KEY *EC_KEY_new(void) + { +@@ -227,6 +224,38 @@ int EC_KEY_up_ref(EC_KEY *r) + return ((i > 1) ? 1 : 0); + } + ++#ifdef OPENSSL_FIPS ++ ++# include ++# include ++# include ++ ++static int fips_check_ec(EC_KEY *key) ++{ ++ EVP_PKEY *pk; ++ unsigned char tbs[] = "ECDSA Pairwise Check Data"; ++ int ret = 0; ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_set1_EC_KEY(pk, key); ++ ++ if (fips_pkey_signature_test(pk, tbs, -1, NULL, 0, NULL, 0, NULL)) ++ ret = 1; ++ ++ err: ++ if (ret == 0) { ++ FIPSerr(FIPS_F_FIPS_CHECK_EC, FIPS_R_PAIRWISE_TEST_FAILED); ++ fips_set_selftest_fail(); ++ } ++ if (pk) ++ EVP_PKEY_free(pk); ++ return ret; ++} ++ ++#endif ++ + int EC_KEY_generate_key(EC_KEY *eckey) + { + int ok = 0; +@@ -235,8 +264,10 @@ int EC_KEY_generate_key(EC_KEY *eckey) + EC_POINT *pub_key = NULL; + + #ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_ec_key_generate_key(eckey); ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_EC_KEY_GENERATE_KEY, FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } + #endif + + if (!eckey || !eckey->group) { +@@ -277,6 +308,14 @@ int EC_KEY_generate_key(EC_KEY *eckey) + eckey->priv_key = priv_key; + eckey->pub_key = pub_key; + ++#ifdef OPENSSL_FIPS ++ if (!fips_check_ec(eckey)) { ++ eckey->priv_key = NULL; ++ eckey->pub_key = NULL; ++ goto err; ++ } ++#endif ++ + ok = 1; + + err: +@@ -408,10 +447,12 @@ int EC_KEY_set_public_key_affine_coordin + goto err; + } + /* +- * Check if retrieved coordinates match originals: if not values are out +- * of range. ++ * Check if retrieved coordinates match originals and are less ++ * than field order: if not values are out of range. + */ +- if (BN_cmp(x, tx) || BN_cmp(y, ty)) { ++ if (BN_cmp(x, tx) || BN_cmp(y, ty) ++ || (BN_cmp(x, &key->group->field) >= 0) ++ || (BN_cmp(y, &key->group->field) >= 0)) { + ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, + EC_R_COORDINATES_OUT_OF_RANGE); + goto err; +diff -up openssl-1.0.2a/crypto/ec/ecp_mont.c.fips-ec openssl-1.0.2a/crypto/ec/ecp_mont.c +--- openssl-1.0.2a/crypto/ec/ecp_mont.c.fips-ec 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/crypto/ec/ecp_mont.c 2015-04-22 19:00:19.722884536 +0200 +@@ -63,10 +63,6 @@ + + #include + +-#ifdef OPENSSL_FIPS +-# include +-#endif +- + #include "ec_lcl.h" + + const EC_METHOD *EC_GFp_mont_method(void) +@@ -111,11 +107,6 @@ const EC_METHOD *EC_GFp_mont_method(void + ec_GFp_mont_field_set_to_one + }; + +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return fips_ec_gfp_mont_method(); +-#endif +- + return &ret; + } + +diff -up openssl-1.0.2a/crypto/ec/ecp_nist.c.fips-ec openssl-1.0.2a/crypto/ec/ecp_nist.c +--- openssl-1.0.2a/crypto/ec/ecp_nist.c.fips-ec 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/crypto/ec/ecp_nist.c 2015-04-22 19:00:19.723884560 +0200 +@@ -67,10 +67,6 @@ + #include + #include "ec_lcl.h" + +-#ifdef OPENSSL_FIPS +-# include +-#endif +- + const EC_METHOD *EC_GFp_nist_method(void) + { + static const EC_METHOD ret = { +@@ -113,11 +109,6 @@ const EC_METHOD *EC_GFp_nist_method(void + 0 /* field_set_to_one */ + }; + +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return fips_ec_gfp_nist_method(); +-#endif +- + return &ret; + } + +diff -up openssl-1.0.2a/crypto/ec/ecp_smpl.c.fips-ec openssl-1.0.2a/crypto/ec/ecp_smpl.c +--- openssl-1.0.2a/crypto/ec/ecp_smpl.c.fips-ec 2015-03-19 14:19:00.000000000 +0100 ++++ openssl-1.0.2a/crypto/ec/ecp_smpl.c 2015-04-22 19:00:19.723884560 +0200 +@@ -66,10 +66,6 @@ + #include + #include + +-#ifdef OPENSSL_FIPS +-# include +-#endif +- + #include "ec_lcl.h" + + const EC_METHOD *EC_GFp_simple_method(void) +@@ -114,11 +110,6 @@ const EC_METHOD *EC_GFp_simple_method(vo + 0 /* field_set_to_one */ + }; + +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return fips_ec_gfp_simple_method(); +-#endif +- + return &ret; + } + +@@ -187,6 +178,11 @@ int ec_GFp_simple_group_set_curve(EC_GRO + return 0; + } + ++ if (BN_num_bits(p) < 256) { ++ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); ++ return 0; ++ } ++ + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) +diff -up openssl-1.0.2a/crypto/evp/m_ecdsa.c.fips-ec openssl-1.0.2a/crypto/evp/m_ecdsa.c +--- openssl-1.0.2a/crypto/evp/m_ecdsa.c.fips-ec 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/crypto/evp/m_ecdsa.c 2015-04-22 19:00:19.723884560 +0200 +@@ -136,7 +136,7 @@ static const EVP_MD ecdsa_md = { + NID_ecdsa_with_SHA1, + NID_ecdsa_with_SHA1, + 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.2a/crypto/fips/cavs/fips_ecdhvs.c.fips-ec openssl-1.0.2a/crypto/fips/cavs/fips_ecdhvs.c +--- openssl-1.0.2a/crypto/fips/cavs/fips_ecdhvs.c.fips-ec 2015-04-22 19:00:19.723884560 +0200 ++++ openssl-1.0.2a/crypto/fips/cavs/fips_ecdhvs.c 2015-04-22 19:00:19.723884560 +0200 +@@ -0,0 +1,456 @@ ++/* fips/ecdh/fips_ecdhvs.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#define OPENSSL_FIPSAPI ++#include ++ ++#ifndef OPENSSL_FIPS ++# include ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS ECDH support\n"); ++ return (0); ++} ++#else ++ ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++ ++# include "fips_utl.h" ++ ++static const EVP_MD *eparse_md(char *line) ++{ ++ char *p; ++ if (line[0] != '[' || line[1] != 'E') ++ return NULL; ++ p = strchr(line, '-'); ++ if (!p) ++ return NULL; ++ line = p + 1; ++ p = strchr(line, ']'); ++ if (!p) ++ return NULL; ++ *p = 0; ++ p = line; ++ while (isspace(*p)) ++ p++; ++ if (!strcmp(p, "SHA1")) ++ return EVP_sha1(); ++ else if (!strcmp(p, "SHA224")) ++ return EVP_sha224(); ++ else if (!strcmp(p, "SHA256")) ++ return EVP_sha256(); ++ else if (!strcmp(p, "SHA384")) ++ return EVP_sha384(); ++ else if (!strcmp(p, "SHA512")) ++ return EVP_sha512(); ++ else ++ return NULL; ++} ++ ++static int lookup_curve2(char *cname) ++{ ++ char *p; ++ p = strchr(cname, ']'); ++ if (!p) { ++ fprintf(stderr, "Parse error: missing ]\n"); ++ return NID_undef; ++ } ++ *p = 0; ++ ++ if (!strcmp(cname, "B-163")) ++ return NID_sect163r2; ++ if (!strcmp(cname, "B-233")) ++ return NID_sect233r1; ++ if (!strcmp(cname, "B-283")) ++ return NID_sect283r1; ++ if (!strcmp(cname, "B-409")) ++ return NID_sect409r1; ++ if (!strcmp(cname, "B-571")) ++ return NID_sect571r1; ++ if (!strcmp(cname, "K-163")) ++ return NID_sect163k1; ++ if (!strcmp(cname, "K-233")) ++ return NID_sect233k1; ++ if (!strcmp(cname, "K-283")) ++ return NID_sect283k1; ++ if (!strcmp(cname, "K-409")) ++ return NID_sect409k1; ++ if (!strcmp(cname, "K-571")) ++ return NID_sect571k1; ++ if (!strcmp(cname, "P-192")) ++ return NID_X9_62_prime192v1; ++ if (!strcmp(cname, "P-224")) ++ return NID_secp224r1; ++ if (!strcmp(cname, "P-256")) ++ return NID_X9_62_prime256v1; ++ if (!strcmp(cname, "P-384")) ++ return NID_secp384r1; ++ if (!strcmp(cname, "P-521")) ++ return NID_secp521r1; ++ ++ fprintf(stderr, "Unknown Curve name %s\n", cname); ++ return NID_undef; ++} ++ ++static int lookup_curve(char *cname) ++{ ++ char *p; ++ p = strchr(cname, ':'); ++ if (!p) { ++ fprintf(stderr, "Parse error: missing :\n"); ++ return NID_undef; ++ } ++ cname = p + 1; ++ while (isspace(*cname)) ++ cname++; ++ return lookup_curve2(cname); ++} ++ ++static EC_POINT *make_peer(EC_GROUP *group, BIGNUM *x, BIGNUM *y) ++{ ++ EC_POINT *peer; ++ int rv; ++ BN_CTX *c; ++ peer = EC_POINT_new(group); ++ if (!peer) ++ return NULL; ++ c = BN_CTX_new(); ++ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ++ == NID_X9_62_prime_field) ++ rv = EC_POINT_set_affine_coordinates_GFp(group, peer, x, y, c); ++ else ++# ifdef OPENSSL_NO_EC2M ++ { ++ fprintf(stderr, "ERROR: GF2m not supported\n"); ++ exit(1); ++ } ++# else ++ rv = EC_POINT_set_affine_coordinates_GF2m(group, peer, x, y, c); ++# endif ++ ++ BN_CTX_free(c); ++ if (rv) ++ return peer; ++ EC_POINT_free(peer); ++ return NULL; ++} ++ ++static int ec_print_key(FILE *out, EC_KEY *key, int add_e, int exout) ++{ ++ const EC_POINT *pt; ++ const EC_GROUP *grp; ++ const EC_METHOD *meth; ++ int rv; ++ BIGNUM *tx, *ty; ++ const BIGNUM *d = NULL; ++ BN_CTX *ctx; ++ ctx = BN_CTX_new(); ++ if (!ctx) ++ return 0; ++ tx = BN_CTX_get(ctx); ++ ty = BN_CTX_get(ctx); ++ if (!tx || !ty) ++ return 0; ++ grp = EC_KEY_get0_group(key); ++ pt = EC_KEY_get0_public_key(key); ++ if (exout) ++ d = EC_KEY_get0_private_key(key); ++ meth = EC_GROUP_method_of(grp); ++ if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) ++ rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, tx, ty, ctx); ++ else ++# ifdef OPENSSL_NO_EC2M ++ { ++ fprintf(stderr, "ERROR: GF2m not supported\n"); ++ exit(1); ++ } ++# else ++ rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, tx, ty, ctx); ++# endif ++ ++ if (add_e) { ++ do_bn_print_name(out, "QeIUTx", tx); ++ do_bn_print_name(out, "QeIUTy", ty); ++ if (d) ++ do_bn_print_name(out, "QeIUTd", d); ++ } else { ++ do_bn_print_name(out, "QIUTx", tx); ++ do_bn_print_name(out, "QIUTy", ty); ++ if (d) ++ do_bn_print_name(out, "QIUTd", d); ++ } ++ ++ BN_CTX_free(ctx); ++ ++ return rv; ++ ++} ++ ++static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group, ++ BIGNUM *ix, BIGNUM *iy, BIGNUM *id, BIGNUM *cx, ++ BIGNUM *cy, const EVP_MD *md, ++ unsigned char *rhash, size_t rhashlen) ++{ ++ EC_KEY *ec = NULL; ++ EC_POINT *peerkey = NULL; ++ unsigned char *Z; ++ unsigned char chash[EVP_MAX_MD_SIZE]; ++ int Zlen; ++ ec = EC_KEY_new(); ++ EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH); ++ EC_KEY_set_group(ec, group); ++ peerkey = make_peer(group, cx, cy); ++ if (rhash == NULL) { ++ if (md) ++ rhashlen = M_EVP_MD_size(md); ++ EC_KEY_generate_key(ec); ++ ec_print_key(out, ec, md ? 1 : 0, exout); ++ } else { ++ EC_KEY_set_public_key_affine_coordinates(ec, ix, iy); ++ EC_KEY_set_private_key(ec, id); ++ } ++ Zlen = (EC_GROUP_get_degree(group) + 7) / 8; ++ Z = OPENSSL_malloc(Zlen); ++ if (!Z) ++ exit(1); ++ ECDH_compute_key(Z, Zlen, peerkey, ec, 0); ++ if (md) { ++ if (exout) ++ OutputValue("Z", Z, Zlen, out, 0); ++ FIPS_digest(Z, Zlen, chash, NULL, md); ++ OutputValue(rhash ? "IUTHashZZ" : "HashZZ", chash, rhashlen, out, 0); ++ if (rhash) { ++ fprintf(out, "Result = %s\n", ++ memcmp(chash, rhash, rhashlen) ? "F" : "P"); ++ } ++ } else ++ OutputValue("ZIUT", Z, Zlen, out, 0); ++ OPENSSL_cleanse(Z, Zlen); ++ OPENSSL_free(Z); ++ EC_KEY_free(ec); ++ EC_POINT_free(peerkey); ++} ++ ++# ifdef FIPS_ALGVS ++int fips_ecdhvs_main(int argc, char **argv) ++# else ++int main(int argc, char **argv) ++# endif ++{ ++ char **args = argv + 1; ++ int argn = argc - 1; ++ FILE *in, *out; ++ char buf[2048], lbuf[2048]; ++ unsigned char *rhash = NULL; ++ long rhashlen; ++ BIGNUM *cx = NULL, *cy = NULL; ++ BIGNUM *id = NULL, *ix = NULL, *iy = NULL; ++ const EVP_MD *md = NULL; ++ EC_GROUP *group = NULL; ++ char *keyword = NULL, *value = NULL; ++ int do_verify = -1, exout = 0; ++ int rv = 1; ++ ++ int curve_nids[5] = { 0, 0, 0, 0, 0 }; ++ int param_set = -1; ++ ++ fips_algtest_init(); ++ ++ if (argn && !strcmp(*args, "ecdhver")) { ++ do_verify = 1; ++ args++; ++ argn--; ++ } else if (argn && !strcmp(*args, "ecdhgen")) { ++ do_verify = 0; ++ args++; ++ argn--; ++ } ++ ++ if (argn && !strcmp(*args, "-exout")) { ++ exout = 1; ++ args++; ++ argn--; ++ } ++ ++ if (do_verify == -1) { ++ fprintf(stderr, "%s [ecdhver|ecdhgen|] [-exout] (infile outfile)\n", ++ argv[0]); ++ exit(1); ++ } ++ ++ if (argn == 2) { ++ in = fopen(*args, "r"); ++ if (!in) { ++ fprintf(stderr, "Error opening input file\n"); ++ exit(1); ++ } ++ out = fopen(args[1], "w"); ++ if (!out) { ++ fprintf(stderr, "Error opening output file\n"); ++ exit(1); ++ } ++ } else if (argn == 0) { ++ in = stdin; ++ out = stdout; ++ } else { ++ fprintf(stderr, "%s [dhver|dhgen|] [-exout] (infile outfile)\n", ++ argv[0]); ++ exit(1); ++ } ++ ++ while (fgets(buf, sizeof(buf), in) != NULL) { ++ fputs(buf, out); ++ if (buf[0] == '[' && buf[1] == 'E') { ++ int c = buf[2]; ++ if (c < 'A' || c > 'E') ++ goto parse_error; ++ param_set = c - 'A'; ++ /* If just [E?] then initial paramset */ ++ if (buf[3] == ']') ++ continue; ++ if (group) ++ EC_GROUP_free(group); ++ group = EC_GROUP_new_by_curve_name(curve_nids[c - 'A']); ++ } ++ if (strlen(buf) > 10 && !strncmp(buf, "[Curve", 6)) { ++ int nid; ++ if (param_set == -1) ++ goto parse_error; ++ nid = lookup_curve(buf); ++ if (nid == NID_undef) ++ goto parse_error; ++ curve_nids[param_set] = nid; ++ } ++ ++ if (strlen(buf) > 4 && buf[0] == '[' && buf[2] == '-') { ++ int nid = lookup_curve2(buf + 1); ++ if (nid == NID_undef) ++ goto parse_error; ++ if (group) ++ EC_GROUP_free(group); ++ group = EC_GROUP_new_by_curve_name(nid); ++ if (!group) { ++ fprintf(stderr, "ERROR: unsupported curve %s\n", buf + 1); ++ return 1; ++ } ++ } ++ ++ if (strlen(buf) > 6 && !strncmp(buf, "[E", 2)) { ++ md = eparse_md(buf); ++ if (md == NULL) ++ goto parse_error; ++ continue; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "QeCAVSx") || !strcmp(keyword, "QCAVSx")) { ++ if (!do_hex2bn(&cx, value)) ++ goto parse_error; ++ } else if (!strcmp(keyword, "QeCAVSy") || !strcmp(keyword, "QCAVSy")) { ++ if (!do_hex2bn(&cy, value)) ++ goto parse_error; ++ if (do_verify == 0) ++ ec_output_Zhash(out, exout, group, ++ NULL, NULL, NULL, ++ cx, cy, md, rhash, rhashlen); ++ } else if (!strcmp(keyword, "deIUT")) { ++ if (!do_hex2bn(&id, value)) ++ goto parse_error; ++ } else if (!strcmp(keyword, "QeIUTx")) { ++ if (!do_hex2bn(&ix, value)) ++ goto parse_error; ++ } else if (!strcmp(keyword, "QeIUTy")) { ++ if (!do_hex2bn(&iy, value)) ++ goto parse_error; ++ } else if (!strcmp(keyword, "CAVSHashZZ")) { ++ if (!md) ++ goto parse_error; ++ rhash = hex2bin_m(value, &rhashlen); ++ if (!rhash || rhashlen != M_EVP_MD_size(md)) ++ goto parse_error; ++ ec_output_Zhash(out, exout, group, ix, iy, id, cx, cy, ++ md, rhash, rhashlen); ++ } ++ } ++ rv = 0; ++ parse_error: ++ if (id) ++ BN_free(id); ++ if (ix) ++ BN_free(ix); ++ if (iy) ++ BN_free(iy); ++ if (cx) ++ BN_free(cx); ++ if (cy) ++ BN_free(cy); ++ if (group) ++ EC_GROUP_free(group); ++ if (in && in != stdin) ++ fclose(in); ++ if (out && out != stdout) ++ fclose(out); ++ if (rv) ++ fprintf(stderr, "Error Parsing request file\n"); ++ return rv; ++} ++ ++#endif +diff -up openssl-1.0.2a/crypto/fips/cavs/fips_ecdsavs.c.fips-ec openssl-1.0.2a/crypto/fips/cavs/fips_ecdsavs.c +--- openssl-1.0.2a/crypto/fips/cavs/fips_ecdsavs.c.fips-ec 2015-04-22 19:00:19.723884560 +0200 ++++ openssl-1.0.2a/crypto/fips/cavs/fips_ecdsavs.c 2015-04-22 19:00:19.723884560 +0200 +@@ -0,0 +1,486 @@ ++/* fips/ecdsa/fips_ecdsavs.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++#define OPENSSL_FIPSAPI ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS ECDSA support\n"); ++ return (0); ++} ++#else ++ ++# include ++# include ++# include ++# include ++# include ++# include ++# include "fips_utl.h" ++ ++# include ++ ++static int elookup_curve(char *in, char *curve_name, const EVP_MD **pmd) ++{ ++ char *cname, *p; ++ /* Copy buffer as we will change it */ ++ strcpy(curve_name, in); ++ cname = curve_name + 1; ++ p = strchr(cname, ']'); ++ if (!p) { ++ fprintf(stderr, "Parse error: missing ]\n"); ++ return NID_undef; ++ } ++ *p = 0; ++ p = strchr(cname, ','); ++ if (p) { ++ if (!pmd) { ++ fprintf(stderr, "Parse error: unexpected digest\n"); ++ return NID_undef; ++ } ++ *p = 0; ++ p++; ++ ++ if (!strcmp(p, "SHA-1")) ++ *pmd = EVP_sha1(); ++ else if (!strcmp(p, "SHA-224")) ++ *pmd = EVP_sha224(); ++ else if (!strcmp(p, "SHA-256")) ++ *pmd = EVP_sha256(); ++ else if (!strcmp(p, "SHA-384")) ++ *pmd = EVP_sha384(); ++ else if (!strcmp(p, "SHA-512")) ++ *pmd = EVP_sha512(); ++ else { ++ fprintf(stderr, "Unknown digest %s\n", p); ++ return NID_undef; ++ } ++ } else if (pmd) ++ *pmd = EVP_sha1(); ++ ++ if (!strcmp(cname, "B-163")) ++ return NID_sect163r2; ++ if (!strcmp(cname, "B-233")) ++ return NID_sect233r1; ++ if (!strcmp(cname, "B-283")) ++ return NID_sect283r1; ++ if (!strcmp(cname, "B-409")) ++ return NID_sect409r1; ++ if (!strcmp(cname, "B-571")) ++ return NID_sect571r1; ++ if (!strcmp(cname, "K-163")) ++ return NID_sect163k1; ++ if (!strcmp(cname, "K-233")) ++ return NID_sect233k1; ++ if (!strcmp(cname, "K-283")) ++ return NID_sect283k1; ++ if (!strcmp(cname, "K-409")) ++ return NID_sect409k1; ++ if (!strcmp(cname, "K-571")) ++ return NID_sect571k1; ++ if (!strcmp(cname, "P-192")) ++ return NID_X9_62_prime192v1; ++ if (!strcmp(cname, "P-224")) ++ return NID_secp224r1; ++ if (!strcmp(cname, "P-256")) ++ return NID_X9_62_prime256v1; ++ if (!strcmp(cname, "P-384")) ++ return NID_secp384r1; ++ if (!strcmp(cname, "P-521")) ++ return NID_secp521r1; ++ ++ fprintf(stderr, "Unknown Curve name %s\n", cname); ++ return NID_undef; ++} ++ ++static int ec_get_pubkey(EC_KEY *key, BIGNUM *x, BIGNUM *y) ++{ ++ const EC_POINT *pt; ++ const EC_GROUP *grp; ++ const EC_METHOD *meth; ++ int rv; ++ BN_CTX *ctx; ++ ctx = BN_CTX_new(); ++ if (!ctx) ++ return 0; ++ grp = EC_KEY_get0_group(key); ++ pt = EC_KEY_get0_public_key(key); ++ meth = EC_GROUP_method_of(grp); ++ if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) ++ rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, x, y, ctx); ++ else ++# ifdef OPENSSL_NO_EC2M ++ { ++ fprintf(stderr, "ERROR: GF2m not supported\n"); ++ exit(1); ++ } ++# else ++ rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, x, y, ctx); ++# endif ++ ++ BN_CTX_free(ctx); ++ ++ return rv; ++ ++} ++ ++static int KeyPair(FILE *in, FILE *out) ++{ ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ int curve_nid = NID_undef; ++ int i, count; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ const BIGNUM *d = NULL; ++ EC_KEY *key = NULL; ++ Qx = BN_new(); ++ Qy = BN_new(); ++ while (fgets(buf, sizeof buf, in) != NULL) { ++ if (*buf == '[' && buf[2] == '-') { ++ if (buf[2] == '-') ++ curve_nid = elookup_curve(buf, lbuf, NULL); ++ fputs(buf, out); ++ continue; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) { ++ fputs(buf, out); ++ continue; ++ } ++ if (!strcmp(keyword, "N")) { ++ count = atoi(value); ++ ++ for (i = 0; i < count; i++) { ++ ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ if (!EC_KEY_generate_key(key)) { ++ fprintf(stderr, "Error generating key\n"); ++ return 0; ++ } ++ ++ if (!ec_get_pubkey(key, Qx, Qy)) { ++ fprintf(stderr, "Error getting public key\n"); ++ return 0; ++ } ++ ++ d = EC_KEY_get0_private_key(key); ++ ++ do_bn_print_name(out, "d", d); ++ do_bn_print_name(out, "Qx", Qx); ++ do_bn_print_name(out, "Qy", Qy); ++ fputs(RESP_EOL, out); ++ EC_KEY_free(key); ++ ++ } ++ ++ } ++ ++ } ++ BN_free(Qx); ++ BN_free(Qy); ++ return 1; ++} ++ ++static int PKV(FILE *in, FILE *out) ++{ ++ ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ int curve_nid = NID_undef; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ EC_KEY *key = NULL; ++ while (fgets(buf, sizeof buf, in) != NULL) { ++ fputs(buf, out); ++ if (*buf == '[' && buf[2] == '-') { ++ curve_nid = elookup_curve(buf, lbuf, NULL); ++ if (curve_nid == NID_undef) ++ return 0; ++ ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "Qx")) { ++ if (!do_hex2bn(&Qx, value)) { ++ fprintf(stderr, "Invalid Qx value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "Qy")) { ++ int rv; ++ if (!do_hex2bn(&Qy, value)) { ++ fprintf(stderr, "Invalid Qy value\n"); ++ return 0; ++ } ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ no_err = 1; ++ rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy); ++ no_err = 0; ++ EC_KEY_free(key); ++ fprintf(out, "Result = %s" RESP_EOL, rv ? "P" : "F"); ++ } ++ ++ } ++ BN_free(Qx); ++ BN_free(Qy); ++ return 1; ++} ++ ++static int SigGen(FILE *in, FILE *out) ++{ ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ unsigned char *msg; ++ int curve_nid = NID_undef; ++ long mlen; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ EC_KEY *key = NULL; ++ ECDSA_SIG *sig = NULL; ++ const EVP_MD *digest = NULL; ++ Qx = BN_new(); ++ Qy = BN_new(); ++ while (fgets(buf, sizeof buf, in) != NULL) { ++ fputs(buf, out); ++ if (*buf == '[') { ++ curve_nid = elookup_curve(buf, lbuf, &digest); ++ if (curve_nid == NID_undef) ++ return 0; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "Msg")) { ++ msg = hex2bin_m(value, &mlen); ++ if (!msg) { ++ fprintf(stderr, "Invalid Message\n"); ++ return 0; ++ } ++ ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ if (!EC_KEY_generate_key(key)) { ++ fprintf(stderr, "Error generating key\n"); ++ return 0; ++ } ++ ++ if (!ec_get_pubkey(key, Qx, Qy)) { ++ fprintf(stderr, "Error getting public key\n"); ++ return 0; ++ } ++ ++ sig = FIPS_ecdsa_sign(key, msg, mlen, digest); ++ ++ if (!sig) { ++ fprintf(stderr, "Error signing message\n"); ++ return 0; ++ } ++ ++ do_bn_print_name(out, "Qx", Qx); ++ do_bn_print_name(out, "Qy", Qy); ++ do_bn_print_name(out, "R", sig->r); ++ do_bn_print_name(out, "S", sig->s); ++ ++ EC_KEY_free(key); ++ OPENSSL_free(msg); ++ FIPS_ecdsa_sig_free(sig); ++ ++ } ++ ++ } ++ BN_free(Qx); ++ BN_free(Qy); ++ return 1; ++} ++ ++static int SigVer(FILE *in, FILE *out) ++{ ++ char buf[2048], lbuf[2048]; ++ char *keyword, *value; ++ unsigned char *msg = NULL; ++ int curve_nid = NID_undef; ++ long mlen; ++ BIGNUM *Qx = NULL, *Qy = NULL; ++ EC_KEY *key = NULL; ++ ECDSA_SIG sg, *sig = &sg; ++ const EVP_MD *digest = NULL; ++ sig->r = NULL; ++ sig->s = NULL; ++ while (fgets(buf, sizeof buf, in) != NULL) { ++ fputs(buf, out); ++ if (*buf == '[') { ++ curve_nid = elookup_curve(buf, lbuf, &digest); ++ if (curve_nid == NID_undef) ++ return 0; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "Msg")) { ++ msg = hex2bin_m(value, &mlen); ++ if (!msg) { ++ fprintf(stderr, "Invalid Message\n"); ++ return 0; ++ } ++ } ++ ++ if (!strcmp(keyword, "Qx")) { ++ if (!do_hex2bn(&Qx, value)) { ++ fprintf(stderr, "Invalid Qx value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "Qy")) { ++ if (!do_hex2bn(&Qy, value)) { ++ fprintf(stderr, "Invalid Qy value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "R")) { ++ if (!do_hex2bn(&sig->r, value)) { ++ fprintf(stderr, "Invalid R value\n"); ++ return 0; ++ } ++ } ++ if (!strcmp(keyword, "S")) { ++ int rv; ++ if (!do_hex2bn(&sig->s, value)) { ++ fprintf(stderr, "Invalid S value\n"); ++ return 0; ++ } ++ key = EC_KEY_new_by_curve_name(curve_nid); ++ rv = EC_KEY_set_public_key_affine_coordinates(key, Qx, Qy); ++ ++ if (rv != 1) { ++ fprintf(stderr, "Error setting public key\n"); ++ return 0; ++ } ++ ++ no_err = 1; ++ rv = FIPS_ecdsa_verify(key, msg, mlen, digest, sig); ++ EC_KEY_free(key); ++ if (msg) ++ OPENSSL_free(msg); ++ no_err = 0; ++ ++ fprintf(out, "Result = %s" RESP_EOL, rv ? "P" : "F"); ++ } ++ ++ } ++ if (sig->r) ++ BN_free(sig->r); ++ if (sig->s) ++ BN_free(sig->s); ++ if (Qx) ++ BN_free(Qx); ++ if (Qy) ++ BN_free(Qy); ++ return 1; ++} ++ ++# ifdef FIPS_ALGVS ++int fips_ecdsavs_main(int argc, char **argv) ++# else ++int main(int argc, char **argv) ++# endif ++{ ++ FILE *in = NULL, *out = NULL; ++ const char *cmd = argv[1]; ++ int rv = 0; ++ fips_algtest_init(); ++ ++ if (argc == 4) { ++ in = fopen(argv[2], "r"); ++ if (!in) { ++ fprintf(stderr, "Error opening input file\n"); ++ exit(1); ++ } ++ out = fopen(argv[3], "w"); ++ if (!out) { ++ fprintf(stderr, "Error opening output file\n"); ++ exit(1); ++ } ++ } else if (argc == 2) { ++ in = stdin; ++ out = stdout; ++ } ++ ++ if (!cmd) { ++ fprintf(stderr, "fips_ecdsavs [KeyPair|PKV|SigGen|SigVer]\n"); ++ return 1; ++ } ++ if (!strcmp(cmd, "KeyPair")) ++ rv = KeyPair(in, out); ++ else if (!strcmp(cmd, "PKV")) ++ rv = PKV(in, out); ++ else if (!strcmp(cmd, "SigVer")) ++ rv = SigVer(in, out); ++ else if (!strcmp(cmd, "SigGen")) ++ rv = SigGen(in, out); ++ else { ++ fprintf(stderr, "Unknown command %s\n", cmd); ++ return 1; ++ } ++ ++ if (argc == 4) { ++ fclose(in); ++ fclose(out); ++ } ++ ++ if (rv <= 0) { ++ fprintf(stderr, "Error running %s\n", cmd); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++#endif +diff -up openssl-1.0.2a/crypto/fips/fips_ecdh_selftest.c.fips-ec openssl-1.0.2a/crypto/fips/fips_ecdh_selftest.c +--- openssl-1.0.2a/crypto/fips/fips_ecdh_selftest.c.fips-ec 2015-04-22 19:00:19.724884583 +0200 ++++ openssl-1.0.2a/crypto/fips/fips_ecdh_selftest.c 2015-04-22 19:00:19.724884583 +0200 +@@ -0,0 +1,242 @@ ++/* fips/ecdh/fips_ecdh_selftest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2011. ++ */ ++/* ==================================================================== ++ * 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 ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++# include "fips_locl.h" ++ ++static const unsigned char p256_qcavsx[] = { ++ 0x52, 0xc6, 0xa5, 0x75, 0xf3, 0x04, 0x98, 0xb3, 0x29, 0x66, 0x0c, 0x62, ++ 0x18, 0x60, 0x55, 0x41, 0x59, 0xd4, 0x60, 0x85, 0x99, 0xc1, 0x51, 0x13, ++ 0x6f, 0x97, 0x85, 0x93, 0x33, 0x34, 0x07, 0x50 ++}; ++ ++static const unsigned char p256_qcavsy[] = { ++ 0x6f, 0x69, 0x24, 0xeb, 0xe9, 0x3b, 0xa7, 0xcc, 0x47, 0x17, 0xaa, 0x3f, ++ 0x70, 0xfc, 0x10, 0x73, 0x0a, 0xcd, 0x21, 0xee, 0x29, 0x19, 0x1f, 0xaf, ++ 0xb4, 0x1c, 0x1e, 0xc2, 0x8e, 0x97, 0x81, 0x6e ++}; ++ ++static const unsigned char p256_qiutx[] = { ++ 0x71, 0x46, 0x88, 0x08, 0x92, 0x21, 0x1b, 0x10, 0x21, 0x74, 0xff, 0x0c, ++ 0x94, 0xde, 0x34, 0x7c, 0x86, 0x74, 0xbe, 0x67, 0x41, 0x68, 0xd4, 0xc1, ++ 0xe5, 0x75, 0x63, 0x9c, 0xa7, 0x46, 0x93, 0x6f ++}; ++ ++static const unsigned char p256_qiuty[] = { ++ 0x33, 0x40, 0xa9, 0x6a, 0xf5, 0x20, 0xb5, 0x9e, 0xfc, 0x60, 0x1a, 0xae, ++ 0x3d, 0xf8, 0x21, 0xd2, 0xa7, 0xca, 0x52, 0x34, 0xb9, 0x5f, 0x27, 0x75, ++ 0x6c, 0x81, 0xbe, 0x32, 0x4d, 0xba, 0xbb, 0xf8 ++}; ++ ++static const unsigned char p256_qiutd[] = { ++ 0x1a, 0x48, 0x55, 0x6b, 0x11, 0xbe, 0x92, 0xd4, 0x1c, 0xd7, 0x45, 0xc3, ++ 0x82, 0x81, 0x51, 0xf1, 0x23, 0x40, 0xb7, 0x83, 0xfd, 0x01, 0x6d, 0xbc, ++ 0xa1, 0x66, 0xaf, 0x0a, 0x03, 0x23, 0xcd, 0xc8 ++}; ++ ++static const unsigned char p256_ziut[] = { ++ 0x77, 0x2a, 0x1e, 0x37, 0xee, 0xe6, 0x51, 0x02, 0x71, 0x40, 0xf8, 0x6a, ++ 0x36, 0xf8, 0x65, 0x61, 0x2b, 0x18, 0x71, 0x82, 0x23, 0xe6, 0xf2, 0x77, ++ 0xce, 0xec, 0xb8, 0x49, 0xc7, 0xbf, 0x36, 0x4f ++}; ++ ++typedef struct { ++ int curve; ++ const unsigned char *x1; ++ size_t x1len; ++ const unsigned char *y1; ++ size_t y1len; ++ const unsigned char *d1; ++ size_t d1len; ++ const unsigned char *x2; ++ size_t x2len; ++ const unsigned char *y2; ++ size_t y2len; ++ const unsigned char *z; ++ size_t zlen; ++} ECDH_SELFTEST_DATA; ++ ++# define make_ecdh_test(nid, pr) { nid, \ ++ pr##_qiutx, sizeof(pr##_qiutx), \ ++ pr##_qiuty, sizeof(pr##_qiuty), \ ++ pr##_qiutd, sizeof(pr##_qiutd), \ ++ pr##_qcavsx, sizeof(pr##_qcavsx), \ ++ pr##_qcavsy, sizeof(pr##_qcavsy), \ ++ pr##_ziut, sizeof(pr##_ziut) } ++ ++static ECDH_SELFTEST_DATA test_ecdh_data[] = { ++ make_ecdh_test(NID_X9_62_prime256v1, p256), ++}; ++ ++int FIPS_selftest_ecdh(void) ++{ ++ EC_KEY *ec1 = NULL, *ec2 = NULL; ++ const EC_POINT *ecp = NULL; ++ BIGNUM *x = NULL, *y = NULL, *d = NULL; ++ unsigned char *ztmp = NULL; ++ int rv = 1; ++ size_t i; ++ ++ for (i = 0; i < sizeof(test_ecdh_data) / sizeof(ECDH_SELFTEST_DATA); i++) { ++ ECDH_SELFTEST_DATA *ecd = test_ecdh_data + i; ++ if (!fips_post_started(FIPS_TEST_ECDH, ecd->curve, 0)) ++ continue; ++ ztmp = OPENSSL_malloc(ecd->zlen); ++ ++ x = BN_bin2bn(ecd->x1, ecd->x1len, x); ++ y = BN_bin2bn(ecd->y1, ecd->y1len, y); ++ d = BN_bin2bn(ecd->d1, ecd->d1len, d); ++ ++ if (!x || !y || !d || !ztmp) { ++ rv = -1; ++ goto err; ++ } ++ ++ ec1 = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec1) { ++ rv = -1; ++ goto err; ++ } ++ EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec1, x, y)) { ++ rv = -1; ++ goto err; ++ } ++ ++ if (!EC_KEY_set_private_key(ec1, d)) { ++ rv = -1; ++ goto err; ++ } ++ ++ x = BN_bin2bn(ecd->x2, ecd->x2len, x); ++ y = BN_bin2bn(ecd->y2, ecd->y2len, y); ++ ++ if (!x || !y) { ++ rv = -1; ++ goto err; ++ } ++ ++ ec2 = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec2) { ++ rv = -1; ++ goto err; ++ } ++ EC_KEY_set_flags(ec1, EC_FLAG_COFACTOR_ECDH); ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec2, x, y)) { ++ rv = -1; ++ goto err; ++ } ++ ++ ecp = EC_KEY_get0_public_key(ec2); ++ if (!ecp) { ++ rv = -1; ++ goto err; ++ } ++ ++ if (!ECDH_compute_key(ztmp, ecd->zlen, ecp, ec1, 0)) { ++ rv = -1; ++ goto err; ++ } ++ ++ if (!fips_post_corrupt(FIPS_TEST_ECDH, ecd->curve, NULL)) ++ ztmp[0] ^= 0x1; ++ ++ if (memcmp(ztmp, ecd->z, ecd->zlen)) { ++ fips_post_failed(FIPS_TEST_ECDH, ecd->curve, 0); ++ rv = 0; ++ } else if (!fips_post_success(FIPS_TEST_ECDH, ecd->curve, 0)) ++ goto err; ++ ++ EC_KEY_free(ec1); ++ ec1 = NULL; ++ EC_KEY_free(ec2); ++ ec2 = NULL; ++ OPENSSL_free(ztmp); ++ ztmp = NULL; ++ } ++ ++ err: ++ ++ if (x) ++ BN_clear_free(x); ++ if (y) ++ BN_clear_free(y); ++ if (d) ++ BN_clear_free(d); ++ if (ec1) ++ EC_KEY_free(ec1); ++ if (ec2) ++ EC_KEY_free(ec2); ++ if (ztmp) ++ OPENSSL_free(ztmp); ++ ++ return rv; ++ ++} ++ ++#endif +diff -up openssl-1.0.2a/crypto/fips/fips_ecdsa_selftest.c.fips-ec openssl-1.0.2a/crypto/fips/fips_ecdsa_selftest.c +--- openssl-1.0.2a/crypto/fips/fips_ecdsa_selftest.c.fips-ec 2015-04-22 19:00:19.724884583 +0200 ++++ openssl-1.0.2a/crypto/fips/fips_ecdsa_selftest.c 2015-04-22 19:00:19.724884583 +0200 +@@ -0,0 +1,165 @@ ++/* fips/ecdsa/fips_ecdsa_selftest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2011. ++ */ ++/* ==================================================================== ++ * 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 ++#include ++#include ++ ++#ifdef OPENSSL_FIPS ++ ++static const char P_256_name[] = "ECDSA P-256"; ++ ++static const unsigned char P_256_d[] = { ++ 0x51, 0xbd, 0x06, 0xa1, 0x1c, 0xda, 0xe2, 0x12, 0x99, 0xc9, 0x52, 0x3f, ++ 0xea, 0xa4, 0xd2, 0xd1, 0xf4, 0x7f, 0xd4, 0x3e, 0xbd, 0xf8, 0xfc, 0x87, ++ 0xdc, 0x82, 0x53, 0x21, 0xee, 0xa0, 0xdc, 0x64 ++}; ++ ++static const unsigned char P_256_qx[] = { ++ 0x23, 0x89, 0xe0, 0xf4, 0x69, 0xe0, 0x49, 0xe5, 0xc7, 0xe5, 0x40, 0x6e, ++ 0x8f, 0x25, 0xdd, 0xad, 0x11, 0x16, 0x14, 0x9b, 0xab, 0x44, 0x06, 0x31, ++ 0xbf, 0x5e, 0xa6, 0x44, 0xac, 0x86, 0x00, 0x07 ++}; ++ ++static const unsigned char P_256_qy[] = { ++ 0xb3, 0x05, 0x0d, 0xd0, 0xdc, 0xf7, 0x40, 0xe6, 0xf9, 0xd8, 0x6d, 0x7b, ++ 0x63, 0xca, 0x97, 0xe6, 0x12, 0xf9, 0xd4, 0x18, 0x59, 0xbe, 0xb2, 0x5e, ++ 0x4a, 0x6a, 0x77, 0x23, 0xf4, 0x11, 0x9d, 0xeb ++}; ++ ++typedef struct { ++ int curve; ++ const char *name; ++ const unsigned char *x; ++ size_t xlen; ++ const unsigned char *y; ++ size_t ylen; ++ const unsigned char *d; ++ size_t dlen; ++} EC_SELFTEST_DATA; ++ ++# define make_ecdsa_test(nid, pr) { nid, pr##_name, \ ++ pr##_qx, sizeof(pr##_qx), \ ++ pr##_qy, sizeof(pr##_qy), \ ++ pr##_d, sizeof(pr##_d)} ++ ++static EC_SELFTEST_DATA test_ec_data[] = { ++ make_ecdsa_test(NID_X9_62_prime256v1, P_256), ++}; ++ ++int FIPS_selftest_ecdsa() ++{ ++ EC_KEY *ec = NULL; ++ BIGNUM *x = NULL, *y = NULL, *d = NULL; ++ EVP_PKEY *pk = NULL; ++ int rv = 0; ++ size_t i; ++ ++ for (i = 0; i < sizeof(test_ec_data) / sizeof(EC_SELFTEST_DATA); i++) { ++ EC_SELFTEST_DATA *ecd = test_ec_data + i; ++ ++ x = BN_bin2bn(ecd->x, ecd->xlen, x); ++ y = BN_bin2bn(ecd->y, ecd->ylen, y); ++ d = BN_bin2bn(ecd->d, ecd->dlen, d); ++ ++ if (!x || !y || !d) ++ goto err; ++ ++ ec = EC_KEY_new_by_curve_name(ecd->curve); ++ if (!ec) ++ goto err; ++ ++ if (!EC_KEY_set_public_key_affine_coordinates(ec, x, y)) ++ goto err; ++ ++ if (!EC_KEY_set_private_key(ec, d)) ++ goto err; ++ ++ if ((pk = EVP_PKEY_new()) == NULL) ++ goto err; ++ ++ EVP_PKEY_assign_EC_KEY(pk, ec); ++ ++ if (!fips_pkey_signature_test(pk, NULL, 0, ++ NULL, 0, EVP_sha256(), 0, ecd->name)) ++ goto err; ++ } ++ ++ rv = 1; ++ ++ err: ++ ++ if (x) ++ BN_clear_free(x); ++ if (y) ++ BN_clear_free(y); ++ if (d) ++ BN_clear_free(d); ++ if (pk) ++ EVP_PKEY_free(pk); ++ else if (ec) ++ EC_KEY_free(ec); ++ ++ return rv; ++ ++} ++ ++#endif +diff -up openssl-1.0.2a/crypto/fips/fips.h.fips-ec openssl-1.0.2a/crypto/fips/fips.h +--- openssl-1.0.2a/crypto/fips/fips.h.fips-ec 2015-04-22 19:00:19.688883733 +0200 ++++ openssl-1.0.2a/crypto/fips/fips.h 2015-04-22 19:00:19.724884583 +0200 +@@ -93,6 +93,8 @@ extern "C" { + void FIPS_corrupt_dsa(void); + void FIPS_corrupt_dsa_keygen(void); + int FIPS_selftest_dsa(void); ++ int FIPS_selftest_ecdsa(void); ++ int FIPS_selftest_ecdh(void); + void FIPS_corrupt_rng(void); + void FIPS_rng_stick(void); + void FIPS_x931_stick(int onoff); +diff -up openssl-1.0.2a/crypto/fips/fips_post.c.fips-ec openssl-1.0.2a/crypto/fips/fips_post.c +--- openssl-1.0.2a/crypto/fips/fips_post.c.fips-ec 2015-04-22 19:00:19.688883733 +0200 ++++ openssl-1.0.2a/crypto/fips/fips_post.c 2015-04-22 19:00:19.724884583 +0200 +@@ -95,8 +95,12 @@ int FIPS_selftest(void) + rv = 0; + if (!FIPS_selftest_rsa()) + rv = 0; ++ if (!FIPS_selftest_ecdsa()) ++ rv = 0; + if (!FIPS_selftest_dsa()) + rv = 0; ++ if (!FIPS_selftest_ecdh()) ++ rv = 0; + return rv; + } + +diff -up openssl-1.0.2a/crypto/fips/Makefile.fips-ec openssl-1.0.2a/crypto/fips/Makefile +--- openssl-1.0.2a/crypto/fips/Makefile.fips-ec 2015-04-22 19:00:19.691883805 +0200 ++++ openssl-1.0.2a/crypto/fips/Makefile 2015-04-22 19:00:19.724884583 +0200 +@@ -24,13 +24,13 @@ LIBSRC=fips_aes_selftest.c fips_des_self + 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 ++ fips_cmac_selftest.c fips_ecdh_selftest.c fips_ecdsa_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 ++ fips_cmac_selftest.o fips_ecdh_selftest.o fips_ecdsa_selftest.o fips_enc.o fips_md.o + + LIBCRYPTO=-L.. -lcrypto + +@@ -119,6 +119,21 @@ fips_aes_selftest.o: ../../include/opens + 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_cmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_cmac_selftest.o: ../../include/openssl/cmac.h ++fips_cmac_selftest.o: ../../include/openssl/crypto.h ++fips_cmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h ++fips_cmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h ++fips_cmac_selftest.o: ../../include/openssl/lhash.h ++fips_cmac_selftest.o: ../../include/openssl/obj_mac.h ++fips_cmac_selftest.o: ../../include/openssl/objects.h ++fips_cmac_selftest.o: ../../include/openssl/opensslconf.h ++fips_cmac_selftest.o: ../../include/openssl/opensslv.h ++fips_cmac_selftest.o: ../../include/openssl/ossl_typ.h ++fips_cmac_selftest.o: ../../include/openssl/safestack.h ++fips_cmac_selftest.o: ../../include/openssl/stack.h ++fips_cmac_selftest.o: ../../include/openssl/symhacks.h fips_cmac_selftest.c ++fips_cmac_selftest.o: fips_locl.h + 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 +@@ -232,6 +247,46 @@ fips_dsa_selftest.o: ../../include/opens + 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_ecdh_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_ecdh_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h ++fips_ecdh_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h ++fips_ecdh_selftest.o: ../../include/openssl/ecdh.h ../../include/openssl/err.h ++fips_ecdh_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h ++fips_ecdh_selftest.o: ../../include/openssl/lhash.h ++fips_ecdh_selftest.o: ../../include/openssl/obj_mac.h ++fips_ecdh_selftest.o: ../../include/openssl/objects.h ++fips_ecdh_selftest.o: ../../include/openssl/opensslconf.h ++fips_ecdh_selftest.o: ../../include/openssl/opensslv.h ++fips_ecdh_selftest.o: ../../include/openssl/ossl_typ.h ++fips_ecdh_selftest.o: ../../include/openssl/safestack.h ++fips_ecdh_selftest.o: ../../include/openssl/stack.h ++fips_ecdh_selftest.o: ../../include/openssl/symhacks.h fips_ecdh_selftest.c ++fips_ecdh_selftest.o: fips_locl.h ++fips_ecdsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_ecdsa_selftest.o: ../../include/openssl/bn.h ++fips_ecdsa_selftest.o: ../../include/openssl/crypto.h ++fips_ecdsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h ++fips_ecdsa_selftest.o: ../../include/openssl/ecdsa.h ++fips_ecdsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h ++fips_ecdsa_selftest.o: ../../include/openssl/fips.h ++fips_ecdsa_selftest.o: ../../include/openssl/lhash.h ++fips_ecdsa_selftest.o: ../../include/openssl/obj_mac.h ++fips_ecdsa_selftest.o: ../../include/openssl/objects.h ++fips_ecdsa_selftest.o: ../../include/openssl/opensslconf.h ++fips_ecdsa_selftest.o: ../../include/openssl/opensslv.h ++fips_ecdsa_selftest.o: ../../include/openssl/ossl_typ.h ++fips_ecdsa_selftest.o: ../../include/openssl/safestack.h ++fips_ecdsa_selftest.o: ../../include/openssl/stack.h ++fips_ecdsa_selftest.o: ../../include/openssl/symhacks.h fips_ecdsa_selftest.c ++fips_enc.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h ++fips_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h ++fips_enc.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h ++fips_enc.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h ++fips_enc.o: ../../include/openssl/opensslconf.h ++fips_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h ++fips_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h ++fips_enc.o: ../../include/openssl/symhacks.h fips_enc.c + fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h + fips_hmac_selftest.o: ../../include/openssl/crypto.h + fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +@@ -246,6 +301,15 @@ fips_hmac_selftest.o: ../../include/open + 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_md.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++fips_md.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h ++fips_md.o: ../../include/openssl/err.h ../../include/openssl/evp.h ++fips_md.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h ++fips_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h ++fips_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h ++fips_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h ++fips_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h ++fips_md.o: fips_md.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 +diff -up openssl-1.0.2a/version.map.fips-ec openssl-1.0.2a/version.map +--- openssl-1.0.2a/version.map.fips-ec 2015-04-22 19:00:19.704884111 +0200 ++++ openssl-1.0.2a/version.map 2015-04-22 19:00:19.724884583 +0200 +@@ -6,6 +6,10 @@ OPENSSL_1.0.1 { + _original*; + _current*; + }; ++OPENSSL_1.0.1_EC { ++ global: ++ EC*; ++}; + OPENSSL_1.0.2 { + global: + SSLeay; diff --git a/SOURCES/openssl-1.0.2a-fips-md5-allow.patch b/SOURCES/openssl-1.0.2a-fips-md5-allow.patch new file mode 100644 index 0000000..825417f --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-ipv6-apps.patch b/SOURCES/openssl-1.0.2a-ipv6-apps.patch new file mode 100644 index 0000000..dd8b42c --- /dev/null +++ b/SOURCES/openssl-1.0.2a-ipv6-apps.patch @@ -0,0 +1,525 @@ +diff -up openssl-1.0.2a/apps/s_apps.h.ipv6-apps openssl-1.0.2a/apps/s_apps.h +--- openssl-1.0.2a/apps/s_apps.h.ipv6-apps 2015-04-20 15:01:24.029120104 +0200 ++++ openssl-1.0.2a/apps/s_apps.h 2015-04-20 15:05:00.353137701 +0200 +@@ -151,7 +151,7 @@ typedef fd_mask fd_set; + #define PORT_STR "4433" + #define PROTOCOL "tcp" + +-int do_server(int port, int type, int *ret, ++int do_server(char *port, int type, int *ret, + int (*cb) (char *hostname, int s, int stype, + unsigned char *context), unsigned char *context, + int naccept); +@@ -167,11 +167,10 @@ int ssl_print_point_formats(BIO *out, SS + int ssl_print_curves(BIO *out, SSL *s, int noshared); + #endif + int ssl_print_tmp_key(BIO *out, SSL *s); +-int init_client(int *sock, char *server, int port, int type); ++int init_client(int *sock, char *server, char *port, int type); + int should_retry(int i); + int extract_port(char *str, short *port_ptr); +-int extract_host_port(char *str, char **host_ptr, unsigned char *ip, +- short *p); ++int extract_host_port(char *str, char **host_ptr, char **port_ptr); + + long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, + int argi, long argl, long ret); +diff -up openssl-1.0.2a/apps/s_client.c.ipv6-apps openssl-1.0.2a/apps/s_client.c +--- openssl-1.0.2a/apps/s_client.c.ipv6-apps 2015-04-20 15:01:24.022119942 +0200 ++++ openssl-1.0.2a/apps/s_client.c 2015-04-20 15:06:42.338503234 +0200 +@@ -662,7 +662,7 @@ int MAIN(int argc, char **argv) + int cbuf_len, cbuf_off; + int sbuf_len, sbuf_off; + fd_set readfds, writefds; +- short port = PORT; ++ char *port_str = PORT_STR; + int full_log = 1; + char *host = SSL_HOST_NAME; + char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; +@@ -785,13 +785,11 @@ int MAIN(int argc, char **argv) + } else if (strcmp(*argv, "-port") == 0) { + if (--argc < 1) + goto bad; +- port = atoi(*(++argv)); +- if (port == 0) +- goto bad; ++ port_str = *(++argv); + } else if (strcmp(*argv, "-connect") == 0) { + if (--argc < 1) + goto bad; +- if (!extract_host_port(*(++argv), &host, NULL, &port)) ++ if (!extract_host_port(*(++argv), &host, &port_str)) + goto bad; + } else if (strcmp(*argv, "-verify") == 0) { + verify = SSL_VERIFY_PEER; +@@ -1417,7 +1415,7 @@ int MAIN(int argc, char **argv) + + re_start: + +- if (init_client(&s, host, port, socket_type) == 0) { ++ if (init_client(&s, host, port_str, socket_type) == 0) { + BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); + SHUTDOWN(s); + goto end; +diff -up openssl-1.0.2a/apps/s_server.c.ipv6-apps openssl-1.0.2a/apps/s_server.c +--- openssl-1.0.2a/apps/s_server.c.ipv6-apps 2015-04-20 15:01:24.030120127 +0200 ++++ openssl-1.0.2a/apps/s_server.c 2015-04-20 15:10:47.245187746 +0200 +@@ -1061,7 +1061,7 @@ int MAIN(int argc, char *argv[]) + { + X509_VERIFY_PARAM *vpm = NULL; + int badarg = 0; +- short port = PORT; ++ char *port_str = PORT_STR; + char *CApath = NULL, *CAfile = NULL; + char *chCApath = NULL, *chCAfile = NULL; + char *vfyCApath = NULL, *vfyCAfile = NULL; +@@ -1148,7 +1148,8 @@ int MAIN(int argc, char *argv[]) + if ((strcmp(*argv, "-port") == 0) || (strcmp(*argv, "-accept") == 0)) { + if (--argc < 1) + goto bad; +- if (!extract_port(*(++argv), &port)) ++ port_str = *(++argv); ++ if (port_str == NULL || *port_str == '\0') + goto bad; + } else if (strcmp(*argv, "-naccept") == 0) { + if (--argc < 1) +@@ -2020,13 +2021,13 @@ int MAIN(int argc, char *argv[]) + BIO_printf(bio_s_out, "ACCEPT\n"); + (void)BIO_flush(bio_s_out); + if (rev) +- do_server(port, socket_type, &accept_socket, rev_body, context, ++ do_server(port_str, socket_type, &accept_socket, rev_body, context, + naccept); + else if (www) +- do_server(port, socket_type, &accept_socket, www_body, context, ++ do_server(port_str, socket_type, &accept_socket, www_body, context, + naccept); + else +- do_server(port, socket_type, &accept_socket, sv_body, context, ++ do_server(port_str, socket_type, &accept_socket, sv_body, context, + naccept); + print_stats(bio_s_out, ctx); + ret = 0; +diff -up openssl-1.0.2a/apps/s_socket.c.ipv6-apps openssl-1.0.2a/apps/s_socket.c +--- openssl-1.0.2a/apps/s_socket.c.ipv6-apps 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/apps/s_socket.c 2015-04-20 15:32:53.960079507 +0200 +@@ -106,9 +106,7 @@ static struct hostent *GetHostByName(cha + static void ssl_sock_cleanup(void); + # endif + static int ssl_sock_init(void); +-static int init_client_ip(int *sock, unsigned char ip[4], int port, int type); +-static int init_server(int *sock, int port, int type); +-static int init_server_long(int *sock, int port, char *ip, int type); ++static int init_server(int *sock, char *port, int type); + static int do_accept(int acc_sock, int *sock, char **host); + static int host_ip(char *str, unsigned char ip[4]); + +@@ -231,65 +229,66 @@ static int ssl_sock_init(void) + return (1); + } + +-int init_client(int *sock, char *host, int port, int type) ++int init_client(int *sock, char *host, char *port, int type) + { +- unsigned char ip[4]; +- +- memset(ip, '\0', sizeof ip); +- if (!host_ip(host, &(ip[0]))) +- return 0; +- return init_client_ip(sock, ip, port, type); +-} +- +-static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) +-{ +- unsigned long addr; +- struct sockaddr_in them; +- int s, i; ++ struct addrinfo *res, *res0, hints; ++ char *failed_call = NULL; ++ int s; ++ int e; + + if (!ssl_sock_init()) + return (0); + +- memset((char *)&them, 0, sizeof(them)); +- them.sin_family = AF_INET; +- them.sin_port = htons((unsigned short)port); +- addr = (unsigned long) +- ((unsigned long)ip[0] << 24L) | +- ((unsigned long)ip[1] << 16L) | +- ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]); +- them.sin_addr.s_addr = htonl(addr); +- +- if (type == SOCK_STREAM) +- s = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); +- else /* ( type == SOCK_DGRAM) */ +- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); +- +- if (s == INVALID_SOCKET) { +- perror("socket"); ++ memset(&hints, '\0', sizeof(hints)); ++ hints.ai_socktype = type; ++ hints.ai_flags = AI_ADDRCONFIG; ++ ++ e = getaddrinfo(host, port, &hints, &res); ++ if (e) { ++ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); ++ if (e == EAI_SYSTEM) ++ perror("getaddrinfo"); + return (0); + } ++ ++ res0 = res; ++ while (res) { ++ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); ++ if (s == INVALID_SOCKET) { ++ failed_call = "socket"; ++ goto nextres; ++ } + # if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) +- if (type == SOCK_STREAM) { +- i = 0; +- i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i)); +- if (i < 0) { +- closesocket(s); +- perror("keepalive"); +- return (0); ++ if (type == SOCK_STREAM) { ++ int i = 0; ++ i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, ++ (char *)&i, sizeof(i)); ++ if (i < 0) { ++ failed_call = "keepalive"; ++ goto nextres; ++ } + } +- } + # endif +- +- if (connect(s, (struct sockaddr *)&them, sizeof(them)) == -1) { +- closesocket(s); +- perror("connect"); +- return (0); ++ if (connect(s, (struct sockaddr *)res->ai_addr, res->ai_addrlen) == 0) { ++ freeaddrinfo(res0); ++ *sock = s; ++ return (1); ++ } ++ ++ failed_call = "socket"; ++ nextres: ++ if (s != INVALID_SOCKET) ++ close(s); ++ res = res->ai_next; + } +- *sock = s; +- return (1); ++ freeaddrinfo(res0); ++ closesocket(s); ++ ++ perror(failed_call); ++ return (0); + } + +-int do_server(int port, int type, int *ret, ++int do_server(char *port, int type, int *ret, + int (*cb) (char *hostname, int s, int stype, + unsigned char *context), unsigned char *context, + int naccept) +@@ -328,69 +327,89 @@ int do_server(int port, int type, int *r + } + } + +-static int init_server_long(int *sock, int port, char *ip, int type) ++static int init_server(int *sock, char *port, int type) + { +- int ret = 0; +- struct sockaddr_in server; +- int s = -1; ++ struct addrinfo *res, *res0 = NULL, hints; ++ char *failed_call = NULL; ++ int s = INVALID_SOCKET; ++ int e; + + if (!ssl_sock_init()) + return (0); + +- memset((char *)&server, 0, sizeof(server)); +- server.sin_family = AF_INET; +- server.sin_port = htons((unsigned short)port); +- if (ip == NULL) +- server.sin_addr.s_addr = INADDR_ANY; +- else +-/* Added for T3E, address-of fails on bit field (beckman@acl.lanl.gov) */ +-# ifndef BIT_FIELD_LIMITS +- memcpy(&server.sin_addr.s_addr, ip, 4); +-# else +- memcpy(&server.sin_addr, ip, 4); +-# endif +- +- if (type == SOCK_STREAM) +- s = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); +- else /* type == SOCK_DGRAM */ +- s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ memset(&hints, '\0', sizeof(hints)); ++ hints.ai_family = AF_INET6; ++ tryipv4: ++ hints.ai_socktype = type; ++ hints.ai_flags = AI_PASSIVE; ++ ++ e = getaddrinfo(NULL, port, &hints, &res); ++ if (e) { ++ if (hints.ai_family == AF_INET) { ++ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); ++ if (e == EAI_SYSTEM) ++ perror("getaddrinfo"); ++ return (0); ++ } else ++ res = NULL; ++ } + +- if (s == INVALID_SOCKET) +- goto err; ++ res0 = res; ++ while (res) { ++ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); ++ if (s == INVALID_SOCKET) { ++ failed_call = "socket"; ++ goto nextres; ++ } ++ if (hints.ai_family == AF_INET6) { ++ int j = 0; ++ setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&j, sizeof j); ++ } + # if defined SOL_SOCKET && defined SO_REUSEADDR +- { +- int j = 1; +- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j); +- } +-# endif +- if (bind(s, (struct sockaddr *)&server, sizeof(server)) == -1) { +-# ifndef OPENSSL_SYS_WINDOWS +- perror("bind"); ++ { ++ int j = 1; ++ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&j, sizeof j); ++ } + # endif +- goto err; ++ ++ if (bind(s, (struct sockaddr *)res->ai_addr, res->ai_addrlen) == -1) { ++ failed_call = "bind"; ++ goto nextres; ++ } ++ if (type == SOCK_STREAM && listen(s, 128) == -1) { ++ failed_call = "listen"; ++ goto nextres; ++ } ++ ++ *sock = s; ++ return (1); ++ ++ nextres: ++ if (s != INVALID_SOCKET) ++ close(s); ++ res = res->ai_next; + } +- /* Make it 128 for linux */ +- if (type == SOCK_STREAM && listen(s, 128) == -1) +- goto err; +- *sock = s; +- ret = 1; +- err: +- if ((ret == 0) && (s != -1)) { +- SHUTDOWN(s); ++ if (res0) ++ freeaddrinfo(res0); ++ ++ if (s == INVALID_SOCKET) { ++ if (hints.ai_family == AF_INET6) { ++ hints.ai_family = AF_INET; ++ goto tryipv4; ++ } ++ perror("socket"); ++ return (0); + } +- return (ret); +-} + +-static int init_server(int *sock, int port, int type) +-{ +- return (init_server_long(sock, port, NULL, type)); ++ perror(failed_call); ++ return (0); + } + + static int do_accept(int acc_sock, int *sock, char **host) + { ++ static struct sockaddr_storage from; ++ char buffer[NI_MAXHOST]; + int ret; +- struct hostent *h1, *h2; +- static struct sockaddr_in from; + int len; + /* struct linger ling; */ + +@@ -432,134 +451,60 @@ static int do_accept(int acc_sock, int * + ling.l_onoff=1; + ling.l_linger=0; + i=setsockopt(ret,SOL_SOCKET,SO_LINGER,(char *)&ling,sizeof(ling)); +- if (i < 0) { perror("linger"); return(0); } ++ if (i < 0) { closesocket(ret); perror("linger"); return(0); } + i=0; + i=setsockopt(ret,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i)); +- if (i < 0) { perror("keepalive"); return(0); } ++ if (i < 0) { closesocket(ret); perror("keepalive"); return(0); } + */ + + if (host == NULL) + goto end; +-# ifndef BIT_FIELD_LIMITS +- /* I should use WSAAsyncGetHostByName() under windows */ +- h1 = gethostbyaddr((char *)&from.sin_addr.s_addr, +- sizeof(from.sin_addr.s_addr), AF_INET); +-# else +- h1 = gethostbyaddr((char *)&from.sin_addr, +- sizeof(struct in_addr), AF_INET); +-# endif +- if (h1 == NULL) { +- BIO_printf(bio_err, "bad gethostbyaddr\n"); ++ ++ if (getnameinfo((struct sockaddr *)&from, sizeof(from), ++ buffer, sizeof(buffer), NULL, 0, 0)) { ++ BIO_printf(bio_err, "getnameinfo failed\n"); + *host = NULL; + /* return(0); */ + } else { +- if ((*host = (char *)OPENSSL_malloc(strlen(h1->h_name) + 1)) == NULL) { ++ if ((*host = (char *)OPENSSL_malloc(strlen(buffer) + 1)) == NULL) { + perror("OPENSSL_malloc"); + closesocket(ret); + return (0); + } +- BUF_strlcpy(*host, h1->h_name, strlen(h1->h_name) + 1); +- +- h2 = GetHostByName(*host); +- if (h2 == NULL) { +- BIO_printf(bio_err, "gethostbyname failure\n"); +- closesocket(ret); +- return (0); +- } +- if (h2->h_addrtype != AF_INET) { +- BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n"); +- closesocket(ret); +- return (0); +- } ++ strcpy(*host, buffer); + } + end: + *sock = ret; + return (1); + } + +-int extract_host_port(char *str, char **host_ptr, unsigned char *ip, +- short *port_ptr) ++int extract_host_port(char *str, char **host_ptr, char **port_ptr) + { +- char *h, *p; ++ char *h, *p, *x; + +- h = str; +- p = strchr(str, ':'); ++ x = h = str; ++ if (*h == '[') { ++ h++; ++ p = strchr(h, ']'); ++ if (p == NULL) { ++ BIO_printf(bio_err, "no ending bracket for IPv6 address\n"); ++ return (0); ++ } ++ *(p++) = '\0'; ++ x = p; ++ } ++ p = strchr(x, ':'); + if (p == NULL) { + BIO_printf(bio_err, "no port defined\n"); + return (0); + } + *(p++) = '\0'; + +- if ((ip != NULL) && !host_ip(str, ip)) +- goto err; + if (host_ptr != NULL) + *host_ptr = h; ++ if (port_ptr != NULL) ++ *port_ptr = p; + +- if (!extract_port(p, port_ptr)) +- goto err; +- return (1); +- err: +- return (0); +-} +- +-static int host_ip(char *str, unsigned char ip[4]) +-{ +- unsigned int in[4]; +- int i; +- +- if (sscanf(str, "%u.%u.%u.%u", &(in[0]), &(in[1]), &(in[2]), &(in[3])) == +- 4) { +- for (i = 0; i < 4; i++) +- if (in[i] > 255) { +- BIO_printf(bio_err, "invalid IP address\n"); +- goto err; +- } +- ip[0] = in[0]; +- ip[1] = in[1]; +- ip[2] = in[2]; +- ip[3] = in[3]; +- } else { /* do a gethostbyname */ +- struct hostent *he; +- +- if (!ssl_sock_init()) +- return (0); +- +- he = GetHostByName(str); +- if (he == NULL) { +- BIO_printf(bio_err, "gethostbyname failure\n"); +- goto err; +- } +- /* cast to short because of win16 winsock definition */ +- if ((short)he->h_addrtype != AF_INET) { +- BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n"); +- return (0); +- } +- ip[0] = he->h_addr_list[0][0]; +- ip[1] = he->h_addr_list[0][1]; +- ip[2] = he->h_addr_list[0][2]; +- ip[3] = he->h_addr_list[0][3]; +- } +- return (1); +- err: +- return (0); +-} +- +-int extract_port(char *str, short *port_ptr) +-{ +- int i; +- struct servent *s; +- +- i = atoi(str); +- if (i != 0) +- *port_ptr = (unsigned short)i; +- else { +- s = getservbyname(str, "tcp"); +- if (s == NULL) { +- BIO_printf(bio_err, "getservbyname failure for %s\n", str); +- return (0); +- } +- *port_ptr = ntohs((unsigned short)s->s_port); +- } + return (1); + } + diff --git a/SOURCES/openssl-1.0.2a-issuer-hash.patch b/SOURCES/openssl-1.0.2a-issuer-hash.patch new file mode 100644 index 0000000..a439d14 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-no-rpath.patch b/SOURCES/openssl-1.0.2a-no-rpath.patch new file mode 100644 index 0000000..4aafefd --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-padlock64.patch b/SOURCES/openssl-1.0.2a-padlock64.patch new file mode 100644 index 0000000..19d3958 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-readme-warning.patch b/SOURCES/openssl-1.0.2a-readme-warning.patch new file mode 100644 index 0000000..7069989 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-rsa-x931.patch b/SOURCES/openssl-1.0.2a-rsa-x931.patch new file mode 100644 index 0000000..4de716a --- /dev/null +++ b/SOURCES/openssl-1.0.2a-rsa-x931.patch @@ -0,0 +1,35 @@ +diff -up openssl-1.0.2a/apps/genrsa.c.x931 openssl-1.0.2a/apps/genrsa.c +--- openssl-1.0.2a/apps/genrsa.c.x931 2015-04-09 18:18:24.132107287 +0200 ++++ openssl-1.0.2a/apps/genrsa.c 2015-04-09 18:18:18.852985339 +0200 +@@ -97,6 +97,7 @@ int MAIN(int argc, char **argv) + int ret = 1; + int i, num = DEFBITS; + long l; ++ int use_x931 = 0; + const EVP_CIPHER *enc = NULL; + unsigned long f4 = RSA_F4; + char *outfile = NULL; +@@ -139,6 +140,8 @@ int MAIN(int argc, char **argv) + f4 = 3; + else if (strcmp(*argv, "-F4") == 0 || strcmp(*argv, "-f4") == 0) + f4 = RSA_F4; ++ else if (strcmp(*argv, "-x931") == 0) ++ use_x931 = 1; + # ifndef OPENSSL_NO_ENGINE + else if (strcmp(*argv, "-engine") == 0) { + if (--argc < 1) +@@ -278,7 +281,13 @@ int MAIN(int argc, char **argv) + if (!rsa) + goto err; + +- if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb)) ++ if (use_x931) { ++ if (!BN_set_word(bn, f4)) ++ goto err; ++ if (!RSA_X931_generate_key_ex(rsa, num, bn, &cb)) ++ goto err; ++ } else if (!BN_set_word(bn, f4) ++ || !RSA_generate_key_ex(rsa, num, bn, &cb)) + goto err; + + app_RAND_write_file(NULL, bio_err); diff --git a/SOURCES/openssl-1.0.2a-test-use-localhost.patch b/SOURCES/openssl-1.0.2a-test-use-localhost.patch new file mode 100644 index 0000000..4510e6e --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-version-add-engines.patch b/SOURCES/openssl-1.0.2a-version-add-engines.patch new file mode 100644 index 0000000..b7936b3 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2a-version.patch b/SOURCES/openssl-1.0.2a-version.patch new file mode 100644 index 0000000..25dfff5 --- /dev/null +++ b/SOURCES/openssl-1.0.2a-version.patch @@ -0,0 +1,83 @@ +diff -up openssl-1.0.2a/crypto/cversion.c.version openssl-1.0.2a/crypto/cversion.c +--- openssl-1.0.2a/crypto/cversion.c.version 2015-03-19 14:30:36.000000000 +0100 ++++ openssl-1.0.2a/crypto/cversion.c 2015-04-21 16:48:56.285535316 +0200 +@@ -62,7 +62,7 @@ + # include "buildinf.h" + #endif + +-const char *SSLeay_version(int t) ++const char *_current_SSLeay_version(int t) + { + if (t == SSLEAY_VERSION) + return OPENSSL_VERSION_TEXT; +@@ -101,7 +101,40 @@ const char *SSLeay_version(int t) + return ("not available"); + } + +-unsigned long SSLeay(void) ++const char *_original_SSLeay_version(int t) ++{ ++ if (t == SSLEAY_VERSION) ++ return "OpenSSL 1.0.0-fips 29 Mar 2010"; ++ else ++ return _current_SSLeay_version(t); ++} ++ ++const char *_original101_SSLeay_version(int t) ++{ ++ if (t == SSLEAY_VERSION) ++ return "OpenSSL 1.0.1e-fips 11 Feb 2013"; ++ else ++ return _current_SSLeay_version(t); ++} ++ ++unsigned long _original_SSLeay(void) ++{ ++ return (0x10000003L); ++} ++ ++unsigned long _original101_SSLeay(void) ++{ ++ return (0x1000105fL); ++} ++ ++unsigned long _current_SSLeay(void) + { + return (SSLEAY_VERSION_NUMBER); + } ++ ++__asm__(".symver _original_SSLeay,SSLeay@"); ++__asm__(".symver _original_SSLeay_version,SSLeay_version@"); ++__asm__(".symver _original101_SSLeay,SSLeay@OPENSSL_1.0.1"); ++__asm__(".symver _original101_SSLeay_version,SSLeay_version@OPENSSL_1.0.1"); ++__asm__(".symver _current_SSLeay,SSLeay@@OPENSSL_1.0.2"); ++__asm__(".symver _current_SSLeay_version,SSLeay_version@@OPENSSL_1.0.2"); +diff -up openssl-1.0.2a/Makefile.shared.version openssl-1.0.2a/Makefile.shared +--- openssl-1.0.2a/Makefile.shared.version 2015-04-21 16:43:02.624170648 +0200 ++++ openssl-1.0.2a/Makefile.shared 2015-04-21 16:43:02.676171879 +0200 +@@ -151,7 +151,7 @@ DO_GNU_SO=$(CALC_VERSIONS); \ + SHLIB_SUFFIX=; \ + ALLSYMSFLAGS='-Wl,--whole-archive'; \ + NOALLSYMSFLAGS='-Wl,--no-whole-archive'; \ +- SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX" ++ SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -shared -Wl,-Bsymbolic -Wl,--default-symver,--version-script=version.map -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX" + + DO_GNU_APP=LDFLAGS="$(CFLAGS)" + +diff -up openssl-1.0.2a/version.map.version openssl-1.0.2a/version.map +--- openssl-1.0.2a/version.map.version 2015-04-21 16:43:02.676171879 +0200 ++++ openssl-1.0.2a/version.map 2015-04-21 16:51:49.621630589 +0200 +@@ -0,0 +1,13 @@ ++OPENSSL_1.0.1 { ++ global: ++ SSLeay; ++ SSLeay_version; ++ local: ++ _original*; ++ _current*; ++}; ++OPENSSL_1.0.2 { ++ global: ++ SSLeay; ++ SSLeay_version; ++} OPENSSL_1.0.1; diff --git a/SOURCES/openssl-1.0.2a-x509.patch b/SOURCES/openssl-1.0.2a-x509.patch new file mode 100644 index 0000000..7c96a57 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2c-default-paths.patch b/SOURCES/openssl-1.0.2c-default-paths.patch new file mode 100644 index 0000000..aa607be --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2c-ecc-suiteb.patch b/SOURCES/openssl-1.0.2c-ecc-suiteb.patch new file mode 100644 index 0000000..dfcae76 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2d-secp256k1.patch b/SOURCES/openssl-1.0.2d-secp256k1.patch new file mode 100644 index 0000000..4c94133 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2e-remove-nistp224.patch b/SOURCES/openssl-1.0.2e-remove-nistp224.patch new file mode 100644 index 0000000..22b99c1 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2e-rpmbuild.patch b/SOURCES/openssl-1.0.2e-rpmbuild.patch new file mode 100644 index 0000000..db1460c --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2e-speed-doc.patch b/SOURCES/openssl-1.0.2e-speed-doc.patch new file mode 100644 index 0000000..8e3d95b --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2e-wrap-pad.patch b/SOURCES/openssl-1.0.2e-wrap-pad.patch new file mode 100644 index 0000000..fad043c --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2g-manfix.patch b/SOURCES/openssl-1.0.2g-manfix.patch new file mode 100644 index 0000000..12e5103 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2h-pkgconfig.patch b/SOURCES/openssl-1.0.2h-pkgconfig.patch new file mode 100644 index 0000000..f810157 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2i-chil-fixes.patch b/SOURCES/openssl-1.0.2i-chil-fixes.patch new file mode 100644 index 0000000..c7f1820 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2i-enc-fail.patch b/SOURCES/openssl-1.0.2i-enc-fail.patch new file mode 100644 index 0000000..819a3fc --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2i-enginesdir.patch b/SOURCES/openssl-1.0.2i-enginesdir.patch new file mode 100644 index 0000000..862ef1b --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2i-fips.patch b/SOURCES/openssl-1.0.2i-fips.patch new file mode 100644 index 0000000..9a2dd6c --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2i-secure-getenv.patch b/SOURCES/openssl-1.0.2i-secure-getenv.patch new file mode 100644 index 0000000..da8728e --- /dev/null +++ b/SOURCES/openssl-1.0.2i-secure-getenv.patch @@ -0,0 +1,241 @@ +diff -up openssl-1.0.2i/crypto/conf/conf_api.c.secure-getenv openssl-1.0.2i/crypto/conf/conf_api.c +--- openssl-1.0.2i/crypto/conf/conf_api.c.secure-getenv 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/conf/conf_api.c 2016-09-22 13:51:29.847742209 +0200 +@@ -63,6 +63,8 @@ + # define NDEBUG + #endif + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -141,7 +143,7 @@ char *_CONF_get_string(const CONF *conf, + if (v != NULL) + return (v->value); + if (strcmp(section, "ENV") == 0) { +- p = getenv(name); ++ p = secure_getenv(name); + if (p != NULL) + return (p); + } +@@ -154,7 +156,7 @@ char *_CONF_get_string(const CONF *conf, + else + return (NULL); + } else +- return (getenv(name)); ++ return (secure_getenv(name)); + } + + #if 0 /* There's no way to provide error checking +diff -up openssl-1.0.2i/crypto/conf/conf_mod.c.secure-getenv openssl-1.0.2i/crypto/conf/conf_mod.c +--- openssl-1.0.2i/crypto/conf/conf_mod.c.secure-getenv 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/conf/conf_mod.c 2016-09-22 13:51:29.847742209 +0200 +@@ -57,6 +57,8 @@ + * + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -530,7 +532,7 @@ char *CONF_get1_default_config_file(void + char *file; + int len; + +- file = getenv("OPENSSL_CONF"); ++ file = secure_getenv("OPENSSL_CONF"); + if (file) + return BUF_strdup(file); + +diff -up openssl-1.0.2i/crypto/engine/eng_list.c.secure-getenv openssl-1.0.2i/crypto/engine/eng_list.c +--- openssl-1.0.2i/crypto/engine/eng_list.c.secure-getenv 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/engine/eng_list.c 2016-09-22 13:51:29.847742209 +0200 +@@ -62,6 +62,8 @@ + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include "eng_int.h" + + /* +@@ -369,10 +371,10 @@ ENGINE *ENGINE_by_id(const char *id) + */ + if (strcmp(id, "dynamic")) { + # ifdef OPENSSL_SYS_VMS +- if ((load_dir = getenv("OPENSSL_ENGINES")) == 0) ++ if (OPENSSL_issetugid() || (load_dir = getenv("OPENSSL_ENGINES")) == 0) + load_dir = "SSLROOT:[ENGINES]"; + # else +- if ((load_dir = getenv("OPENSSL_ENGINES")) == 0) ++ if ((load_dir = secure_getenv("OPENSSL_ENGINES")) == 0) + load_dir = ENGINESDIR; + # endif + iterator = ENGINE_by_id("dynamic"); +diff -up openssl-1.0.2i/crypto/md5/md5_dgst.c.secure-getenv openssl-1.0.2i/crypto/md5/md5_dgst.c +--- openssl-1.0.2i/crypto/md5/md5_dgst.c.secure-getenv 2016-09-22 13:51:29.840742047 +0200 ++++ openssl-1.0.2i/crypto/md5/md5_dgst.c 2016-09-22 13:51:29.847742209 +0200 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include "md5_locl.h" + #include +@@ -75,7 +77,8 @@ const char MD5_version[] = "MD5" OPENSSL + int MD5_Init(MD5_CTX *c) + #ifdef OPENSSL_FIPS + { +- if (FIPS_mode() && getenv("OPENSSL_FIPS_NON_APPROVED_MD5_ALLOW") == NULL) ++ if (FIPS_mode() ++ && secure_getenv("OPENSSL_FIPS_NON_APPROVED_MD5_ALLOW") == NULL) + OpenSSLDie(__FILE__, __LINE__, "Digest MD5 forbidden in FIPS mode!"); + return private_MD5_Init(c); + } +diff -up openssl-1.0.2i/crypto/o_init.c.secure-getenv openssl-1.0.2i/crypto/o_init.c +--- openssl-1.0.2i/crypto/o_init.c.secure-getenv 2016-09-22 13:51:29.830741814 +0200 ++++ openssl-1.0.2i/crypto/o_init.c 2016-09-22 13:51:30.046746834 +0200 +@@ -53,6 +53,8 @@ + * + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #ifdef OPENSSL_FIPS +@@ -72,7 +74,7 @@ static void init_fips_mode(void) + char buf[2] = "0"; + int fd; + +- if (getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) { ++ if (secure_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) ; +diff -up openssl-1.0.2i/crypto/rand/randfile.c.secure-getenv openssl-1.0.2i/crypto/rand/randfile.c +--- openssl-1.0.2i/crypto/rand/randfile.c.secure-getenv 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/rand/randfile.c 2016-09-22 13:53:17.222237626 +0200 +@@ -55,6 +55,8 @@ + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ ++/* for secure_getenv */ ++#define _GNU_SOURCE + + #include + #include +@@ -327,14 +329,12 @@ const char *RAND_file_name(char *buf, si + struct stat sb; + #endif + +- if (OPENSSL_issetugid() == 0) +- s = getenv("RANDFILE"); ++ s = secure_getenv("RANDFILE"); + if (s != NULL && *s && strlen(s) + 1 < size) { + if (BUF_strlcpy(buf, s, size) >= size) + return NULL; + } else { +- if (OPENSSL_issetugid() == 0) +- s = getenv("HOME"); ++ s = secure_getenv("HOME"); + #ifdef DEFAULT_HOME + if (s == NULL) { + s = DEFAULT_HOME; +diff -up openssl-1.0.2i/crypto/x509/by_dir.c.secure-getenv openssl-1.0.2i/crypto/x509/by_dir.c +--- openssl-1.0.2i/crypto/x509/by_dir.c.secure-getenv 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/x509/by_dir.c 2016-09-22 13:51:30.047746858 +0200 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -128,7 +130,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, in + switch (cmd) { + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) { +- dir = (char *)getenv(X509_get_default_cert_dir_env()); ++ dir = (char *)secure_getenv(X509_get_default_cert_dir_env()); + if (dir) + ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); + else +diff -up openssl-1.0.2i/crypto/x509/by_file.c.secure-getenv openssl-1.0.2i/crypto/x509/by_file.c +--- openssl-1.0.2i/crypto/x509/by_file.c.secure-getenv 2016-09-22 13:51:29.812741396 +0200 ++++ openssl-1.0.2i/crypto/x509/by_file.c 2016-09-22 13:51:30.047746858 +0200 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -97,7 +99,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx + switch (cmd) { + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) { +- file = (char *)getenv(X509_get_default_cert_file_env()); ++ file = (char *)secure_getenv(X509_get_default_cert_file_env()); + if (file) + ok = (X509_load_cert_crl_file(ctx, file, + X509_FILETYPE_PEM) != 0); +diff -up openssl-1.0.2i/crypto/x509/x509_vfy.c.secure-getenv openssl-1.0.2i/crypto/x509/x509_vfy.c +--- openssl-1.0.2i/crypto/x509/x509_vfy.c.secure-getenv 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/crypto/x509/x509_vfy.c 2016-09-22 13:51:30.048746881 +0200 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -620,7 +622,7 @@ static int check_chain_extensions(X509_S + * A hack to keep people who don't want to modify their software + * happy + */ +- if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) ++ if (secure_getenv("OPENSSL_ALLOW_PROXY_CERTS")) + allow_proxy_certs = 1; + purpose = ctx->param->purpose; + } +diff -up openssl-1.0.2i/engines/ccgost/gost_ctl.c.secure-getenv openssl-1.0.2i/engines/ccgost/gost_ctl.c +--- openssl-1.0.2i/engines/ccgost/gost_ctl.c.secure-getenv 2016-09-22 12:23:06.000000000 +0200 ++++ openssl-1.0.2i/engines/ccgost/gost_ctl.c 2016-09-22 13:51:30.048746881 +0200 +@@ -6,6 +6,8 @@ + * Implementation of control commands for GOST engine * + * OpenSSL 0.9.9 libraries required * + **********************************************************************/ ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -64,7 +66,7 @@ const char *get_gost_engine_param(int pa + if (gost_params[param] != NULL) { + return gost_params[param]; + } +- tmp = getenv(gost_envnames[param]); ++ tmp = secure_getenv(gost_envnames[param]); + if (tmp) { + if (gost_params[param]) + OPENSSL_free(gost_params[param]); +@@ -79,7 +81,7 @@ int gost_set_default_param(int param, co + const char *tmp; + if (param < 0 || param > GOST_PARAM_MAX) + return 0; +- tmp = getenv(gost_envnames[param]); ++ tmp = secure_getenv(gost_envnames[param]); + /* + * if there is value in the environment, use it, else -passed string * + */ diff --git a/SOURCES/openssl-1.0.2i-trusted-first-doc.patch b/SOURCES/openssl-1.0.2i-trusted-first-doc.patch new file mode 100644 index 0000000..12ea01e --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2j-deprecate-algos.patch b/SOURCES/openssl-1.0.2j-deprecate-algos.patch new file mode 100644 index 0000000..cbfb2e9 --- /dev/null +++ b/SOURCES/openssl-1.0.2j-deprecate-algos.patch @@ -0,0 +1,226 @@ +diff -up openssl-1.0.2j/crypto/asn1/a_verify.c.deprecate-algos openssl-1.0.2j/crypto/asn1/a_verify.c +--- openssl-1.0.2j/crypto/asn1/a_verify.c.deprecate-algos 2016-09-26 11:49:07.000000000 +0200 ++++ openssl-1.0.2j/crypto/asn1/a_verify.c 2017-01-09 16:47:11.666994197 +0100 +@@ -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_A + + #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 + 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 -up openssl-1.0.2j/crypto/o_init.c.deprecate-algos openssl-1.0.2j/crypto/o_init.c +--- openssl-1.0.2j/crypto/o_init.c.deprecate-algos 2017-01-05 17:49:00.000000000 +0100 ++++ openssl-1.0.2j/crypto/o_init.c 2017-01-09 16:52:29.018298611 +0100 +@@ -64,11 +64,21 @@ + # include + # include + # include ++# include ++# include ++# include ++# include + # include + # include ++# include ++# include + + # define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled" + ++# define LEGACY_SETTINGS_FILE "/etc/pki/tls/legacy-settings" ++ ++# define NUM_MAX_LEGACY_MDS 8 ++ + static void init_fips_mode(void) + { + char buf[2] = "0"; +@@ -98,6 +108,115 @@ static void init_fips_mode(void) + } + #endif + ++int private_ossl_allowed_legacy_mds[NUM_MAX_LEGACY_MDS + 1]; /* zero terminated */ ++ ++int private_ossl_minimum_dh_bits; ++ ++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); ++} ++ + /* + * Perform any essential OpenSSL initialization operations. Currently only + * sets FIPS callbacks +@@ -109,6 +228,7 @@ void __attribute__ ((constructor)) OPENS + if (done) + return; + done = 1; ++ load_legacy_settings(); + #ifdef OPENSSL_FIPS + if (!FIPS_module_installed()) { + return; +diff -up openssl-1.0.2j/ssl/s3_clnt.c.deprecate-algos openssl-1.0.2j/ssl/s3_clnt.c +--- openssl-1.0.2j/ssl/s3_clnt.c.deprecate-algos 2016-09-26 11:49:07.000000000 +0200 ++++ openssl-1.0.2j/ssl/s3_clnt.c 2017-01-09 17:01:19.428506961 +0100 +@@ -3478,6 +3478,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; +@@ -3608,8 +3610,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/SOURCES/openssl-1.0.2j-downgrade-strength.patch b/SOURCES/openssl-1.0.2j-downgrade-strength.patch new file mode 100644 index 0000000..6e9e387 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2j-krb5keytab.patch b/SOURCES/openssl-1.0.2j-krb5keytab.patch new file mode 100644 index 0000000..9feb8cf --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2j-new-fips-reqs.patch b/SOURCES/openssl-1.0.2j-new-fips-reqs.patch new file mode 100644 index 0000000..2b9ec06 --- /dev/null +++ b/SOURCES/openssl-1.0.2j-new-fips-reqs.patch @@ -0,0 +1,1396 @@ +diff -up openssl-1.0.2j/crypto/bn/bn_rand.c.fips-reqs openssl-1.0.2j/crypto/bn/bn_rand.c +--- openssl-1.0.2j/crypto/bn/bn_rand.c.fips-reqs 2016-09-26 11:49:07.000000000 +0200 ++++ openssl-1.0.2j/crypto/bn/bn_rand.c 2017-01-10 16:25:11.142340595 +0100 +@@ -141,8 +141,11 @@ static int bnrand(int pseudorand, BIGNUM + } + + /* make a random number and set the top and bottom bits */ +- time(&tim); +- RAND_add(&tim, sizeof(tim), 0.0); ++ if (!FIPS_mode()) { ++ /* in FIPS mode the RNG is always properly seeded or the module fails */ ++ time(&tim); ++ RAND_add(&tim, sizeof(tim), 0.0); ++ } + + /* We ignore the value of pseudorand and always call RAND_bytes */ + if (RAND_bytes(buf, bytes) <= 0) +diff -up openssl-1.0.2j/crypto/dh/dh_gen.c.fips-reqs openssl-1.0.2j/crypto/dh/dh_gen.c +--- openssl-1.0.2j/crypto/dh/dh_gen.c.fips-reqs 2017-01-10 16:25:11.099339627 +0100 ++++ openssl-1.0.2j/crypto/dh/dh_gen.c 2017-01-10 16:25:11.142340595 +0100 +@@ -128,7 +128,7 @@ static int dh_builtin_genparams(DH *ret, + return 0; + } + +- if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) { ++ if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN)) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } +diff -up openssl-1.0.2j/crypto/dh/dh.h.fips-reqs openssl-1.0.2j/crypto/dh/dh.h +--- openssl-1.0.2j/crypto/dh/dh.h.fips-reqs 2017-01-10 16:25:11.099339627 +0100 ++++ openssl-1.0.2j/crypto/dh/dh.h 2017-01-10 16:25:11.142340595 +0100 +@@ -78,6 +78,7 @@ + # endif + + # define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 ++# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN 2048 + + # define DH_FLAG_CACHE_MONT_P 0x01 + +diff -up openssl-1.0.2j/crypto/dsa/dsa_gen.c.fips-reqs openssl-1.0.2j/crypto/dsa/dsa_gen.c +--- openssl-1.0.2j/crypto/dsa/dsa_gen.c.fips-reqs 2017-01-10 16:25:11.100339650 +0100 ++++ openssl-1.0.2j/crypto/dsa/dsa_gen.c 2017-01-10 16:25:11.143340618 +0100 +@@ -157,9 +157,11 @@ int dsa_builtin_paramgen(DSA *ret, size_ + } + + if (FIPS_module_mode() && +- (bits != 1024 || qbits != 160) && +- (bits != 2048 || qbits != 224) && +- (bits != 2048 || qbits != 256) && (bits != 3072 || qbits != 256)) { ++ (getenv("OPENSSL_ENFORCE_MODULUS_BITS") || 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; + } +diff -up openssl-1.0.2j/crypto/dsa/dsa.h.fips-reqs openssl-1.0.2j/crypto/dsa/dsa.h +--- openssl-1.0.2j/crypto/dsa/dsa.h.fips-reqs 2017-01-10 16:25:11.100339650 +0100 ++++ openssl-1.0.2j/crypto/dsa/dsa.h 2017-01-10 16:25:11.143340618 +0100 +@@ -89,6 +89,7 @@ + # endif + + # define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 ++# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS_GEN (getenv("OPENSSL_ENFORCE_MODULUS_BITS")?2048:1024) + + # define DSA_FLAG_CACHE_MONT_P 0x01 + /* +@@ -251,9 +252,9 @@ int DSAparams_print_fp(FILE *fp, const D + int DSA_print_fp(FILE *bp, const DSA *x, int off); + # endif + +-# define DSS_prime_checks 50 ++# define DSS_prime_checks 64 + /* +- * Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of ++ * Primality test according to FIPS PUB 186-4, Appendix 2.1: 64 rounds of + * Rabin-Miller + */ + # define DSA_is_prime(n, callback, cb_arg) \ +diff -up openssl-1.0.2j/crypto/dsa/dsa_key.c.fips-reqs openssl-1.0.2j/crypto/dsa/dsa_key.c +--- openssl-1.0.2j/crypto/dsa/dsa_key.c.fips-reqs 2017-01-10 16:25:11.141340573 +0100 ++++ openssl-1.0.2j/crypto/dsa/dsa_key.c 2017-01-10 16:25:11.143340618 +0100 +@@ -125,7 +125,7 @@ static int dsa_builtin_keygen(DSA *dsa) + + # ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW) +- && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { ++ && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS_GEN)) { + DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } +diff -up openssl-1.0.2j/crypto/evp/e_aes.c.fips-reqs openssl-1.0.2j/crypto/evp/e_aes.c +--- openssl-1.0.2j/crypto/evp/e_aes.c.fips-reqs 2017-01-10 16:25:11.102339695 +0100 ++++ openssl-1.0.2j/crypto/evp/e_aes.c 2017-01-10 16:25:11.143340618 +0100 +@@ -381,6 +381,8 @@ static int aesni_xts_init_key(EVP_CIPHER + + if (key) { + /* key_len is two AES keys */ ++ if (FIPS_module_mode() && memcmp(key, key + ctx->key_len / 2, ctx->key_len / 2) == 0) ++ return 0; + if (enc) { + aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) aesni_encrypt; +@@ -701,6 +703,9 @@ static int aes_t4_xts_init_key(EVP_CIPHE + + if (key) { + int bits = ctx->key_len * 4; ++ ++ if (FIPS_module_mode() && memcmp(key, key + ctx->key_len / 2, ctx->key_len / 2) == 0) ++ return 0; + xctx->stream = NULL; + /* key_len is two AES keys */ + if (enc) { +@@ -1645,6 +1650,8 @@ static int aes_xts_init_key(EVP_CIPHER_C + + if (key) + do { ++ if (FIPS_module_mode() && memcmp(key, key + ctx->key_len / 2, ctx->key_len / 2) == 0) ++ return 0; + # ifdef AES_XTS_ASM + xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; + # else +diff -up openssl-1.0.2j/crypto/fips/fips.c.fips-reqs openssl-1.0.2j/crypto/fips/fips.c +--- openssl-1.0.2j/crypto/fips/fips.c.fips-reqs 2017-01-10 16:25:11.141340573 +0100 ++++ openssl-1.0.2j/crypto/fips/fips.c 2017-01-10 16:25:11.143340618 +0100 +@@ -424,26 +424,24 @@ int FIPS_module_mode_set(int onoff, cons + ret = 0; + goto end; + } +- OPENSSL_ia32cap_P[0] |= (1 << 28); /* set "shared cache" */ +- OPENSSL_ia32cap_P[1] &= ~(1 << (60 - 32)); /* clear AVX */ + } + # endif + +- if (!verify_checksums()) { +- FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, +- FIPS_R_FINGERPRINT_DOES_NOT_MATCH); ++ if (!FIPS_selftest()) { + fips_selftest_fail = 1; + ret = 0; + goto end; + } + +- if (FIPS_selftest()) +- fips_set_mode(onoff); +- else { ++ if (!verify_checksums()) { ++ FIPSerr(FIPS_F_FIPS_MODULE_MODE_SET, ++ FIPS_R_FINGERPRINT_DOES_NOT_MATCH); + fips_selftest_fail = 1; + ret = 0; + goto end; + } ++ ++ fips_set_mode(onoff); + ret = 1; + goto end; + } +diff -up openssl-1.0.2j/crypto/fips/fips_dh_selftest.c.fips-reqs openssl-1.0.2j/crypto/fips/fips_dh_selftest.c +--- openssl-1.0.2j/crypto/fips/fips_dh_selftest.c.fips-reqs 2017-01-10 16:25:11.143340618 +0100 ++++ openssl-1.0.2j/crypto/fips/fips_dh_selftest.c 2017-01-10 16:25:11.143340618 +0100 +@@ -0,0 +1,162 @@ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 2013 Red Hat, Inc. ++ * ++ * 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 dh_test_2048_p[] = { ++ 0xAE, 0xEC, 0xEE, 0x22, 0xFA, 0x3A, 0xA5, 0x22, 0xC0, 0xDE, 0x0F, 0x09, ++ 0x7E, 0x17, 0xC0, 0x05, 0xF9, 0xF1, 0xE7, 0xC6, 0x87, 0x14, 0x6D, 0x11, ++ 0xE7, 0xAE, 0xED, 0x2F, 0x72, 0x59, 0xC5, 0xA9, 0x9B, 0xB8, 0x02, 0xA5, ++ 0xF3, 0x69, 0x70, 0xD6, 0xDD, 0x90, 0xF9, 0x19, 0x79, 0xBE, 0x60, 0x8F, ++ 0x25, 0x92, 0x30, 0x1C, 0x51, 0x51, 0x38, 0x26, 0x82, 0x25, 0xE6, 0xFC, ++ 0xED, 0x65, 0x96, 0x8F, 0x57, 0xE5, 0x53, 0x8B, 0x38, 0x63, 0xC7, 0xCE, ++ 0xBC, 0x1B, 0x4D, 0x18, 0x2A, 0x5B, 0x04, 0x3F, 0x6A, 0x3C, 0x94, 0x39, ++ 0xAE, 0x36, 0xD6, 0x5E, 0x0F, 0xA2, 0xCC, 0xD0, 0xD4, 0xD5, 0xC6, 0x1E, ++ 0xF6, 0xA0, 0xF5, 0x89, 0x4E, 0xB4, 0x0B, 0xA4, 0xB3, 0x2B, 0x3D, 0xE2, ++ 0x4E, 0xE1, 0x49, 0x25, 0x99, 0x5F, 0x32, 0x16, 0x33, 0x32, 0x1B, 0x7A, ++ 0xA5, 0x5C, 0x6B, 0x34, 0x0D, 0x39, 0x99, 0xDC, 0xF0, 0x76, 0xE5, 0x5A, ++ 0xD4, 0x71, 0x00, 0xED, 0x5A, 0x73, 0xFB, 0xC8, 0x01, 0xAD, 0x99, 0xCF, ++ 0x99, 0x52, 0x7C, 0x9C, 0x64, 0xC6, 0x76, 0x40, 0x57, 0xAF, 0x59, 0xD7, ++ 0x38, 0x0B, 0x40, 0xDE, 0x33, 0x0D, 0xB8, 0x76, 0xEC, 0xA9, 0xD8, 0x73, ++ 0xF8, 0xEF, 0x26, 0x66, 0x06, 0x27, 0xDD, 0x7C, 0xA4, 0x10, 0x9C, 0xA6, ++ 0xAA, 0xF9, 0x53, 0x62, 0x73, 0x1D, 0xBA, 0x1C, 0xF1, 0x67, 0xF4, 0x35, ++ 0xED, 0x6F, 0x37, 0x92, 0xE8, 0x4F, 0x6C, 0xBA, 0x52, 0x6E, 0xA1, 0xED, ++ 0xDA, 0x9F, 0x85, 0x11, 0x82, 0x52, 0x62, 0x08, 0x44, 0xF1, 0x30, 0x03, ++ 0xC3, 0x38, 0x2C, 0x79, 0xBD, 0xD4, 0x43, 0x45, 0xEE, 0x8E, 0x50, 0xFC, ++ 0x29, 0x46, 0x9A, 0xFE, 0x54, 0x1A, 0x19, 0x8F, 0x4B, 0x84, 0x08, 0xDE, ++ 0x20, 0x62, 0x73, 0xCC, 0xDD, 0x7E, 0xF0, 0xEF, 0xA2, 0xFD, 0x86, 0x58, ++ 0x4B, 0xD8, 0x37, 0xEB ++}; ++ ++static const unsigned char dh_test_2048_g[] = { ++ 0x02 ++}; ++ ++static const unsigned char dh_test_2048_pub_key[] = { ++ 0xA0, 0x39, 0x11, 0x77, 0x9A, 0xC1, 0x30, 0x1F, 0xBE, 0x48, 0xA7, 0xAA, ++ 0xA0, 0x84, 0x54, 0x64, 0xAD, 0x1B, 0x70, 0xFA, 0x13, 0x55, 0x63, 0xD2, ++ 0x1F, 0x62, 0x32, 0x93, 0x8E, 0xC9, 0x3E, 0x09, 0xA7, 0x64, 0xE4, 0x12, ++ 0x6E, 0x1B, 0xF2, 0x92, 0x3B, 0xB9, 0xCB, 0x56, 0xEA, 0x07, 0x88, 0xB5, ++ 0xA6, 0xBC, 0x16, 0x1F, 0x27, 0xFE, 0xD8, 0xAA, 0x40, 0xB2, 0xB0, 0x2D, ++ 0x37, 0x76, 0xA6, 0xA4, 0x82, 0x2C, 0x0E, 0x22, 0x64, 0x9D, 0xCB, 0xD1, ++ 0x00, 0xB7, 0x89, 0x14, 0x72, 0x4E, 0xBE, 0x48, 0x41, 0xF8, 0xB2, 0x51, ++ 0x11, 0x09, 0x4B, 0x22, 0x01, 0x23, 0x39, 0x96, 0xE0, 0x15, 0xD7, 0x9F, ++ 0x60, 0xD1, 0xB7, 0xAE, 0xFE, 0x5F, 0xDB, 0xE7, 0x03, 0x17, 0x97, 0xA6, ++ 0x16, 0x74, 0xBD, 0x53, 0x81, 0x19, 0xC5, 0x47, 0x5E, 0xCE, 0x8D, 0xED, ++ 0x45, 0x5D, 0x3C, 0x00, 0xA0, 0x0A, 0x68, 0x6A, 0xE0, 0x8E, 0x06, 0x46, ++ 0x6F, 0xD7, 0xF9, 0xDF, 0x31, 0x7E, 0x77, 0x44, 0x0D, 0x98, 0xE0, 0xCA, ++ 0x98, 0x09, 0x52, 0x04, 0x90, 0xEA, 0x6D, 0xF4, 0x30, 0x69, 0x8F, 0xB1, ++ 0x9B, 0xC1, 0x43, 0xDB, 0xD5, 0x8D, 0xC8, 0x8E, 0xB6, 0x0B, 0x05, 0xBE, ++ 0x0E, 0xC5, 0x99, 0xC8, 0x6E, 0x4E, 0xF3, 0xCB, 0xC3, 0x5E, 0x9B, 0x53, ++ 0xF7, 0x06, 0x1C, 0x4F, 0xC7, 0xB8, 0x6E, 0x30, 0x18, 0xCA, 0x9B, 0xB9, ++ 0xBC, 0x5F, 0x17, 0x72, 0x29, 0x5A, 0xE5, 0xD9, 0x96, 0xB7, 0x0B, 0xF3, ++ 0x2D, 0x8C, 0xF1, 0xE1, 0x0E, 0x0D, 0x74, 0xD5, 0x9D, 0xF0, 0x06, 0xA9, ++ 0xB4, 0x95, 0x63, 0x76, 0x46, 0x55, 0x48, 0x82, 0x39, 0x90, 0xEF, 0x56, ++ 0x75, 0x34, 0xB8, 0x34, 0xC3, 0x18, 0x6E, 0x1E, 0xAD, 0xE3, 0x48, 0x7E, ++ 0x93, 0x2C, 0x23, 0xE7, 0xF8, 0x90, 0x73, 0xB1, 0x77, 0x80, 0x67, 0xA9, ++ 0x36, 0x9E, 0xDA, 0xD2 ++}; ++ ++static const unsigned char dh_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 ++}; ++ ++int FIPS_selftest_dh() ++{ ++ DH *dh = NULL; ++ int ret = 0; ++ void *pub_key = NULL; ++ int len; ++ ++ dh = DH_new(); ++ ++ if (dh == NULL) ++ goto err; ++ ++ fips_load_key_component(dh, p, dh_test_2048); ++ fips_load_key_component(dh, g, dh_test_2048); ++ /* note that the private key is much shorter than normally used ++ * but still g ** priv_key > p ++ */ ++ fips_load_key_component(dh, priv_key, dh_test_2048); ++ ++ if (DH_generate_key(dh) <= 0) ++ goto err; ++ ++ len = BN_num_bytes(dh->pub_key); ++ if ((pub_key = OPENSSL_malloc(len)) == NULL) ++ goto err; ++ BN_bn2bin(dh->pub_key, pub_key); ++ ++ if (len != sizeof(dh_test_2048_pub_key) || ++ memcmp(pub_key, dh_test_2048_pub_key, len) != 0) ++ goto err; ++ ++ ret = 1; ++ ++ err: ++ if (dh) ++ DH_free(dh); ++ ++ OPENSSL_free(pub_key); ++ return ret; ++} ++#endif +diff -up openssl-1.0.2j/crypto/fips/fips.h.fips-reqs openssl-1.0.2j/crypto/fips/fips.h +--- openssl-1.0.2j/crypto/fips/fips.h.fips-reqs 2017-01-10 16:25:11.137340483 +0100 ++++ openssl-1.0.2j/crypto/fips/fips.h 2017-01-10 16:25:11.144340641 +0100 +@@ -96,6 +96,7 @@ extern "C" { + int FIPS_selftest_dsa(void); + int FIPS_selftest_ecdsa(void); + int FIPS_selftest_ecdh(void); ++ int FIPS_selftest_dh(void); + void FIPS_corrupt_rng(void); + void FIPS_rng_stick(void); + void FIPS_x931_stick(int onoff); +diff -up openssl-1.0.2j/crypto/fips/fips_post.c.fips-reqs openssl-1.0.2j/crypto/fips/fips_post.c +--- openssl-1.0.2j/crypto/fips/fips_post.c.fips-reqs 2017-01-10 16:25:11.134340415 +0100 ++++ openssl-1.0.2j/crypto/fips/fips_post.c 2017-01-10 16:25:11.144340641 +0100 +@@ -99,6 +99,8 @@ int FIPS_selftest(void) + rv = 0; + if (!FIPS_selftest_dsa()) + rv = 0; ++ if (!FIPS_selftest_dh()) ++ rv = 0; + if (!FIPS_selftest_ecdh()) + rv = 0; + return rv; +diff -up openssl-1.0.2j/crypto/fips/fips_rsa_selftest.c.fips-reqs openssl-1.0.2j/crypto/fips/fips_rsa_selftest.c +--- openssl-1.0.2j/crypto/fips/fips_rsa_selftest.c.fips-reqs 2017-01-10 16:25:11.109339852 +0100 ++++ openssl-1.0.2j/crypto/fips/fips_rsa_selftest.c 2017-01-10 16:25:11.144340641 +0100 +@@ -60,68 +60,107 @@ + #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"; ++ "\x00\xc9\xd5\x6d\x9d\x90\xdb\x43\xd6\x02\xed\x96\x88\x13\x8a" ++ "\xb2\xbf\x6e\xa1\x06\x10\xb2\x78\x37\xa7\x14\xa8\xff\xdd\x00" ++ "\xdd\xb4\x93\xa0\x45\xcc\x96\x90\xed\xad\xa9\xdd\xc4\xd6\xca" ++ "\x0c\xf0\xed\x4f\x72\x5e\x21\x49\x9a\x18\x12\x15\x8f\x90\x5a" ++ "\xdb\xb6\x33\x99\xa3\xe6\xb4\xf0\xc4\x97\x21\x26\xbb\xe3\xba" ++ "\xf2\xff\xa0\x72\xda\x89\x63\x8e\x8b\x3e\x08\x9d\x92\x2a\xbe" ++ "\x16\xe1\x43\x15\xfc\x57\xc7\x1f\x09\x11\x67\x1c\xa9\x96\xd1" ++ "\x8b\x3e\x80\x93\xc1\x59\xd0\x6d\x39\xf2\xac\x95\xcc\x10\x75" ++ "\xe9\x31\x24\xd1\x43\xaf\x68\x52\x4b\xe7\x16\xd7\x49\x65\x6f" ++ "\x26\xc0\x86\xad\xc0\x07\x0a\xc1\xe1\x2f\x87\x85\x86\x3b\xdc" ++ "\x5a\x99\xbe\xe9\xf9\xb9\xe9\x82\x27\x51\x04\x15\xab\x06\x0e" ++ "\x76\x5a\x28\x8d\x92\xbd\xc5\xb5\x7b\xa8\xdf\x4e\x47\xa2\xc1" ++ "\xe7\x52\xbf\x47\xf7\x62\xe0\x3a\x6f\x4d\x6a\x4d\x4e\xd4\xb9" ++ "\x59\x69\xfa\xb2\x14\xc1\xee\xe6\x2f\x95\xcd\x94\x72\xae\xe4" ++ "\xdb\x18\x9a\xc4\xcd\x70\xbd\xee\x31\x16\xb7\x49\x65\xac\x40" ++ "\x19\x0e\xb5\x6d\x83\xf1\x36\xbb\x08\x2f\x2e\x4e\x92\x62\xa4" ++ "\xff\x50\xdb\x20\x45\xa2\xeb\x16\x7a\xf2\xd5\x28\xc1\xfd\x4e" "\x03\x71"; + + static int corrupt_rsa; + + static int setrsakey(RSA *key) + { +- static const unsigned char e[] = "\x11"; ++ static const unsigned char e[] = "\x01\x00\x01"; + + 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"; ++ "\x36\x27\x3d\xb1\xf9\x1b\xdb\xa7\xa0\x41\x7f\x12\x23\xac\x23" ++ "\x29\x99\xd5\x3a\x7b\x60\x67\x41\x07\x63\x53\xb4\xd2\xe7\x58" ++ "\x95\x0a\xc7\x05\xf3\x4e\xb2\xb4\x12\xd4\x70\xdc\x4f\x85\x06" ++ "\xd3\xdd\xd8\x63\x27\x3e\x67\x31\x21\x24\x39\x04\xbc\x06\xa4" ++ "\xcc\xce\x2b\x7a\xfe\x7b\xad\xde\x11\x6e\xa3\xa5\xe6\x04\x53" ++ "\x0e\xa3\x4e\x2d\xb4\x8f\x31\xbf\xca\x75\x25\x52\x02\x85\xde" ++ "\x3d\xb2\x72\x43\xb2\x89\x8a\x9a\x34\x41\x26\x3f\x9a\x67\xbe" ++ "\xa4\x96\x7b\x0e\x75\xba\xa6\x93\xd5\xb8\xd8\xb8\x57\xf2\x4b" ++ "\x0f\x14\x81\xd1\x57\x4e\xf6\x45\x4c\xa6\x3b\xd0\x70\xca\xd3" ++ "\x9d\x55\xde\x22\x05\xe7\x8e\x28\x4d\xee\x11\xcf\xb6\x67\x76" ++ "\x09\xd3\xe3\x3c\x13\xf9\x99\x34\x10\x7b\xec\x81\x38\xf0\xb6" ++ "\x34\x9c\x9b\x50\x6f\x0b\x91\x81\x4d\x89\x94\x04\x7b\xf0\x3c" ++ "\xf4\xb1\xb2\x00\x48\x8d\x5a\x8f\x88\x9e\xc5\xab\x3a\x9e\x44" ++ "\x3f\x54\xe7\xd9\x6e\x47\xaa\xa1\xbd\x40\x46\x31\xf9\xf0\x34" ++ "\xb6\x04\xe1\x2b\x5b\x73\x86\xdd\x3a\x92\x1b\x71\xc7\x3f\x32" ++ "\xe5\xc3\xc2\xab\xa1\x7e\xbf\xa4\x52\xa0\xb0\x68\x90\xd1\x20" ++ "\x12\x79\xe9\xd7\xc9\x40\xba\xf2\x19\xc7\xa5\x00\x92\x86\x0d" "\x01"; + + 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"; ++ "\x00\xfc\x5c\x6e\x16\xce\x1f\x03\x7b\xcd\xf7\xb3\x72\xb2\x8f" ++ "\x16\x72\xb8\x56\xae\xf7\xcd\x67\xd8\x4e\x7d\x07\xaf\xd5\x43" ++ "\x26\xc3\x35\xbe\x43\x8f\x4e\x2f\x1c\x43\x4e\x6b\xd2\xb2\xec" ++ "\x52\x6d\x97\x52\x2b\xcc\x5c\x3a\x6b\xf4\x14\xc6\x74\xda\x66" ++ "\x38\x1c\x7a\x3f\x84\x2f\xe3\xf9\x5a\xb8\x65\x69\x46\x06\xa3" ++ "\x37\x79\xb2\xa1\x5b\x58\xed\x5e\xa7\x5f\x8c\x65\x66\xbb\xd1" ++ "\x24\x36\xe6\x37\xa7\x3d\x49\x77\x8a\x8c\x34\xd8\x69\x29\xf3" ++ "\x4d\x58\x22\xb0\x51\x24\xb6\x40\xa8\x86\x59\x0a\xb7\xba\x5c" ++ "\x97\xda\x57\xe8\x36\xda\x7a\x9c\xad"; + + 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"; ++ "\x00\xcc\xbe\x7b\x09\x69\x06\xee\x45\xbf\x88\x47\x38\xa8\xf8" ++ "\x17\xe5\xb6\xba\x67\x55\xe3\xe8\x05\x8b\xb8\xe2\x53\xd6\x8e" ++ "\xef\x2c\xe7\x4f\x4a\xf7\x4e\x26\x8d\x85\x0b\x3f\xec\xc3\x1c" ++ "\xd4\xeb\xec\x6a\xc8\x72\x2a\x25\x7d\xfd\xa6\x77\x96\xf0\x1e" ++ "\xcd\x28\x57\xf8\x37\x30\x75\x6b\xbd\xd4\x7b\x0c\x87\xc5\x6c" ++ "\x87\x40\xa5\xbb\x27\x2c\x78\xc9\x74\x5a\x54\x5b\x0b\x30\x6f" ++ "\x44\x4a\xfa\x71\xe4\x21\x61\x66\xf9\xee\x65\xde\x7c\x04\xd7" ++ "\xfd\xa9\x15\x5b\x7f\xe2\x7a\xba\x69\x86\x72\xa6\x06\x8d\x9b" ++ "\x90\x55\x60\x9e\x4c\x5d\xa9\xb6\x55"; + + 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"; ++ "\x7a\xd6\x12\xd0\x0e\xec\x91\xa9\x85\x8b\xf8\x50\xf0\x11\x2e" ++ "\x00\x11\x32\x40\x60\x66\x1f\x11\xee\xc2\x75\x27\x65\x4b\x16" ++ "\x67\x16\x95\xd2\x14\xc3\x1d\xb3\x48\x1f\xb7\xe4\x0b\x2b\x74" ++ "\xc3\xdb\x50\x27\xf9\x85\x3a\xfa\xa9\x08\x23\xc1\x65\x3d\x34" ++ "\x3a\xc8\x56\x7a\x65\x45\x36\x6e\xae\x2a\xce\x9f\x43\x43\xd7" ++ "\x10\xe9\x9e\x18\xf4\xa4\x35\xda\x8a\x6b\xb0\x3f\xdd\x53\xe3" ++ "\xa8\xc5\x4e\x79\x9d\x1f\x51\x8c\xa2\xca\x66\x3c\x6a\x2a\xff" ++ "\x8e\xd2\xf3\xb7\xcb\x82\xda\xde\x2c\xe6\xd2\x8c\xb3\xad\xb6" ++ "\x4c\x95\x55\x76\xbd\xc9\xc8\xd1"; + + 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"; ++ "\x00\x83\x23\x1d\xbb\x11\x42\x17\x2b\x25\x5a\x2c\x03\xe6\x75" ++ "\xc1\x18\xa8\xc9\x0b\x96\xbf\xba\xc4\x92\x91\x80\xa5\x22\x2f" ++ "\xba\x91\x90\x36\x01\x56\x15\x00\x2c\x74\xa2\x97\xf7\x15\xa1" ++ "\x49\xdf\x32\x35\xd2\xdd\x0c\x91\xa6\xf8\xe7\xbe\x81\x36\x9b" ++ "\x03\xdc\x6b\x3b\xd8\x5d\x79\x57\xe0\xe6\x4f\x49\xdf\x4c\x5c" ++ "\x0e\xe5\x21\x41\x95\xfd\xad\xff\x9a\x3e\xa0\xf9\x0f\x59\x9e" ++ "\x6a\xa7\x7b\x71\xa7\x24\x9a\x36\x52\xae\x97\x20\xc1\x5e\x78" ++ "\xd9\x47\x8b\x1e\x67\xf2\xaf\x98\xe6\x2d\xef\x10\xd7\xf1\xab" ++ "\x49\xee\xe5\x4b\x7e\xae\x1f\x1d\x61"; + + 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"; ++ "\x23\x96\xc1\x91\x17\x5e\x0a\x83\xd2\xdc\x7b\x69\xb2\x59\x1d" ++ "\x33\x58\x52\x3f\x18\xc7\x09\x50\x1c\xb9\xa1\xbb\x4c\xa2\x38" ++ "\x40\x4c\x9a\x8e\xfe\x9c\x90\x92\xd0\x71\x9f\x89\x99\x50\x91" ++ "\x1f\x34\x8b\x74\x53\x11\x11\x4a\x70\xe2\xf7\x30\xd8\x8c\x80" ++ "\xe1\xcc\x9f\xf1\x63\x17\x1a\x7d\x67\x29\x4c\xcb\x4e\x74\x7b" ++ "\xe0\x3e\x9e\x2f\xf4\x67\x8f\xec\xb9\x5c\x00\x1e\x7e\xa2\x7b" ++ "\x92\xc9\x6f\x4c\xe4\x0e\xf9\x48\x63\xcd\x50\x22\x5d\xbf\xb6" ++ "\x9d\x01\x33\x6a\xf4\x50\xbe\x86\x98\x4f\xca\x3f\x3a\xfa\xcf" ++ "\x07\x40\xc4\xaa\xad\xae\xbe\xbf"; + + key->n = BN_bin2bn(n, sizeof(n) - 1, key->n); + if (corrupt_rsa) +- BN_set_bit(key->n, 1024); ++ BN_set_bit(key->n, 2048); + 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); +@@ -145,200 +184,292 @@ 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 ++ 0xC2, 0x80, 0x82, 0x56, 0xD8, 0xA7, 0xB2, 0x9C, 0xF5, 0xD6, 0x3C, 0xE3, ++ 0xBF, 0xE9, 0x3A, 0x53, 0x40, 0xAE, 0xF2, 0xA9, 0x6A, 0x39, 0x49, 0x5B, ++ 0x05, 0x7F, 0x67, 0x38, 0x2E, 0x1D, 0xE1, 0x93, 0x22, 0x65, 0x79, 0x84, ++ 0x68, 0xFA, 0xD8, 0xAF, 0xA1, 0x98, 0x61, 0x6F, 0x44, 0x27, 0xA6, 0x8B, ++ 0xCF, 0x0E, 0x13, 0xA9, 0xCE, 0xD7, 0x6C, 0xD2, 0x38, 0xB5, 0x16, 0xB9, ++ 0x66, 0x94, 0x48, 0xDE, 0x9E, 0x19, 0x3D, 0x6F, 0xB3, 0xA1, 0x9A, 0x19, ++ 0xDF, 0xFB, 0xAB, 0xA5, 0x9F, 0x38, 0xDA, 0xC9, 0x21, 0x8F, 0xCE, 0x98, ++ 0x01, 0x3A, 0xC8, 0xE0, 0xDF, 0xDA, 0xFC, 0xF0, 0xA6, 0x86, 0x29, 0xB5, ++ 0x7F, 0x61, 0xFB, 0xBA, 0xC5, 0x49, 0xB2, 0x7C, 0x6A, 0x26, 0x82, 0xC4, ++ 0x8F, 0xAA, 0x5B, 0x10, 0xD5, 0xEE, 0xA0, 0x55, 0x42, 0xEF, 0x32, 0x5A, ++ 0x3F, 0x55, 0xB3, 0x2C, 0x22, 0xE9, 0x65, 0xDA, 0x8D, 0x0A, 0xB9, 0x70, ++ 0x43, 0xCC, 0x3F, 0x64, 0x9C, 0xB5, 0x65, 0x49, 0xBD, 0x7F, 0x35, 0xC1, ++ 0x20, 0x85, 0x24, 0xFE, 0xAA, 0x6B, 0x37, 0x04, 0xA1, 0x0E, 0x9D, 0x5C, ++ 0xBA, 0x7F, 0x14, 0x69, 0xC5, 0x93, 0xB2, 0x33, 0xC2, 0xC0, 0xC7, 0xDF, ++ 0x7E, 0x9E, 0xA4, 0xB0, 0xA0, 0x64, 0xD2, 0xAC, 0xFC, 0xFD, 0xFD, 0x99, ++ 0x8F, 0x6A, 0x40, 0x26, 0xC1, 0x2E, 0x4E, 0x8B, 0x33, 0xBE, 0xF1, 0x45, ++ 0x59, 0x8F, 0x33, 0x40, 0x1D, 0x2A, 0xD2, 0xF7, 0x50, 0x83, 0x89, 0xCF, ++ 0x94, 0xC6, 0xF8, 0x36, 0xF0, 0x84, 0x0B, 0x85, 0xA5, 0x02, 0xA9, 0x0F, ++ 0x41, 0x7A, 0x77, 0xA3, 0x2F, 0x47, 0x1E, 0x1D, 0xEC, 0xE6, 0xD3, 0x01, ++ 0x1E, 0x6F, 0x7A, 0x96, 0x50, 0x37, 0x37, 0x4B, 0x27, 0x52, 0x0B, 0xDC, ++ 0xDB, 0xC7, 0xA9, 0x31, 0xB2, 0x40, 0xEE, 0x60, 0x41, 0x26, 0x6A, 0x05, ++ 0xCE, 0x08, 0x1D, 0x89 + }; + + 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 ++ 0xB4, 0x01, 0x93, 0x16, 0x05, 0xF6, 0xEB, 0xE2, 0xA4, 0xEB, 0x48, 0xAA, ++ 0x00, 0xF4, 0xA1, 0x99, 0x0A, 0xB4, 0xB6, 0x63, 0xE9, 0x68, 0xCA, 0xB3, ++ 0x13, 0xD7, 0x66, 0x6A, 0xCD, 0xCB, 0x33, 0x9F, 0xE5, 0x84, 0xE2, 0xC3, ++ 0x0B, 0x53, 0xE5, 0x8B, 0x96, 0x4B, 0xDB, 0x2D, 0x80, 0xA4, 0x1D, 0xE3, ++ 0x81, 0xDC, 0x52, 0x99, 0xBA, 0x9B, 0x6A, 0x9D, 0x48, 0x1F, 0x73, 0xF7, ++ 0xAC, 0x09, 0x13, 0xA1, 0x16, 0x2C, 0x60, 0xFB, 0xBC, 0x25, 0xF7, 0x53, ++ 0xD1, 0x04, 0x5A, 0x3F, 0x95, 0x09, 0x5E, 0xE5, 0xA2, 0x7D, 0xFC, 0x2A, ++ 0x51, 0x1D, 0x21, 0xCE, 0x2B, 0x4E, 0x1B, 0xB8, 0xCB, 0xDD, 0x24, 0xEE, ++ 0x99, 0x1D, 0x37, 0xDC, 0xED, 0x5F, 0x2F, 0x48, 0x5E, 0x33, 0x94, 0x06, ++ 0x19, 0xCD, 0x5A, 0x26, 0x85, 0x77, 0x9D, 0xAF, 0x86, 0x97, 0xC9, 0x08, ++ 0xD5, 0x81, 0x0E, 0xB8, 0x9F, 0xB6, 0xAF, 0x20, 0x72, 0xDC, 0x13, 0x4D, ++ 0x7A, 0xE4, 0x5C, 0x81, 0xDE, 0xC0, 0x3D, 0x19, 0x9C, 0x33, 0x11, 0x07, ++ 0xD5, 0xA9, 0x51, 0x67, 0xCD, 0xFD, 0x37, 0x61, 0x14, 0x9F, 0xE7, 0x70, ++ 0x18, 0x32, 0xC3, 0x34, 0x54, 0x0D, 0x4F, 0xB4, 0xAE, 0x9F, 0xEC, 0x64, ++ 0xD8, 0xB2, 0x16, 0xA4, 0xB2, 0x99, 0x92, 0xCB, 0x7F, 0x1F, 0x06, 0x17, ++ 0x5F, 0xA1, 0x07, 0x68, 0xAE, 0xA7, 0x2D, 0x03, 0x91, 0x2A, 0x9D, 0x69, ++ 0xC2, 0x9D, 0x90, 0xF7, 0xF9, 0x66, 0x5D, 0x13, 0xB7, 0x7F, 0xD3, 0x97, ++ 0x45, 0x97, 0x43, 0xD8, 0xCE, 0x3C, 0xF2, 0x98, 0x98, 0xDD, 0xE2, 0x2D, ++ 0xCF, 0xA1, 0xC4, 0x25, 0x46, 0x2E, 0xD2, 0xE5, 0x5F, 0xC6, 0x01, 0xC5, ++ 0x4F, 0x42, 0x2B, 0xDE, 0x0F, 0xEA, 0x4A, 0x4F, 0xC3, 0x5B, 0xDF, 0x9B, ++ 0x5D, 0x30, 0x18, 0x93, 0xD0, 0xDE, 0xC5, 0x09, 0xAA, 0x57, 0x57, 0xBD, ++ 0x2D, 0x84, 0x03, 0xB7 + }; + + 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 ++ 0x38, 0xDA, 0x99, 0x51, 0x26, 0x38, 0xC6, 0x7F, 0xC4, 0x81, 0x57, 0x19, ++ 0x35, 0xC6, 0xF6, 0x1E, 0x90, 0x47, 0x20, 0x55, 0x47, 0x56, 0x26, 0xE9, ++ 0xF2, 0xA8, 0x39, 0x6C, 0xD5, 0xCD, 0xCB, 0x55, 0xFC, 0x0C, 0xC5, 0xCB, ++ 0xF7, 0x40, 0x17, 0x3B, 0xCF, 0xE4, 0x05, 0x03, 0x3B, 0xA0, 0xB2, 0xC9, ++ 0x0D, 0x5E, 0x48, 0x3A, 0xE9, 0xAD, 0x28, 0x71, 0x7D, 0x8F, 0x89, 0x16, ++ 0x59, 0x93, 0x35, 0xDC, 0x4D, 0x7B, 0xDF, 0x84, 0xE4, 0x68, 0xAA, 0x33, ++ 0xAA, 0xDC, 0x66, 0x50, 0xC8, 0xA9, 0x32, 0x12, 0xDC, 0xC6, 0x90, 0x49, ++ 0x0B, 0x75, 0xFF, 0x9B, 0x95, 0x00, 0x9A, 0x90, 0xE0, 0xD4, 0x0E, 0x67, ++ 0xAB, 0x3C, 0x47, 0x36, 0xC5, 0x2E, 0x1C, 0x46, 0xF0, 0x2D, 0xD3, 0x8B, ++ 0x42, 0x08, 0xDE, 0x0D, 0xB6, 0x2C, 0x86, 0xB0, 0x35, 0x71, 0x18, 0x6B, ++ 0x89, 0x67, 0xC0, 0x05, 0xAD, 0xF4, 0x1D, 0x62, 0x4E, 0x75, 0xEC, 0xD6, ++ 0xC2, 0xDB, 0x07, 0xB0, 0xB6, 0x8D, 0x15, 0xAD, 0xCD, 0xBF, 0xF5, 0x60, ++ 0x76, 0xAE, 0x48, 0xB8, 0x77, 0x7F, 0xC5, 0x01, 0xD9, 0x29, 0xBB, 0xD6, ++ 0x17, 0xA2, 0x20, 0x5A, 0xC0, 0x4A, 0x3B, 0x34, 0xC8, 0xB9, 0x39, 0xCF, ++ 0x06, 0x89, 0x95, 0x6F, 0xC7, 0xCA, 0xC4, 0xE4, 0x43, 0xDF, 0x5A, 0x23, ++ 0xE2, 0x89, 0xA3, 0x38, 0x78, 0x31, 0x38, 0xC6, 0xA4, 0x6F, 0x5F, 0x73, ++ 0x5A, 0xE5, 0x9E, 0x09, 0xE7, 0x6F, 0xD4, 0xF8, 0x3E, 0xB7, 0xB0, 0x56, ++ 0x9A, 0xF3, 0x65, 0xF0, 0xC2, 0xA6, 0x8A, 0x08, 0xBA, 0x44, 0xAC, 0x97, ++ 0xDE, 0xB4, 0x16, 0x83, 0xDF, 0xE3, 0xEE, 0x71, 0xFA, 0xF9, 0x51, 0x50, ++ 0x14, 0xDC, 0xFD, 0x6A, 0x82, 0x20, 0x68, 0x64, 0x7D, 0x4E, 0x82, 0x68, ++ 0xD7, 0x45, 0xFA, 0x6A, 0xE4, 0xE5, 0x29, 0x3A, 0x70, 0xFB, 0xE4, 0x62, ++ 0x2B, 0x31, 0xB9, 0x7D + }; + + 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 ++ 0x99, 0x02, 0xC9, 0x1E, 0x31, 0x82, 0xB4, 0xE6, 0x1B, 0x32, 0xCE, 0x5D, ++ 0x41, 0x1D, 0x00, 0x2F, 0x04, 0x8B, 0xBD, 0x37, 0x79, 0xCF, 0x77, 0x03, ++ 0x05, 0x6A, 0x21, 0xC7, 0x8D, 0x24, 0x60, 0x49, 0x39, 0x58, 0xC5, 0x27, ++ 0x8F, 0xC5, 0x97, 0x4A, 0xB2, 0xE1, 0xD4, 0x36, 0x57, 0xBD, 0x43, 0xCC, ++ 0x7B, 0xCE, 0xF2, 0xA5, 0x30, 0xF8, 0x72, 0x14, 0xBB, 0xD0, 0x9F, 0xC1, ++ 0x49, 0xC8, 0x1C, 0xAF, 0xCD, 0x95, 0x78, 0x72, 0x25, 0xF9, 0x45, 0xC6, ++ 0x5B, 0x62, 0x5E, 0x01, 0xD7, 0x40, 0x5E, 0xC8, 0xCA, 0x0A, 0xF3, 0xBA, ++ 0x08, 0x07, 0x88, 0xCA, 0x49, 0x36, 0x84, 0x7D, 0xF6, 0xFC, 0x5A, 0xDB, ++ 0xFC, 0x50, 0xD3, 0xEB, 0x3D, 0x83, 0xB0, 0xF5, 0x94, 0x5E, 0x88, 0xC3, ++ 0x82, 0xCD, 0x53, 0x40, 0x96, 0x18, 0x6B, 0x4A, 0x6C, 0x9C, 0xFE, 0xE5, ++ 0x3B, 0x75, 0xF9, 0xEB, 0xA5, 0x77, 0x11, 0xEF, 0x88, 0x1C, 0x25, 0x70, ++ 0x7D, 0x88, 0x5D, 0xC3, 0xCA, 0xE1, 0x49, 0x14, 0x90, 0xAD, 0xF2, 0x5E, ++ 0x49, 0xD7, 0x99, 0xA5, 0x7B, 0x77, 0x3B, 0x8E, 0xB8, 0xDB, 0xF1, 0x4C, ++ 0xD6, 0x9A, 0xDC, 0xE5, 0x7A, 0x1C, 0xE1, 0xCE, 0x9D, 0xF1, 0xF3, 0xA0, ++ 0x0A, 0x35, 0x52, 0x9D, 0xB9, 0x46, 0x94, 0x82, 0x0F, 0xF7, 0xB2, 0x62, ++ 0x51, 0x70, 0x75, 0xD2, 0x37, 0x96, 0x67, 0x2F, 0xD0, 0x22, 0xD8, 0x07, ++ 0x8D, 0x69, 0x9E, 0x6D, 0x0B, 0x40, 0x4F, 0x70, 0xEC, 0x0B, 0xCA, 0x88, ++ 0x80, 0x8D, 0x9A, 0xF4, 0xF9, 0x18, 0x50, 0x27, 0x08, 0xFA, 0xCC, 0xC7, ++ 0x3F, 0xE4, 0x84, 0x83, 0xA1, 0xB6, 0x1D, 0x23, 0x34, 0xFE, 0x48, 0xE5, ++ 0xE3, 0xAE, 0x4D, 0x98, 0xBC, 0xA6, 0x8A, 0x9F, 0xFD, 0x4D, 0xDB, 0x9D, ++ 0xF7, 0xEB, 0x4E, 0xB6, 0x6F, 0x25, 0xEA, 0x7A, 0xE9, 0x85, 0xB2, 0xEF, ++ 0x90, 0xD2, 0xA6, 0x2B + }; + + 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 ++ 0x3F, 0x83, 0x43, 0x78, 0x25, 0xBE, 0x81, 0xB2, 0x6E, 0x78, 0x11, 0x32, ++ 0xD0, 0x88, 0x05, 0x53, 0x95, 0xED, 0x81, 0x12, 0xCE, 0x50, 0xD9, 0x06, ++ 0x42, 0x89, 0xA0, 0x55, 0x7A, 0x05, 0x13, 0x94, 0x35, 0x9B, 0xCA, 0x5D, ++ 0xCB, 0xB2, 0x32, 0xE1, 0x04, 0x99, 0xEC, 0xE7, 0xA6, 0x69, 0x4D, 0x2B, ++ 0xC1, 0x57, 0x13, 0x48, 0x0D, 0x6B, 0x4D, 0x83, 0x28, 0x06, 0x79, 0x9D, ++ 0xB4, 0x70, 0xCE, 0xC0, 0xFC, 0x3B, 0x69, 0xB3, 0x91, 0x54, 0xA9, 0x44, ++ 0x2E, 0xDA, 0x4A, 0xC5, 0xC2, 0x99, 0xF0, 0xDE, 0xCA, 0x77, 0x99, 0x6B, ++ 0x0C, 0x79, 0xE5, 0x29, 0x74, 0x83, 0x69, 0xEA, 0xB8, 0x72, 0x30, 0x3D, ++ 0x7A, 0x30, 0xE1, 0x03, 0x7B, 0x09, 0xE6, 0x11, 0xC0, 0xDC, 0xFF, 0xFD, ++ 0xBD, 0xEC, 0x9C, 0xCC, 0x46, 0x7B, 0x4C, 0x4C, 0x59, 0xBE, 0x82, 0x7C, ++ 0xF5, 0x60, 0x5A, 0xC3, 0xE8, 0xA8, 0x8A, 0x38, 0x9E, 0x01, 0x57, 0xF1, ++ 0x79, 0x3A, 0x7C, 0xA3, 0x9F, 0x12, 0x1A, 0x4F, 0x2E, 0xA2, 0xE5, 0x0A, ++ 0xAB, 0xC0, 0xF4, 0xA5, 0xE3, 0x5F, 0x89, 0x1C, 0x8F, 0xA4, 0x5E, 0xCE, ++ 0x0D, 0x91, 0x05, 0x1B, 0x17, 0x62, 0x48, 0xFE, 0xA5, 0x4C, 0xEF, 0x2D, ++ 0x28, 0xF1, 0x5E, 0xE6, 0xD1, 0x30, 0x89, 0x0A, 0xAD, 0x18, 0xAF, 0x6F, ++ 0x04, 0x09, 0x36, 0x9A, 0xFF, 0xCA, 0xA1, 0xA7, 0x05, 0x7F, 0xD4, 0xBF, ++ 0x3A, 0xB5, 0x42, 0x6D, 0xE9, 0x07, 0x29, 0x65, 0x8B, 0xAD, 0x4D, 0x0F, ++ 0x22, 0xE1, 0x59, 0x43, 0x68, 0x87, 0xA8, 0x8B, 0xBC, 0x69, 0xA1, 0x94, ++ 0x22, 0x3E, 0x8A, 0x49, 0xE8, 0xA3, 0x6F, 0xC2, 0x93, 0x58, 0xE7, 0xAE, ++ 0xC9, 0x1F, 0xCF, 0x61, 0x93, 0xFC, 0xC1, 0xF6, 0xF3, 0x27, 0x7F, 0x0A, ++ 0x90, 0xE0, 0x65, 0x32, 0x57, 0x47, 0xE2, 0xED, 0x08, 0x59, 0xA6, 0xF0, ++ 0x17, 0x2C, 0x13, 0xE0 + }; + + 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 ++ 0x3B, 0x60, 0x4B, 0xFC, 0x54, 0x28, 0x23, 0xE6, 0x2F, 0x05, 0x04, 0xBA, ++ 0x9D, 0xE4, 0x3C, 0xB8, 0x5B, 0x60, 0x5C, 0xCD, 0x9D, 0xEA, 0xC3, 0x4C, ++ 0xC2, 0x33, 0xE6, 0xC6, 0x21, 0x48, 0x76, 0xEC, 0xB2, 0xF5, 0x11, 0xDE, ++ 0x44, 0xB4, 0xAF, 0x16, 0x11, 0xC3, 0x18, 0x16, 0xB3, 0x69, 0xBB, 0x94, ++ 0xED, 0xE8, 0xB3, 0x9E, 0xB1, 0x43, 0x8E, 0xCE, 0xB4, 0x34, 0x9B, 0x08, ++ 0x22, 0xAF, 0x31, 0x73, 0xB5, 0xFA, 0x11, 0x7E, 0x8F, 0x13, 0x52, 0xEC, ++ 0xC9, 0x03, 0xEE, 0x0D, 0x2B, 0x91, 0x32, 0xF2, 0x8E, 0xDF, 0x02, 0xE0, ++ 0x0A, 0x47, 0xD2, 0x0A, 0x51, 0x00, 0x1A, 0x30, 0x6F, 0x0C, 0xB3, 0x54, ++ 0x64, 0x20, 0x90, 0x0C, 0x01, 0xBE, 0xC0, 0x42, 0x8C, 0x5D, 0x18, 0x6F, ++ 0x32, 0x75, 0x45, 0x7B, 0x1C, 0x04, 0xA2, 0x9F, 0x84, 0xD7, 0xF5, 0x3A, ++ 0x95, 0xD4, 0xE8, 0x8D, 0xEC, 0x99, 0xEF, 0x18, 0x5E, 0x64, 0xD3, 0xAF, ++ 0xF8, 0xD4, 0xFF, 0x3C, 0x87, 0xA0, 0x3F, 0xC7, 0x22, 0x05, 0xFD, 0xFD, ++ 0x29, 0x8A, 0x28, 0xDA, 0xA9, 0x8A, 0x8B, 0x23, 0x62, 0x9D, 0x42, 0xB8, ++ 0x4A, 0x76, 0x0D, 0x9F, 0x9A, 0xE0, 0xE6, 0xDD, 0xAD, 0x5E, 0x5F, 0xD5, ++ 0x32, 0xE9, 0x4B, 0x97, 0x7D, 0x62, 0x0A, 0xB3, 0xBE, 0xF2, 0x8C, 0x1F, ++ 0x2B, 0x22, 0x06, 0x15, 0x33, 0x71, 0xED, 0x9B, 0xA0, 0x82, 0xCE, 0xBF, ++ 0x3B, 0x08, 0x5F, 0xA7, 0x20, 0x94, 0x09, 0xEB, 0x82, 0xA5, 0x41, 0x60, ++ 0xF1, 0x08, 0xEB, 0x8D, 0xCC, 0x8D, 0xC9, 0x52, 0x0A, 0xAF, 0xF4, 0xF9, ++ 0x9F, 0x82, 0xD8, 0x0B, 0x75, 0x5E, 0xE4, 0xAF, 0x65, 0x96, 0xAF, 0xFC, ++ 0x33, 0xBF, 0x9F, 0x3E, 0xA4, 0x7B, 0x86, 0xC7, 0xF7, 0x47, 0xAB, 0x37, ++ 0x05, 0xD6, 0x0D, 0x31, 0x72, 0x8C, 0x80, 0x1E, 0xA9, 0x54, 0xFC, 0xDF, ++ 0x27, 0x90, 0xE2, 0x01 + }; + + 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 ++ 0xA2, 0xD8, 0x42, 0x53, 0xDD, 0xBF, 0x1F, 0x6B, 0x07, 0xE0, 0x60, 0x86, ++ 0x5A, 0x60, 0x06, 0x8F, 0x44, 0xD9, 0xB0, 0x4A, 0xAA, 0x90, 0x71, 0xB8, ++ 0xB2, 0xBC, 0x30, 0x41, 0x50, 0xBB, 0xFD, 0x46, 0x98, 0x4D, 0xC0, 0x89, ++ 0x57, 0x85, 0x8A, 0x97, 0x49, 0x25, 0xA8, 0x0C, 0x69, 0x70, 0x19, 0x39, ++ 0x66, 0x24, 0xB4, 0x69, 0x47, 0xD2, 0x7C, 0xDE, 0x2D, 0x37, 0x59, 0xB3, ++ 0xE3, 0xC7, 0x6B, 0xDD, 0xBE, 0xE1, 0xE6, 0x28, 0x9A, 0x8D, 0x42, 0x3E, ++ 0x28, 0x01, 0xD7, 0x03, 0xC9, 0x73, 0xC3, 0x6B, 0x03, 0xEC, 0x1E, 0xF8, ++ 0x53, 0x8B, 0x52, 0x42, 0x89, 0x55, 0xB7, 0x87, 0xA9, 0x94, 0xC2, 0xB4, ++ 0x4B, 0x76, 0xF5, 0x61, 0x47, 0xE1, 0x44, 0x7B, 0xEC, 0xB4, 0x25, 0x66, ++ 0xC0, 0xFF, 0xEB, 0x86, 0x24, 0xAA, 0xA8, 0x72, 0xC7, 0xFB, 0xFB, 0xF6, ++ 0x84, 0xA7, 0x5B, 0xD4, 0x87, 0xE5, 0x84, 0x56, 0x1E, 0x4C, 0xE5, 0xBC, ++ 0x87, 0x94, 0xAC, 0x9C, 0x1B, 0x3D, 0xF7, 0xD4, 0x36, 0x85, 0x9F, 0xC9, ++ 0xF6, 0x43, 0x3F, 0xB6, 0x25, 0x33, 0x48, 0x0F, 0xE5, 0x7C, 0xCD, 0x53, ++ 0x48, 0xEB, 0x02, 0x11, 0xB9, 0x9E, 0xC3, 0xB4, 0xE1, 0x54, 0xD6, 0xAA, ++ 0x1A, 0x9E, 0x10, 0xE1, 0x27, 0x25, 0xF2, 0xE1, 0xAB, 0xAB, 0x6C, 0x45, ++ 0x61, 0xD5, 0xA3, 0x6C, 0xB6, 0x33, 0x52, 0xAE, 0x3D, 0xFD, 0x22, 0xFC, ++ 0x3A, 0xAB, 0x63, 0x94, 0xB5, 0x3A, 0x69, 0x11, 0xAC, 0x99, 0x4F, 0x33, ++ 0x67, 0x0A, 0x1A, 0x70, 0x1E, 0xB9, 0xE2, 0x26, 0x27, 0x68, 0xEA, 0xF5, ++ 0x97, 0x55, 0xAC, 0x83, 0x6A, 0x40, 0x3B, 0x56, 0xAE, 0x13, 0x88, 0xE8, ++ 0x98, 0x72, 0x52, 0x91, 0x7F, 0x78, 0x0A, 0x18, 0xD4, 0x44, 0x78, 0x83, ++ 0x0D, 0x44, 0x77, 0xA6, 0xF3, 0x04, 0xF1, 0x8C, 0xBC, 0x2F, 0xF9, 0x5B, ++ 0xDB, 0x70, 0x00, 0xF6 + }; + + 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 ++ 0xC2, 0xB1, 0x97, 0x00, 0x9A, 0xE5, 0x80, 0x6A, 0xE2, 0x51, 0x68, 0xB9, ++ 0x7A, 0x0C, 0xF2, 0xB4, 0x77, 0xED, 0x15, 0x0C, 0x4E, 0xE1, 0xDC, 0xFF, ++ 0x8E, 0xBC, 0xDE, 0xC7, 0x9A, 0x96, 0xF1, 0x47, 0x45, 0x24, 0x9D, 0x6F, ++ 0xA6, 0xF3, 0x1D, 0x0D, 0x35, 0x4C, 0x1A, 0xF3, 0x58, 0x2C, 0x6C, 0x06, ++ 0xD6, 0x22, 0x37, 0x77, 0x8C, 0x33, 0xE5, 0x07, 0x53, 0x93, 0x28, 0xCF, ++ 0x67, 0xFA, 0xC4, 0x1F, 0x1B, 0x24, 0xDB, 0x4C, 0xC5, 0x2A, 0x51, 0xA2, ++ 0x60, 0x15, 0x8C, 0x54, 0xB4, 0x30, 0xE2, 0x24, 0x47, 0x86, 0xF2, 0xF8, ++ 0x6C, 0xD6, 0x12, 0x59, 0x2C, 0x74, 0x9A, 0x37, 0xF3, 0xC4, 0xA2, 0xD5, ++ 0x4E, 0x1F, 0x77, 0xF0, 0x27, 0xCE, 0x77, 0xF8, 0x4A, 0x79, 0x03, 0xBE, ++ 0xC8, 0x06, 0x2D, 0xA7, 0xA6, 0x46, 0xF5, 0x55, 0x79, 0xD7, 0x5C, 0xC6, ++ 0x5B, 0xB1, 0x00, 0x4E, 0x7C, 0xD9, 0x11, 0x85, 0xE0, 0xB1, 0x4D, 0x2D, ++ 0x13, 0xD7, 0xAC, 0xEA, 0x64, 0xD1, 0xAC, 0x8F, 0x8D, 0x8F, 0xEA, 0x42, ++ 0x7F, 0xF9, 0xB7, 0x7D, 0x2C, 0x68, 0x49, 0x07, 0x7A, 0x74, 0xEF, 0xB4, ++ 0xC9, 0x97, 0x16, 0x5C, 0x6C, 0x6E, 0x5C, 0x09, 0x2E, 0x8E, 0x13, 0x2E, ++ 0x1A, 0x8D, 0xA6, 0x0C, 0x6E, 0x0C, 0x1C, 0x0F, 0xCC, 0xB2, 0x78, 0x8A, ++ 0x07, 0xFC, 0x5C, 0xC2, 0xF5, 0x65, 0xEC, 0xAB, 0x8B, 0x3C, 0xCA, 0x91, ++ 0x6F, 0x84, 0x7C, 0x21, 0x0E, 0xB8, 0xDA, 0x7B, 0x6C, 0xF7, 0xDF, 0xAB, ++ 0x7E, 0x15, 0xFD, 0x85, 0x0B, 0x33, 0x9B, 0x6A, 0x3A, 0xC3, 0xEF, 0x65, ++ 0x04, 0x6E, 0xB2, 0xAC, 0x98, 0xFD, 0xEB, 0x02, 0xF5, 0xC0, 0x0B, 0x5E, ++ 0xCB, 0xD4, 0x83, 0x82, 0x18, 0x1B, 0xDA, 0xB4, 0xCD, 0xE8, 0x71, 0x6B, ++ 0x1D, 0xB5, 0x4F, 0xE9, 0xD6, 0x43, 0xA0, 0x0A, 0x14, 0xA0, 0xE7, 0x5D, ++ 0x47, 0x9D, 0x18, 0xD7 + }; + + 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 ++ 0x11, 0x5E, 0x63, 0xFE, 0x47, 0xAA, 0x6A, 0x84, 0xEB, 0x44, 0x9A, 0x00, ++ 0x96, 0x4A, 0xED, 0xD2, 0xA7, 0x67, 0x3A, 0x64, 0x82, 0x30, 0x61, 0x2D, ++ 0xE3, 0xF5, 0x49, 0x68, 0x5E, 0x60, 0xD2, 0x4D, 0xEF, 0xF2, 0xA4, 0xB2, ++ 0x9A, 0x81, 0x1D, 0x41, 0xA5, 0x73, 0x59, 0xEB, 0xBB, 0xC4, 0x9E, 0x2B, ++ 0xEB, 0xC3, 0xDE, 0x3A, 0xEA, 0xF5, 0xAD, 0xDA, 0x87, 0x08, 0x68, 0xCF, ++ 0x12, 0x9B, 0xC1, 0xE4, 0xA7, 0x71, 0xF8, 0xBD, 0x6B, 0x6F, 0x50, 0xF1, ++ 0xD1, 0xFF, 0xCE, 0x6C, 0xD9, 0xBE, 0xDA, 0x76, 0xF3, 0xEB, 0xAB, 0x9C, ++ 0x41, 0x6E, 0x4F, 0x35, 0x7A, 0x61, 0x27, 0xBC, 0x03, 0x3E, 0xAE, 0x3E, ++ 0x1B, 0xDD, 0xAC, 0xD9, 0x1A, 0xFF, 0xD3, 0xF5, 0x66, 0x43, 0x07, 0x76, ++ 0x8A, 0x69, 0x2D, 0x14, 0xB1, 0xBE, 0x55, 0x49, 0x90, 0x89, 0x4B, 0xC4, ++ 0x11, 0x67, 0xD5, 0x9D, 0xB0, 0xB2, 0xEE, 0x8D, 0x0A, 0x47, 0x4A, 0xD9, ++ 0x0E, 0xD1, 0x24, 0xF0, 0x30, 0x2B, 0xF2, 0x79, 0x47, 0xDB, 0x70, 0xB4, ++ 0x46, 0xF2, 0xF8, 0xB7, 0xB4, 0xF6, 0x34, 0x79, 0xA8, 0x2D, 0x3D, 0x56, ++ 0xD5, 0x9A, 0x60, 0x7A, 0x04, 0xC7, 0x66, 0x1D, 0xCD, 0x3C, 0xD5, 0x39, ++ 0x37, 0x12, 0x51, 0x5E, 0x9F, 0xF8, 0x1A, 0xAF, 0x13, 0xC1, 0x13, 0x00, ++ 0x35, 0xD5, 0x8D, 0x17, 0xE3, 0x02, 0x28, 0xD9, 0xEC, 0xDE, 0xD1, 0x2F, ++ 0x93, 0x49, 0x03, 0x11, 0x3E, 0x56, 0x9D, 0xC2, 0x31, 0xF8, 0xAF, 0x2D, ++ 0xD9, 0x99, 0xB7, 0x8A, 0xAC, 0x5A, 0x86, 0x20, 0x3A, 0x83, 0x29, 0x26, ++ 0x9D, 0x03, 0x52, 0x2B, 0x34, 0x56, 0x40, 0x16, 0x53, 0x50, 0x82, 0xC9, ++ 0xC7, 0xD5, 0x51, 0x4C, 0xED, 0xB3, 0xE2, 0xE1, 0xCF, 0xA8, 0xCE, 0xBD, ++ 0xB1, 0x48, 0xA6, 0x8A, 0x79, 0x17, 0x55, 0x11, 0xEF, 0xE8, 0x14, 0xF4, ++ 0x7E, 0x37, 0x1D, 0x96 + }; + + 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 ++ 0x35, 0x6D, 0xF1, 0x9E, 0xCF, 0xB1, 0xF6, 0x0C, 0x04, 0x21, 0x17, 0xB3, ++ 0xC4, 0x9D, 0xFE, 0x62, 0x1C, 0x1A, 0x45, 0x00, 0x2E, 0x6B, 0xB6, 0x9F, ++ 0x5C, 0xB1, 0xCB, 0xCF, 0xF9, 0x67, 0xEA, 0x62, 0x8A, 0xEB, 0x77, 0x02, ++ 0x42, 0x30, 0x88, 0xB1, 0x48, 0xDF, 0x12, 0x60, 0x6E, 0x92, 0xBB, 0x4B, ++ 0x09, 0x68, 0xD1, 0x70, 0x2B, 0x59, 0xEE, 0x57, 0x96, 0xF9, 0xEA, 0xA3, ++ 0x4C, 0xE9, 0xC9, 0xBD, 0x25, 0x34, 0x66, 0x15, 0x6C, 0xC9, 0x81, 0xD1, ++ 0x48, 0x0F, 0x33, 0x5F, 0x05, 0x4F, 0xC2, 0xC4, 0xDD, 0x09, 0x54, 0x79, ++ 0xA1, 0x57, 0x07, 0x70, 0xA0, 0x33, 0x02, 0x4D, 0x5D, 0xE9, 0x24, 0xD1, ++ 0xEF, 0xF0, 0x61, 0xD0, 0x1D, 0x41, 0xE2, 0x9B, 0x2B, 0x7C, 0xD0, 0x4E, ++ 0x55, 0xD9, 0x6D, 0xA1, 0x16, 0x9F, 0xDA, 0xC3, 0x3B, 0xF1, 0x74, 0xD1, ++ 0x99, 0xF1, 0x63, 0x57, 0xAD, 0xC7, 0x55, 0xF4, 0x97, 0x43, 0x1C, 0xED, ++ 0x1B, 0x7A, 0x32, 0xCB, 0x24, 0xA6, 0x3D, 0x93, 0x37, 0x90, 0x74, 0xEE, ++ 0xD2, 0x8D, 0x4B, 0xBC, 0x72, 0xDA, 0x25, 0x2B, 0x64, 0xE9, 0xCA, 0x69, ++ 0x36, 0xB6, 0xEC, 0x6E, 0x8F, 0x33, 0x0E, 0x74, 0x40, 0x48, 0x51, 0xE2, ++ 0x54, 0x6F, 0xAF, 0x6E, 0x36, 0x54, 0x3A, 0xEC, 0x78, 0x37, 0xE6, 0x1F, ++ 0x76, 0xA5, 0x4D, 0xA6, 0xD9, 0xB3, 0x6B, 0x17, 0x6D, 0x61, 0xFC, 0xA3, ++ 0x85, 0x4A, 0xCC, 0xDA, 0x52, 0xAC, 0x5B, 0xDA, 0x51, 0xE5, 0x7F, 0x5B, ++ 0x52, 0x8B, 0x74, 0x75, 0x99, 0x5C, 0x01, 0xFD, 0x25, 0x3E, 0xCD, 0x86, ++ 0x6F, 0x7A, 0xC0, 0xD8, 0x17, 0x6F, 0xD1, 0xD2, 0x6B, 0xAB, 0x14, 0x1F, ++ 0x3B, 0xB8, 0x15, 0x05, 0x86, 0x40, 0x36, 0xCF, 0xDA, 0x59, 0x2B, 0x9A, ++ 0xE9, 0x1E, 0x6E, 0xD3, 0x6B, 0xA1, 0x19, 0xC5, 0xE6, 0x3F, 0xE9, 0x2E, ++ 0x43, 0xA8, 0x34, 0x0A + }; + +-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 int fips_rsa_encrypt_test(RSA *rsa, const unsigned char *plaintext, ++ int ptlen) ++{ ++ unsigned char *ctbuf = NULL, *ptbuf = NULL; ++ int ret = 0; ++ int len; + +-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 +-}; ++ ctbuf = OPENSSL_malloc(RSA_size(rsa)); ++ if (!ctbuf) ++ goto err; + +-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 +-}; ++ len = RSA_public_encrypt(ptlen, plaintext, ctbuf, rsa, RSA_PKCS1_PADDING); ++ if (len <= 0) ++ goto err; ++ /* Check ciphertext doesn't match plaintext */ ++ if (len >= ptlen && !memcmp(plaintext, ctbuf, ptlen)) ++ goto err; + +-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 +-}; ++ ptbuf = OPENSSL_malloc(RSA_size(rsa)); ++ if (!ptbuf) ++ goto err; ++ ++ len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING); ++ if (len != ptlen) ++ goto err; ++ if (memcmp(ptbuf, plaintext, len)) ++ goto err; ++ ++ ret = 1; ++ ++ err: ++ if (ctbuf) ++ OPENSSL_free(ctbuf); ++ if (ptbuf) ++ OPENSSL_free(ptbuf); ++ return ret; ++} + + int FIPS_selftest_rsa() + { +@@ -352,7 +483,7 @@ int FIPS_selftest_rsa() + if ((pk = EVP_PKEY_new()) == NULL) + goto err; + +- EVP_PKEY_assign_RSA(pk, key); ++ EVP_PKEY_set1_RSA(pk, key); + + if (!fips_pkey_signature_test(pk, kat_tbs, sizeof(kat_tbs) - 1, + kat_RSA_SHA1, sizeof(kat_RSA_SHA1), +@@ -406,29 +537,7 @@ int FIPS_selftest_rsa() + 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")) ++ if (!fips_rsa_encrypt_test(key, kat_tbs, sizeof(kat_tbs) - 1)) + goto err; + + ret = 1; +@@ -436,7 +545,7 @@ int FIPS_selftest_rsa() + err: + if (pk) + EVP_PKEY_free(pk); +- else if (key) ++ if (key) + RSA_free(key); + return ret; + } +diff -up openssl-1.0.2j/crypto/fips/Makefile.fips-reqs openssl-1.0.2j/crypto/fips/Makefile +--- openssl-1.0.2j/crypto/fips/Makefile.fips-reqs 2017-01-10 16:25:11.134340415 +0100 ++++ openssl-1.0.2j/crypto/fips/Makefile 2017-01-10 16:25:11.144340641 +0100 +@@ -24,13 +24,15 @@ LIBSRC=fips_aes_selftest.c fips_des_self + 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_ecdh_selftest.c fips_ecdsa_selftest.c fips_enc.c fips_md.c ++ fips_cmac_selftest.c fips_ecdh_selftest.c fips_ecdsa_selftest.c fips_enc.c fips_md.c \ ++ fips_dh_selftest.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_ecdh_selftest.o fips_ecdsa_selftest.o fips_enc.o fips_md.o ++ fips_cmac_selftest.o fips_ecdh_selftest.o fips_ecdsa_selftest.o fips_enc.o fips_md.o \ ++ fips_dh_selftest.o + + LIBCRYPTO=-L.. -lcrypto + +diff -up openssl-1.0.2j/crypto/rand/rand_lcl.h.fips-reqs openssl-1.0.2j/crypto/rand/rand_lcl.h +--- openssl-1.0.2j/crypto/rand/rand_lcl.h.fips-reqs 2017-01-10 16:25:10.830333571 +0100 ++++ openssl-1.0.2j/crypto/rand/rand_lcl.h 2017-01-10 16:25:11.144340641 +0100 +@@ -112,7 +112,7 @@ + #ifndef HEADER_RAND_LCL_H + # define HEADER_RAND_LCL_H + +-# define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ ++# define ENTROPY_NEEDED 48 /* require 384 bits = 48 bytes of randomness */ + + # if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) + # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +diff -up openssl-1.0.2j/crypto/rand/rand_lib.c.fips-reqs openssl-1.0.2j/crypto/rand/rand_lib.c +--- openssl-1.0.2j/crypto/rand/rand_lib.c.fips-reqs 2016-09-26 11:49:07.000000000 +0200 ++++ openssl-1.0.2j/crypto/rand/rand_lib.c 2017-01-10 16:25:11.145340663 +0100 +@@ -236,12 +236,22 @@ static int drbg_rand_add(DRBG_CTX *ctx, + double entropy) + { + RAND_SSLeay()->add(in, inlen, entropy); ++ if (FIPS_rand_status()) { ++ CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ FIPS_drbg_reseed(ctx, NULL, 0); ++ CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ } + return 1; + } + + static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) + { + RAND_SSLeay()->seed(in, inlen); ++ if (FIPS_rand_status()) { ++ CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ FIPS_drbg_reseed(ctx, NULL, 0); ++ CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ } + return 1; + } + +diff -up openssl-1.0.2j/crypto/rsa/rsa_gen.c.fips-reqs openssl-1.0.2j/crypto/rsa/rsa_gen.c +--- openssl-1.0.2j/crypto/rsa/rsa_gen.c.fips-reqs 2017-01-10 16:25:11.112339920 +0100 ++++ openssl-1.0.2j/crypto/rsa/rsa_gen.c 2017-01-10 16:25:11.145340663 +0100 +@@ -1,5 +1,6 @@ + /* crypto/rsa/rsa_gen.c */ + /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) ++ * Copyright (C) 2013 Red Hat, Inc. + * All rights reserved. + * + * This package is an SSL implementation written +@@ -169,6 +170,259 @@ int RSA_generate_key_ex(RSA *rsa, int bi + return rsa_builtin_keygen(rsa, bits, e_value, cb); + } + ++#ifdef OPENSSL_FIPS ++static int FIPS_rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, ++ BN_GENCB *cb) ++{ ++ BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; ++ BIGNUM local_r0, local_d, local_p; ++ BIGNUM *pr0, *d, *p; ++ BN_CTX *ctx = NULL; ++ int ok = -1; ++ int i; ++ int n = 0; ++ int test = 0; ++ int pbits = bits / 2; ++ ++ if (FIPS_selftest_failed()) { ++ FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_FIPS_SELFTEST_FAILED); ++ return 0; ++ } ++ ++ if ((pbits & 0xFF) ++ || (getenv("OPENSSL_ENFORCE_MODULUS_BITS") && bits != 2048 ++ && bits != 3072)) { ++ FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_INVALID_KEY_LENGTH); ++ return 0; ++ } ++ ++ ctx = BN_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ BN_CTX_start(ctx); ++ r0 = BN_CTX_get(ctx); ++ r1 = BN_CTX_get(ctx); ++ r2 = BN_CTX_get(ctx); ++ r3 = BN_CTX_get(ctx); ++ ++ if (r3 == NULL) ++ goto err; ++ ++ /* We need the RSA components non-NULL */ ++ if (!rsa->n && ((rsa->n = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->d && ((rsa->d = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->e && ((rsa->e = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->p && ((rsa->p = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->q && ((rsa->q = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) ++ goto err; ++ if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) ++ goto err; ++ ++ if (!BN_set_word(r0, RSA_F4)) ++ goto err; ++ if (BN_cmp(e_value, r0) < 0 || BN_num_bits(e_value) > 256) { ++ ok = 0; /* we set our own err */ ++ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_BAD_E_VALUE); ++ goto err; ++ } ++ ++ /* prepare approximate minimum p and q */ ++ if (!BN_set_word(r0, 0xB504F334)) ++ goto err; ++ if (!BN_lshift(r0, r0, pbits - 32)) ++ goto err; ++ ++ /* prepare minimum p and q difference */ ++ if (!BN_one(r3)) ++ goto err; ++ if (!BN_lshift(r3, r3, pbits - 100)) ++ goto err; ++ ++ BN_copy(rsa->e, e_value); ++ ++ if (!BN_is_zero(rsa->p) && !BN_is_zero(rsa->q)) ++ test = 1; ++ ++ retry: ++ /* generate p and q */ ++ for (i = 0; i < 5 * pbits; i++) { ++ ploop: ++ if (!test) ++ if (!BN_rand(rsa->p, pbits, 0, 1)) ++ goto err; ++ if (BN_cmp(rsa->p, r0) < 0) { ++ if (test) ++ goto err; ++ goto ploop; ++ } ++ ++ 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)) { ++ int r; ++ r = BN_is_prime_fasttest_ex(rsa->p, pbits > 1024 ? 4 : 5, ctx, 0, ++ cb); ++ if (r == -1 || (test && r <= 0)) ++ goto err; ++ if (r > 0) ++ break; ++ } ++ ++ if (!BN_GENCB_call(cb, 2, n++)) ++ goto err; ++ } ++ ++ if (!BN_GENCB_call(cb, 3, 0)) ++ goto err; ++ ++ if (i >= 5 * pbits) ++ /* prime not found */ ++ goto err; ++ ++ for (i = 0; i < 5 * pbits; i++) { ++ qloop: ++ if (!test) ++ if (!BN_rand(rsa->q, pbits, 0, 1)) ++ goto err; ++ if (BN_cmp(rsa->q, r0) < 0) { ++ if (test) ++ goto err; ++ goto qloop; ++ } ++ if (!BN_sub(r2, rsa->q, rsa->p)) ++ goto err; ++ if (BN_ucmp(r2, r3) <= 0) { ++ if (test) ++ goto err; ++ goto qloop; ++ } ++ ++ 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)) { ++ int r; ++ r = BN_is_prime_fasttest_ex(rsa->q, pbits > 1024 ? 4 : 5, ctx, 0, ++ cb); ++ if (r == -1 || (test && r <= 0)) ++ goto err; ++ if (r > 0) ++ break; ++ } ++ ++ if (!BN_GENCB_call(cb, 2, n++)) ++ goto err; ++ } ++ ++ if (!BN_GENCB_call(cb, 3, 1)) ++ goto err; ++ ++ if (i >= 5 * pbits) ++ /* prime not found */ ++ goto err; ++ ++ if (test) { ++ /* do not try to calculate the remaining key values */ ++ BN_clear(rsa->n); ++ ok = 1; ++ goto err; ++ } ++ ++ if (BN_cmp(rsa->p, rsa->q) < 0) { ++ tmp = rsa->p; ++ rsa->p = rsa->q; ++ rsa->q = tmp; ++ } ++ ++ /* calculate n */ ++ if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) ++ goto err; ++ ++ /* calculate d */ ++ if (!BN_sub(r1, rsa->p, BN_value_one())) ++ goto err; /* p-1 */ ++ if (!BN_sub(r2, rsa->q, BN_value_one())) ++ goto err; /* q-1 */ ++ ++ if (!BN_gcd(r0, r1, r2, ctx)) ++ goto err; ++ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { ++ pr0 = &local_r0; ++ BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); ++ } else ++ pr0 = r0; ++ if (!BN_div(r0, NULL, r1, pr0, ctx)) ++ goto err; ++ if (!BN_mul(r0, r0, r2, ctx)) ++ goto err; /* lcm(p-1, q-1) */ ++ ++ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { ++ pr0 = &local_r0; ++ BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); ++ } else ++ pr0 = r0; ++ if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) ++ goto err; /* d */ ++ ++ if (BN_num_bits(rsa->d) < pbits) ++ goto retry; /* d is too small */ ++ ++ /* set up d for correct BN_FLG_CONSTTIME flag */ ++ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { ++ d = &local_d; ++ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); ++ } else ++ d = rsa->d; ++ ++ /* calculate d mod (p-1) */ ++ if (!BN_mod(rsa->dmp1, d, r1, ctx)) ++ goto err; ++ ++ /* calculate d mod (q-1) */ ++ if (!BN_mod(rsa->dmq1, d, r2, ctx)) ++ goto err; ++ ++ /* calculate inverse of q mod p */ ++ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { ++ p = &local_p; ++ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); ++ } else ++ p = rsa->p; ++ if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) ++ goto err; ++ ++ if (fips_rsa_pairwise_fail) ++ BN_add_word(rsa->n, 1); ++ ++ if (!fips_check_rsa(rsa)) ++ goto err; ++ ++ ok = 1; ++ err: ++ if (ok == -1) { ++ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); ++ ok = 0; ++ } ++ if (ctx != NULL) { ++ BN_CTX_end(ctx); ++ BN_CTX_free(ctx); ++ } ++ ++ return ok; ++} ++#endif ++ + static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + BN_GENCB *cb) + { +@@ -180,15 +434,11 @@ static int rsa_builtin_keygen(RSA *rsa, + + #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; + } ++ return FIPS_rsa_builtin_keygen(rsa, bits, e_value, cb); + } + #endif + +@@ -317,16 +567,6 @@ 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.2j/ssl/t1_enc.c.fips-reqs openssl-1.0.2j/ssl/t1_enc.c +--- openssl-1.0.2j/ssl/t1_enc.c.fips-reqs 2016-09-26 11:49:07.000000000 +0200 ++++ openssl-1.0.2j/ssl/t1_enc.c 2017-01-10 16:25:11.145340663 +0100 +@@ -292,6 +292,23 @@ static int tls1_PRF(long digest_mask, + return ret; + } + ++int private_tls1_PRF(long digest_mask, ++ const void *seed1, int seed1_len, ++ const void *seed2, int seed2_len, ++ const void *seed3, int seed3_len, ++ const void *seed4, int seed4_len, ++ const void *seed5, int seed5_len, ++ const unsigned char *sec, int slen, ++ unsigned char *out1, unsigned char *out2, int olen) ++{ ++ return tls1_PRF(digest_mask, ++ seed1, seed1_len, ++ seed2, seed2_len, ++ seed3, seed3_len, ++ seed4, seed4_len, ++ seed5, seed5_len, sec, slen, out1, out2, olen); ++} ++ + static int tls1_generate_key_block(SSL *s, unsigned char *km, + unsigned char *tmp, int num) + { diff --git a/SOURCES/openssl-1.0.2k-backports.patch b/SOURCES/openssl-1.0.2k-backports.patch new file mode 100644 index 0000000..4d1e578 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cc-reqs.patch b/SOURCES/openssl-1.0.2k-cc-reqs.patch new file mode 100644 index 0000000..683d9af --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cve-2017-3735.patch b/SOURCES/openssl-1.0.2k-cve-2017-3735.patch new file mode 100644 index 0000000..19b4b4b --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cve-2017-3736.patch b/SOURCES/openssl-1.0.2k-cve-2017-3736.patch new file mode 100644 index 0000000..6fc0491 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cve-2017-3737.patch b/SOURCES/openssl-1.0.2k-cve-2017-3737.patch new file mode 100644 index 0000000..0f6f462 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cve-2017-3738.patch b/SOURCES/openssl-1.0.2k-cve-2017-3738.patch new file mode 100644 index 0000000..e8b6ba5 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cve-2018-0495.patch b/SOURCES/openssl-1.0.2k-cve-2018-0495.patch new file mode 100644 index 0000000..78bba65 --- /dev/null +++ b/SOURCES/openssl-1.0.2k-cve-2018-0495.patch @@ -0,0 +1,896 @@ +diff -up openssl-1.0.2k/crypto/bn/bn_div.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_div.c +--- openssl-1.0.2k/crypto/bn/bn_div.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_div.c 2018-08-14 10:57:21.592518702 +0200 +@@ -290,6 +290,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const + 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 -up openssl-1.0.2k/crypto/bn/bn_exp.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_exp.c +--- openssl-1.0.2k/crypto/bn/bn_exp.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_exp.c 2018-08-14 10:57:21.596518798 +0200 +@@ -466,17 +466,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI + 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 BI + 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 BI + /* 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 BI + 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_PREBU + } + + 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 + 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 + * 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 + + /* 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 + 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 -up openssl-1.0.2k/crypto/bn/bn.h.rohnp-fix openssl-1.0.2k/crypto/bn/bn.h +--- openssl-1.0.2k/crypto/bn/bn.h.rohnp-fix 2018-06-20 17:44:01.752387208 +0200 ++++ openssl-1.0.2k/crypto/bn/bn.h 2018-08-14 10:57:21.592518702 +0200 +@@ -702,6 +702,16 @@ BIGNUM *bn_dup_expand(const BIGNUM *a, i + /* 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 + 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 + + # 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 -up openssl-1.0.2k/crypto/bn/bn_lcl.h.rohnp-fix openssl-1.0.2k/crypto/bn/bn_lcl.h +--- openssl-1.0.2k/crypto/bn/bn_lcl.h.rohnp-fix 2018-06-20 17:44:01.748387114 +0200 ++++ openssl-1.0.2k/crypto/bn/bn_lcl.h 2018-08-14 10:57:21.596518798 +0200 +@@ -113,6 +113,7 @@ + # define HEADER_BN_LCL_H + + # include ++# include "bn_int.h" + + #ifdef __cplusplus + extern "C" { +diff -up openssl-1.0.2k/crypto/bn/bn_lib.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_lib.c +--- openssl-1.0.2k/crypto/bn/bn_lib.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_lib.c 2018-08-14 10:57:21.592518702 +0200 +@@ -290,8 +290,6 @@ static BN_ULONG *bn_expand_internal(cons + 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, i + + 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 -up openssl-1.0.2k/crypto/bn/bn_mod.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_mod.c +--- openssl-1.0.2k/crypto/bn/bn_mod.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_mod.c 2018-08-14 10:57:21.601518919 +0200 +@@ -149,18 +149,73 @@ int BN_mod_add(BIGNUM *r, const BIGNUM * + + /* + * 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_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, +- const BIGNUM *m) ++int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ++ const BIGNUM *m) + { +- if (!BN_uadd(r, a, b)) ++ 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 (BN_ucmp(r, m) >= 0) +- return BN_usub(r, r, m); ++ ++ 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) ++{ ++ 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, + BN_CTX *ctx) + { +diff -up openssl-1.0.2k/crypto/bn/bn_mont.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_mont.c +--- openssl-1.0.2k/crypto/bn/bn_mont.c.rohnp-fix 2018-08-14 10:57:21.589518629 +0200 ++++ openssl-1.0.2k/crypto/bn/bn_mont.c 2018-08-14 11:15:11.425320301 +0200 +@@ -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,12 +123,23 @@ + #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; + #if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) +@@ -140,8 +151,8 @@ int BN_mod_mul_montgomery(BIGNUM *r, con + 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, con + } + /* 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, con + } + + #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(BIGNU + # 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(BIGNU + if (bn_wexpand(ret, nl) == NULL) + return (0); + ret->top = nl; ++ ret->flags |= BN_FLG_FIXED_TOP; + ret->neg = r->neg; + + rp = ret->d; +- ap = &(r->d[nl]); + +-# define BRANCH_FREE 1 +-# if BRANCH_FREE +- { +- BN_ULONG *nrp; +- size_t m; ++ /* ++ * 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]); + +- 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, cons + 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, cons + 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, c + 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, c + 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, c + 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 -up openssl-1.0.2k/crypto/bn/bn_sqr.c.rohnp-fix openssl-1.0.2k/crypto/bn/bn_sqr.c +--- openssl-1.0.2k/crypto/bn/bn_sqr.c.rohnp-fix 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_sqr.c 2018-08-14 10:57:21.593518726 +0200 +@@ -135,14 +135,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, B + } + + 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 -up openssl-1.0.2k/crypto/dsa/dsa_ossl.c.rohnp-fix openssl-1.0.2k/crypto/dsa/dsa_ossl.c +--- openssl-1.0.2k/crypto/dsa/dsa_ossl.c.rohnp-fix 2018-06-20 17:44:02.153396702 +0200 ++++ openssl-1.0.2k/crypto/dsa/dsa_ossl.c 2018-06-20 17:44:02.577406741 +0200 +@@ -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 unsign + } + #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 unsign + 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 unsign + * 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 unsign + 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 -up openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c.rohnp-fix openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c +--- openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c.rohnp-fix 2018-06-20 17:44:02.205397934 +0200 ++++ openssl-1.0.2k/crypto/ecdsa/ecs_ossl.c 2018-08-14 11:18:02.062439755 +0200 +@@ -63,6 +63,7 @@ + #ifdef OPENSSL_FIPS + # include + #endif ++#include "bn_int.h" + + static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + const BIGNUM *, const BIGNUM *, +@@ -98,6 +99,7 @@ static int ecdsa_sign_setup(EC_KEY *ecke + 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); +@@ -129,6 +131,13 @@ static int ecdsa_sign_setup(EC_KEY *ecke + 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 +@@ -142,13 +151,19 @@ static int ecdsa_sign_setup(EC_KEY *ecke + /* + * 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)) { +@@ -240,13 +255,14 @@ static ECDSA_SIG *ecdsa_do_sign(const un + 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; + + #ifdef OPENSSL_FIPS + if (FIPS_selftest_failed()) { +@@ -272,7 +288,7 @@ static ECDSA_SIG *ecdsa_do_sign(const un + 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; + } +@@ -281,6 +297,8 @@ static ECDSA_SIG *ecdsa_do_sign(const un + 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. +@@ -311,21 +329,33 @@ static ECDSA_SIG *ecdsa_do_sign(const un + } + } + +- 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) { +@@ -349,8 +379,6 @@ static ECDSA_SIG *ecdsa_do_sign(const un + BN_CTX_free(ctx); + if (m) + BN_clear_free(m); +- if (tmp) +- BN_clear_free(tmp); + if (order) + BN_free(order); + if (kinv) +diff -up openssl-1.0.2k/crypto/Makefile.rohnp-fix openssl-1.0.2k/crypto/Makefile +--- openssl-1.0.2k/crypto/Makefile.rohnp-fix 2018-06-20 17:44:02.467404137 +0200 ++++ openssl-1.0.2k/crypto/Makefile 2018-08-14 10:57:21.595518774 +0200 +@@ -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/SOURCES/openssl-1.0.2k-cve-2018-0732.patch b/SOURCES/openssl-1.0.2k-cve-2018-0732.patch new file mode 100644 index 0000000..1b8920f --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cve-2018-0734.patch b/SOURCES/openssl-1.0.2k-cve-2018-0734.patch new file mode 100644 index 0000000..64be98a --- /dev/null +++ b/SOURCES/openssl-1.0.2k-cve-2018-0734.patch @@ -0,0 +1,148 @@ +diff -up openssl-1.0.2k/crypto/dsa/dsa_ossl.c.dsa-signing openssl-1.0.2k/crypto/dsa/dsa_ossl.c +--- openssl-1.0.2k/crypto/dsa/dsa_ossl.c.dsa-signing 2019-02-08 10:53:17.825805336 +0100 ++++ openssl-1.0.2k/crypto/dsa/dsa_ossl.c 2019-04-04 16:05:53.155386419 +0200 +@@ -76,6 +76,8 @@ static int dsa_do_verify(const unsigned + DSA_SIG *sig, DSA *dsa); + static int dsa_init(DSA *dsa); + static int dsa_finish(DSA *dsa); ++static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, ++ BN_CTX *ctx); + + static DSA_METHOD openssl_dsa_meth = { + "OpenSSL DSA method", +@@ -275,7 +277,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C + { + BN_CTX *ctx; + BIGNUM k, kq, *K, *kinv = NULL, *r = NULL; ++ BIGNUM l, m; + int ret = 0; ++ int q_bits; + + if (!dsa->p || !dsa->q || !dsa->g) { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); +@@ -284,6 +288,8 @@ static int dsa_sign_setup(DSA *dsa, BN_C + + BN_init(&k); + BN_init(&kq); ++ BN_init(&l); ++ BN_init(&m); + + if (ctx_in == NULL) { + if ((ctx = BN_CTX_new()) == NULL) +@@ -294,6 +300,13 @@ static int dsa_sign_setup(DSA *dsa, BN_C + if ((r = BN_new()) == NULL) + goto err; + ++ /* Preallocate space */ ++ q_bits = BN_num_bits(dsa->q) + sizeof(dsa->q->d[0]) * 16; ++ if (!BN_set_bit(&k, q_bits) ++ || !BN_set_bit(&l, q_bits) ++ || !BN_set_bit(&m, q_bits)) ++ goto err; ++ + /* Get random k */ + do + if (!BN_rand_range(&k, dsa->q)) +@@ -302,9 +315,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_set_flags(&k, BN_FLG_CONSTTIME); ++ BN_set_flags(&l, BN_FLG_CONSTTIME); + } + +- + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) +@@ -314,24 +327,23 @@ static int dsa_sign_setup(DSA *dsa, BN_C + /* Compute r = (g^k mod p) mod q */ + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { +- if (!BN_copy(&kq, &k)) +- goto err; +- +- BN_set_flags(&kq, BN_FLG_CONSTTIME); +- + /* + * We do not want timing information to leak the length of k, so we +- * compute g^k using an equivalent exponent of fixed length. (This +- * is a kludge that we need because the BN_mod_exp_mont() does not +- * let us specify the desired timing behaviour.) ++ * 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 modulus. ++ * ++ * TODO: revisit the BN_copy aiming for a memory access agnostic ++ * conditional copy. + */ +- +- if (!BN_add(&kq, &kq, dsa->q)) ++ if (!BN_add(&l, &k, dsa->q) ++ || !BN_add(&m, &l, dsa->q) ++ || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m)) + goto err; +- if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) { +- if (!BN_add(&kq, &kq, dsa->q)) +- goto err; +- } ++ ++ BN_set_flags(&kq, BN_FLG_CONSTTIME); + + K = &kq; + } else { +@@ -343,8 +355,8 @@ static int dsa_sign_setup(DSA *dsa, BN_C + if (!BN_mod(r, r, dsa->q, ctx)) + goto err; + +- /* Compute part of 's = inv(k) (m + xr) mod q' */ +- if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL) ++ /* Compute part of 's = inv(k) (m + xr) mod q' */ ++ if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL) + goto err; + + if (*kinvp != NULL) +@@ -365,7 +377,9 @@ static int dsa_sign_setup(DSA *dsa, BN_C + BN_CTX_free(ctx); + BN_clear_free(&k); + BN_clear_free(&kq); +- return (ret); ++ BN_clear_free(&l); ++ BN_clear_free(&m); ++ return ret; + } + + static int dsa_do_verify(const unsigned char *dgst, int dgst_len, +@@ -491,3 +505,31 @@ static int dsa_finish(DSA *dsa) + BN_MONT_CTX_free(dsa->method_mont_p); + return (1); + } ++ ++/* ++ * Compute the inverse of k modulo q. ++ * Since q is prime, Fermat's Little Theorem applies, which reduces this to ++ * mod-exp operation. Both the exponent and modulus are public information ++ * so a mod-exp that doesn't leak the base is sufficient. A newly allocated ++ * BIGNUM is returned which the caller must free. ++ */ ++static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, ++ BN_CTX *ctx) ++{ ++ BIGNUM *res = NULL; ++ BIGNUM *r, e; ++ ++ if ((r = BN_new()) == NULL) ++ return NULL; ++ ++ BN_init(&e); ++ ++ if (BN_set_word(r, 2) ++ && BN_sub(&e, q, r) ++ && BN_mod_exp_mont(r, k, &e, q, ctx, NULL)) ++ res = r; ++ else ++ BN_free(r); ++ BN_free(&e); ++ return res; ++} diff --git a/SOURCES/openssl-1.0.2k-cve-2018-0737.patch b/SOURCES/openssl-1.0.2k-cve-2018-0737.patch new file mode 100644 index 0000000..bd9381f --- /dev/null +++ b/SOURCES/openssl-1.0.2k-cve-2018-0737.patch @@ -0,0 +1,274 @@ +diff -up openssl-1.0.2k/crypto/rsa/rsa_gen.c.gen-timing openssl-1.0.2k/crypto/rsa/rsa_gen.c +--- openssl-1.0.2k/crypto/rsa/rsa_gen.c.gen-timing 2018-06-18 13:46:24.323138691 +0200 ++++ openssl-1.0.2k/crypto/rsa/rsa_gen.c 2018-06-18 14:53:26.361975922 +0200 +@@ -1,6 +1,6 @@ + /* crypto/rsa/rsa_gen.c */ + /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +- * Copyright (C) 2013 Red Hat, Inc. ++ * Copyright (C) 2013, 2018 Red Hat, Inc. + * All rights reserved. + * + * This package is an SSL implementation written +@@ -175,14 +175,13 @@ static int FIPS_rsa_builtin_keygen(RSA * + BN_GENCB *cb) + { + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; +- BIGNUM local_r0, local_d, local_p; +- BIGNUM *pr0, *d, *p; + BN_CTX *ctx = NULL; + int ok = -1; + int i; + int n = 0; + int test = 0; + int pbits = bits / 2; ++ unsigned long error = 0; + + if (FIPS_selftest_failed()) { + FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN, FIPS_R_FIPS_SELFTEST_FAILED); +@@ -251,6 +250,12 @@ static int FIPS_rsa_builtin_keygen(RSA * + if (!BN_is_zero(rsa->p) && !BN_is_zero(rsa->q)) + test = 1; + ++ BN_set_flags(r0, BN_FLG_CONSTTIME); ++ BN_set_flags(r1, BN_FLG_CONSTTIME); ++ BN_set_flags(r2, BN_FLG_CONSTTIME); ++ BN_set_flags(rsa->p, BN_FLG_CONSTTIME); ++ BN_set_flags(rsa->q, BN_FLG_CONSTTIME); ++ + retry: + /* generate p and q */ + for (i = 0; i < 5 * pbits; i++) { +@@ -266,9 +271,9 @@ static int FIPS_rsa_builtin_keygen(RSA * + + 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 */ + int r; + r = BN_is_prime_fasttest_ex(rsa->p, pbits > 1024 ? 4 : 5, ctx, 0, + cb); +@@ -276,8 +281,16 @@ static int FIPS_rsa_builtin_keygen(RSA * + goto err; + if (r > 0) + break; ++ } else { ++ 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; + } +@@ -309,9 +322,9 @@ static int FIPS_rsa_builtin_keygen(RSA * + + 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 */ + int r; + r = BN_is_prime_fasttest_ex(rsa->q, pbits > 1024 ? 4 : 5, ctx, 0, + cb); +@@ -319,8 +332,16 @@ static int FIPS_rsa_builtin_keygen(RSA * + goto err; + if (r > 0) + break; ++ } else { ++ 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; + } +@@ -355,51 +376,44 @@ static int FIPS_rsa_builtin_keygen(RSA * + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; /* q-1 */ + ++ /* note that computing gcd is not safe to timing attacks */ + if (!BN_gcd(r0, r1, r2, ctx)) + goto err; +- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { +- pr0 = &local_r0; +- BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); +- } else +- pr0 = r0; +- if (!BN_div(r0, NULL, r1, pr0, ctx)) +- goto err; +- if (!BN_mul(r0, r0, r2, ctx)) +- goto err; /* lcm(p-1, q-1) */ +- +- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { +- pr0 = &local_r0; +- BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); +- } else +- pr0 = r0; +- if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) +- goto err; /* d */ ++ ++ { ++ if (!BN_div(r0, NULL, r1, r0, ctx)) ++ goto err; ++ ++ if (!BN_mul(r0, r0, r2, ctx)) /* lcm(p-1, q-1) */ ++ goto err; ++ ++ if (!BN_mod_inverse(rsa->d, rsa->e, r0, ctx)) /* d */ ++ goto err; ++ } + + if (BN_num_bits(rsa->d) < pbits) + goto retry; /* d is too small */ + +- /* set up d for correct BN_FLG_CONSTTIME flag */ +- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { +- d = &local_d; +- BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); +- } else +- d = rsa->d; ++ { ++ BIGNUM *d = BN_new(); + +- /* calculate d mod (p-1) */ +- if (!BN_mod(rsa->dmp1, d, r1, ctx)) +- goto err; ++ if (d == NULL) ++ goto err; ++ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + +- /* calculate d mod (q-1) */ +- if (!BN_mod(rsa->dmq1, d, r2, ctx)) +- goto err; ++ if (/* calculate d mod (p-1) */ ++ !BN_mod(rsa->dmp1, d, r1, ctx) ++ /* calculate d mod (q-1) */ ++ || !BN_mod(rsa->dmq1, d, r2, ctx)) { ++ BN_free(d); ++ goto err; ++ } ++ /* We MUST free d before any further use of rsa->d */ ++ BN_free(d); ++ } + + /* calculate inverse of q mod p */ +- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { +- p = &local_p; +- BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); +- } else +- p = rsa->p; +- if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) ++ if (!BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) + goto err; + + if (fips_rsa_pairwise_fail) +@@ -431,6 +445,17 @@ static int rsa_builtin_keygen(RSA *rsa, + 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()) { +@@ -483,45 +508,55 @@ static int rsa_builtin_keygen(RSA *rsa, + 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/SOURCES/openssl-1.0.2k-cve-2018-0739.patch b/SOURCES/openssl-1.0.2k-cve-2018-0739.patch new file mode 100644 index 0000000..14d5e0b --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-cve-2018-5407.patch b/SOURCES/openssl-1.0.2k-cve-2018-5407.patch new file mode 100644 index 0000000..4152f20 --- /dev/null +++ b/SOURCES/openssl-1.0.2k-cve-2018-5407.patch @@ -0,0 +1,305 @@ +diff -up openssl-1.0.2k/crypto/bn/bn_lib.c.ecc-ladder openssl-1.0.2k/crypto/bn/bn_lib.c +--- openssl-1.0.2k/crypto/bn/bn_lib.c.ecc-ladder 2019-02-06 12:58:50.575844123 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_lib.c 2019-02-08 10:48:53.529291777 +0100 +@@ -877,6 +877,38 @@ void BN_consttime_swap(BN_ULONG conditio + a->top ^= t; + b->top ^= t; + ++ t = (a->neg ^ b->neg) & condition; ++ a->neg ^= t; ++ b->neg ^= t; ++ ++ /*- ++ * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention ++ * is actually to treat it as it's read-only data, and some (if not most) ++ * of it does reside in read-only segment. In other words observation of ++ * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal ++ * condition. It would either cause SEGV or effectively cause data ++ * corruption. ++ * ++ * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be ++ * preserved. ++ * ++ * BN_FLG_SECURE: must be preserved, because it determines how x->d was ++ * allocated and hence how to free it. ++ * ++ * BN_FLG_CONSTTIME: sufficient to mask and swap ++ * ++ * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on ++ * the data, so the d array may be padded with additional 0 values (i.e. ++ * top could be greater than the minimal value that it could be). We should ++ * be swapping it ++ */ ++ ++#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP) ++ ++ t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition; ++ a->flags ^= t; ++ b->flags ^= t; ++ + #define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ +diff -up openssl-1.0.2k/crypto/ec/ec_mult.c.ecc-ladder openssl-1.0.2k/crypto/ec/ec_mult.c +--- openssl-1.0.2k/crypto/ec/ec_mult.c.ecc-ladder 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/ec/ec_mult.c 2019-02-08 10:48:53.531291744 +0100 +@@ -306,6 +306,224 @@ static signed char *compute_wNAF(const B + return r; + } + ++#define EC_POINT_BN_set_flags(P, flags) do { \ ++ BN_set_flags(&(P)->X, (flags)); \ ++ BN_set_flags(&(P)->Y, (flags)); \ ++ BN_set_flags(&(P)->Z, (flags)); \ ++} while(0) ++ ++/*- ++ * This functions computes (in constant time) a point multiplication over the ++ * EC group. ++ * ++ * At a high level, it is Montgomery ladder with conditional swaps. ++ * ++ * It performs either a fixed scalar point multiplication ++ * (scalar * generator) ++ * when point is NULL, or a generic scalar point multiplication ++ * (scalar * point) ++ * when point is not NULL. ++ * ++ * scalar should be in the range [0,n) otherwise all constant time bets are off. ++ * ++ * NB: This says nothing about EC_POINT_add and EC_POINT_dbl, ++ * which of course are not constant time themselves. ++ * ++ * The product is stored in r. ++ * ++ * Returns 1 on success, 0 otherwise. ++ */ ++static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r, ++ const BIGNUM *scalar, const EC_POINT *point, ++ BN_CTX *ctx) ++{ ++ int i, cardinality_bits, group_top, kbit, pbit, Z_is_one; ++ EC_POINT *s = NULL; ++ BIGNUM *k = NULL; ++ BIGNUM *lambda = NULL; ++ BIGNUM *cardinality = NULL; ++ BN_CTX *new_ctx = NULL; ++ int ret = 0; ++ ++ if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL) ++ return 0; ++ ++ BN_CTX_start(ctx); ++ ++ s = EC_POINT_new(group); ++ if (s == NULL) ++ goto err; ++ ++ if (point == NULL) { ++ if (!EC_POINT_copy(s, group->generator)) ++ goto err; ++ } else { ++ if (!EC_POINT_copy(s, point)) ++ goto err; ++ } ++ ++ EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME); ++ ++ cardinality = BN_CTX_get(ctx); ++ lambda = BN_CTX_get(ctx); ++ k = BN_CTX_get(ctx); ++ if (k == NULL || !BN_mul(cardinality, &group->order, &group->cofactor, ctx)) ++ goto err; ++ ++ /* ++ * Group cardinalities are often on a word boundary. ++ * So when we pad the scalar, some timing diff might ++ * pop if it needs to be expanded due to carries. ++ * So expand ahead of time. ++ */ ++ cardinality_bits = BN_num_bits(cardinality); ++ group_top = cardinality->top; ++ if ((bn_wexpand(k, group_top + 2) == NULL) ++ || (bn_wexpand(lambda, group_top + 2) == NULL)) ++ goto err; ++ ++ if (!BN_copy(k, scalar)) ++ goto err; ++ ++ BN_set_flags(k, BN_FLG_CONSTTIME); ++ ++ if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) { ++ /*- ++ * this is an unusual input, and we don't guarantee ++ * constant-timeness ++ */ ++ if (!BN_nnmod(k, k, cardinality, ctx)) ++ goto err; ++ } ++ ++ if (!BN_add(lambda, k, cardinality)) ++ goto err; ++ BN_set_flags(lambda, BN_FLG_CONSTTIME); ++ if (!BN_add(k, lambda, cardinality)) ++ goto err; ++ /* ++ * lambda := scalar + cardinality ++ * k := scalar + 2*cardinality ++ */ ++ kbit = BN_is_bit_set(lambda, cardinality_bits); ++ BN_consttime_swap(kbit, k, lambda, group_top + 2); ++ ++ group_top = group->field.top; ++ if ((bn_wexpand(&s->X, group_top) == NULL) ++ || (bn_wexpand(&s->Y, group_top) == NULL) ++ || (bn_wexpand(&s->Z, group_top) == NULL) ++ || (bn_wexpand(&r->X, group_top) == NULL) ++ || (bn_wexpand(&r->Y, group_top) == NULL) ++ || (bn_wexpand(&r->Z, group_top) == NULL)) ++ goto err; ++ ++ /* top bit is a 1, in a fixed pos */ ++ if (!EC_POINT_copy(r, s)) ++ goto err; ++ ++ EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME); ++ ++ if (!EC_POINT_dbl(group, s, s, ctx)) ++ goto err; ++ ++ pbit = 0; ++ ++#define EC_POINT_CSWAP(c, a, b, w, t) do { \ ++ BN_consttime_swap(c, &(a)->X, &(b)->X, w); \ ++ BN_consttime_swap(c, &(a)->Y, &(b)->Y, w); \ ++ BN_consttime_swap(c, &(a)->Z, &(b)->Z, w); \ ++ t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ ++ (a)->Z_is_one ^= (t); \ ++ (b)->Z_is_one ^= (t); \ ++} while(0) ++ ++ /*- ++ * The ladder step, with branches, is ++ * ++ * k[i] == 0: S = add(R, S), R = dbl(R) ++ * k[i] == 1: R = add(S, R), S = dbl(S) ++ * ++ * Swapping R, S conditionally on k[i] leaves you with state ++ * ++ * k[i] == 0: T, U = R, S ++ * k[i] == 1: T, U = S, R ++ * ++ * Then perform the ECC ops. ++ * ++ * U = add(T, U) ++ * T = dbl(T) ++ * ++ * Which leaves you with state ++ * ++ * k[i] == 0: U = add(R, S), T = dbl(R) ++ * k[i] == 1: U = add(S, R), T = dbl(S) ++ * ++ * Swapping T, U conditionally on k[i] leaves you with state ++ * ++ * k[i] == 0: R, S = T, U ++ * k[i] == 1: R, S = U, T ++ * ++ * Which leaves you with state ++ * ++ * k[i] == 0: S = add(R, S), R = dbl(R) ++ * k[i] == 1: R = add(S, R), S = dbl(S) ++ * ++ * So we get the same logic, but instead of a branch it's a ++ * conditional swap, followed by ECC ops, then another conditional swap. ++ * ++ * Optimization: The end of iteration i and start of i-1 looks like ++ * ++ * ... ++ * CSWAP(k[i], R, S) ++ * ECC ++ * CSWAP(k[i], R, S) ++ * (next iteration) ++ * CSWAP(k[i-1], R, S) ++ * ECC ++ * CSWAP(k[i-1], R, S) ++ * ... ++ * ++ * So instead of two contiguous swaps, you can merge the condition ++ * bits and do a single swap. ++ * ++ * k[i] k[i-1] Outcome ++ * 0 0 No Swap ++ * 0 1 Swap ++ * 1 0 Swap ++ * 1 1 No Swap ++ * ++ * This is XOR. pbit tracks the previous bit of k. ++ */ ++ ++ for (i = cardinality_bits - 1; i >= 0; i--) { ++ kbit = BN_is_bit_set(k, i) ^ pbit; ++ EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one); ++ if (!EC_POINT_add(group, s, r, s, ctx)) ++ goto err; ++ if (!EC_POINT_dbl(group, r, r, ctx)) ++ goto err; ++ /* ++ * pbit logic merges this cswap with that of the ++ * next iteration ++ */ ++ pbit ^= kbit; ++ } ++ /* one final cswap to move the right value into r */ ++ EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one); ++#undef EC_POINT_CSWAP ++ ++ ret = 1; ++ ++ err: ++ EC_POINT_free(s); ++ BN_CTX_end(ctx); ++ BN_CTX_free(new_ctx); ++ ++ return ret; ++} ++ ++#undef EC_POINT_BN_set_flags ++ + /* + * TODO: table should be optimised for the wNAF-based implementation, + * sometimes smaller windows will give better performance (thus the +@@ -365,6 +583,34 @@ int ec_wNAF_mul(const EC_GROUP *group, E + return EC_POINT_set_to_infinity(group, r); + } + ++ if (!BN_is_zero(&group->order) && !BN_is_zero(&group->cofactor)) { ++ /*- ++ * Handle the common cases where the scalar is secret, enforcing a constant ++ * time scalar multiplication algorithm. ++ */ ++ if ((scalar != NULL) && (num == 0)) { ++ /*- ++ * In this case we want to compute scalar * GeneratorPoint: this ++ * codepath is reached most prominently by (ephemeral) key generation ++ * of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH ++ * keygen/first half), where the scalar is always secret. This is why ++ * we ignore if BN_FLG_CONSTTIME is actually set and we always call the ++ * constant time version. ++ */ ++ return ec_mul_consttime(group, r, scalar, NULL, ctx); ++ } ++ if ((scalar == NULL) && (num == 1)) { ++ /*- ++ * In this case we want to compute scalar * GenericPoint: this codepath ++ * is reached most prominently by the second half of ECDH, where the ++ * secret scalar is multiplied by the peer's public point. To protect ++ * the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and ++ * we always call the constant time version. ++ */ ++ return ec_mul_consttime(group, r, scalars[0], points[0], ctx); ++ } ++ } ++ + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); diff --git a/SOURCES/openssl-1.0.2k-cve-2019-1559.patch b/SOURCES/openssl-1.0.2k-cve-2019-1559.patch new file mode 100644 index 0000000..b8a7793 --- /dev/null +++ b/SOURCES/openssl-1.0.2k-cve-2019-1559.patch @@ -0,0 +1,38 @@ +diff -up openssl-1.0.2k/ssl/d1_pkt.c.padding-oracle openssl-1.0.2k/ssl/d1_pkt.c +--- openssl-1.0.2k/ssl/d1_pkt.c.padding-oracle 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/ssl/d1_pkt.c 2019-04-05 10:39:08.574409987 +0200 +@@ -1290,6 +1290,7 @@ int dtls1_read_bytes(SSL *s, int type, u + ERR_add_error_data(2, "SSL alert number ", tmp); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->session_ctx, s->session); ++ s->state = SSL_ST_ERR; + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; +diff -up openssl-1.0.2k/ssl/s3_pkt.c.padding-oracle openssl-1.0.2k/ssl/s3_pkt.c +--- openssl-1.0.2k/ssl/s3_pkt.c.padding-oracle 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/ssl/s3_pkt.c 2019-04-05 10:40:35.838894197 +0200 +@@ -1495,6 +1495,7 @@ int ssl3_read_bytes(SSL *s, int type, un + ERR_add_error_data(2, "SSL alert number ", tmp); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->session_ctx, s->session); ++ s->state = SSL_ST_ERR; + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; +@@ -1714,9 +1715,12 @@ int ssl3_send_alert(SSL *s, int level, i + * protocol_version alerts */ + if (desc < 0) + return -1; +- /* If a fatal one, remove from cache */ +- if ((level == 2) && (s->session != NULL)) +- SSL_CTX_remove_session(s->session_ctx, s->session); ++ /* If a fatal one, remove from cache and go into the error state */ ++ if (level == SSL3_AL_FATAL) { ++ if (s->session != NULL) ++ SSL_CTX_remove_session(s->session_ctx, s->session); ++ s->state = SSL_ST_ERR; ++ } + + s->s3->alert_dispatch = 1; + s->s3->send_alert[0] = level; diff --git a/SOURCES/openssl-1.0.2k-fips-randlock.patch b/SOURCES/openssl-1.0.2k-fips-randlock.patch new file mode 100644 index 0000000..8b08ef4 --- /dev/null +++ b/SOURCES/openssl-1.0.2k-fips-randlock.patch @@ -0,0 +1,65 @@ +diff -up openssl-1.0.2k/crypto/fips/fips_drbg_lib.c.fips-randlock openssl-1.0.2k/crypto/fips/fips_drbg_lib.c +--- openssl-1.0.2k/crypto/fips/fips_drbg_lib.c.fips-randlock 2017-03-09 17:59:26.249231181 +0100 ++++ openssl-1.0.2k/crypto/fips/fips_drbg_lib.c 2017-11-16 09:16:06.188098078 +0100 +@@ -338,6 +338,12 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx, + return drbg_reseed(dctx, adin, adinlen, 1); + } + ++void FIPS_drbg_set_reseed(DRBG_CTX *dctx) ++{ ++ if (dctx->status == DRBG_STATUS_READY) ++ dctx->reseed_counter = dctx->reseed_interval; ++} ++ + static int fips_drbg_check(DRBG_CTX *dctx) + { + if (dctx->xflags & DRBG_FLAG_TEST) +diff -up openssl-1.0.2k/crypto/fips/fips_rand.h.fips-randlock openssl-1.0.2k/crypto/fips/fips_rand.h +--- openssl-1.0.2k/crypto/fips/fips_rand.h.fips-randlock 2017-03-09 17:59:26.252231250 +0100 ++++ openssl-1.0.2k/crypto/fips/fips_rand.h 2017-11-07 10:06:40.241450151 +0100 +@@ -86,6 +86,7 @@ extern "C" { + const unsigned char *pers, size_t perslen); + int FIPS_drbg_reseed(DRBG_CTX *dctx, const unsigned char *adin, + size_t adinlen); ++ void FIPS_drbg_set_reseed(DRBG_CTX *dctx); + int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen); +diff -up openssl-1.0.2k/crypto/rand/md_rand.c.fips-randlock openssl-1.0.2k/crypto/rand/md_rand.c +--- openssl-1.0.2k/crypto/rand/md_rand.c.fips-randlock 2017-03-09 17:59:26.255231320 +0100 ++++ openssl-1.0.2k/crypto/rand/md_rand.c 2017-12-06 09:20:23.615879425 +0100 +@@ -391,10 +391,10 @@ int ssleay_rand_bytes(unsigned char *buf + CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); + crypto_lock_rand = 1; + +- /* always poll for external entropy in FIPS mode, drbg provides the +- * expansion ++ /* always poll for external entropy in FIPS mode, if run as seed ++ * source, drbg provides the expansion + */ +- if (!initialized || FIPS_module_mode()) { ++ if (!initialized || (!lock && FIPS_module_mode())) { + RAND_poll(); + initialized = 1; + } +diff -up openssl-1.0.2k/crypto/rand/rand_lib.c.fips-randlock openssl-1.0.2k/crypto/rand/rand_lib.c +--- openssl-1.0.2k/crypto/rand/rand_lib.c.fips-randlock 2017-03-09 17:59:26.292232183 +0100 ++++ openssl-1.0.2k/crypto/rand/rand_lib.c 2017-11-07 10:20:08.050403861 +0100 +@@ -238,7 +238,7 @@ static int drbg_rand_add(DRBG_CTX *ctx, + RAND_SSLeay()->add(in, inlen, entropy); + if (FIPS_rand_status()) { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); +- FIPS_drbg_reseed(ctx, NULL, 0); ++ FIPS_drbg_set_reseed(ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + return 1; +@@ -249,7 +249,7 @@ static int drbg_rand_seed(DRBG_CTX *ctx, + RAND_SSLeay()->seed(in, inlen); + if (FIPS_rand_status()) { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); +- FIPS_drbg_reseed(ctx, NULL, 0); ++ FIPS_drbg_set_reseed(ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + return 1; diff --git a/SOURCES/openssl-1.0.2k-fix-9-lives.patch b/SOURCES/openssl-1.0.2k-fix-9-lives.patch new file mode 100644 index 0000000..62b9b03 --- /dev/null +++ b/SOURCES/openssl-1.0.2k-fix-9-lives.patch @@ -0,0 +1,1445 @@ +diff -up openssl-1.0.2k/crypto/bn/bn_blind.c.9-lives openssl-1.0.2k/crypto/bn/bn_blind.c +--- openssl-1.0.2k/crypto/bn/bn_blind.c.9-lives 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_blind.c 2019-04-05 10:50:56.136104388 +0200 +@@ -206,10 +206,15 @@ int BN_BLINDING_update(BN_BLINDING *b, B + if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) + goto err; + } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) { +- if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) +- goto err; +- if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)) +- goto err; ++ if (b->m_ctx != NULL) { ++ if (!bn_mul_mont_fixed_top(b->Ai, b->Ai, b->Ai, b->m_ctx, ctx) ++ || !bn_mul_mont_fixed_top(b->A, b->A, b->A, b->m_ctx, ctx)) ++ goto err; ++ } else { ++ if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx) ++ || !BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) ++ goto err; ++ } + } + + ret = 1; +@@ -241,13 +246,13 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BI + else if (!BN_BLINDING_update(b, ctx)) + return (0); + +- if (r != NULL) { +- if (!BN_copy(r, b->Ai)) +- ret = 0; +- } ++ if (r != NULL && (BN_copy(r, b->Ai) == NULL)) ++ return 0; + +- if (!BN_mod_mul(n, n, b->A, b->mod, ctx)) +- ret = 0; ++ if (b->m_ctx != NULL) ++ ret = BN_mod_mul_montgomery(n, n, b->A, b->m_ctx, ctx); ++ else ++ ret = BN_mod_mul(n, n, b->A, b->mod, ctx); + + return ret; + } +@@ -264,14 +269,29 @@ int BN_BLINDING_invert_ex(BIGNUM *n, con + + bn_check_top(n); + +- if (r != NULL) +- ret = BN_mod_mul(n, n, r, b->mod, ctx); +- else { +- if (b->Ai == NULL) { +- BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); +- return (0); ++ if (r == NULL && (r = b->Ai) == NULL) { ++ BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); ++ return 0; ++ } ++ ++ if (b->m_ctx != NULL) { ++ /* ensure that BN_mod_mul_montgomery takes pre-defined path */ ++ if (n->dmax >= r->top) { ++ size_t i, rtop = r->top, ntop = n->top; ++ BN_ULONG mask; ++ ++ for (i = 0; i < rtop; i++) { ++ mask = (BN_ULONG)0 - ((i - ntop) >> (8 * sizeof(i) - 1)); ++ n->d[i] &= mask; ++ } ++ mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1)); ++ /* always true, if (rtop >= ntop) n->top = r->top; */ ++ n->top = (int)(rtop & ~mask) | (ntop & mask); ++ n->flags |= (BN_FLG_FIXED_TOP & ~mask); + } +- ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); ++ ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx); ++ } else { ++ ret = BN_mod_mul(n, n, r, b->mod, ctx); + } + + bn_check_top(n); +@@ -366,14 +386,19 @@ BN_BLINDING *BN_BLINDING_create_param(BN + } while (1); + + if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { +- if (!ret->bn_mod_exp +- (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) ++ if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) + goto err; + } else { + if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) + goto err; + } + ++ if (ret->m_ctx != NULL) { ++ if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx) ++ || !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx)) ++ goto err; ++ } ++ + return ret; + err: + if (b == NULL && ret != NULL) { +diff -up openssl-1.0.2k/crypto/bn/bn_lib.c.9-lives openssl-1.0.2k/crypto/bn/bn_lib.c +--- openssl-1.0.2k/crypto/bn/bn_lib.c.9-lives 2019-04-05 10:50:56.128104529 +0200 ++++ openssl-1.0.2k/crypto/bn/bn_lib.c 2019-04-05 10:50:56.136104388 +0200 +@@ -144,74 +144,47 @@ const BIGNUM *BN_value_one(void) + + int BN_num_bits_word(BN_ULONG l) + { +- static const unsigned char bits[256] = { +- 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, +- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +- }; +- +-#if defined(SIXTY_FOUR_BIT_LONG) +- if (l & 0xffffffff00000000L) { +- if (l & 0xffff000000000000L) { +- if (l & 0xff00000000000000L) { +- return (bits[(int)(l >> 56)] + 56); +- } else +- return (bits[(int)(l >> 48)] + 48); +- } else { +- if (l & 0x0000ff0000000000L) { +- return (bits[(int)(l >> 40)] + 40); +- } else +- return (bits[(int)(l >> 32)] + 32); +- } +- } else +-#else +-# ifdef SIXTY_FOUR_BIT +- if (l & 0xffffffff00000000LL) { +- if (l & 0xffff000000000000LL) { +- if (l & 0xff00000000000000LL) { +- return (bits[(int)(l >> 56)] + 56); +- } else +- return (bits[(int)(l >> 48)] + 48); +- } else { +- if (l & 0x0000ff0000000000LL) { +- return (bits[(int)(l >> 40)] + 40); +- } else +- return (bits[(int)(l >> 32)] + 32); +- } +- } else +-# endif +-#endif +- { +-#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) +- if (l & 0xffff0000L) { +- if (l & 0xff000000L) +- return (bits[(int)(l >> 24L)] + 24); +- else +- return (bits[(int)(l >> 16L)] + 16); +- } else +-#endif +- { +-#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) +- if (l & 0xff00L) +- return (bits[(int)(l >> 8)] + 8); +- else ++ BN_ULONG x, mask; ++ int bits = (l != 0); ++ ++#if BN_BITS2 > 32 ++ x = l >> 32; ++ mask = (0 - x) & BN_MASK2; ++ mask = (0 - (mask >> (BN_BITS2 - 1))); ++ bits += 32 & mask; ++ l ^= (x ^ l) & mask; + #endif +- return (bits[(int)(l)]); +- } +- } ++ ++ x = l >> 16; ++ mask = (0 - x) & BN_MASK2; ++ mask = (0 - (mask >> (BN_BITS2 - 1))); ++ bits += 16 & mask; ++ l ^= (x ^ l) & mask; ++ ++ x = l >> 8; ++ mask = (0 - x) & BN_MASK2; ++ mask = (0 - (mask >> (BN_BITS2 - 1))); ++ bits += 8 & mask; ++ l ^= (x ^ l) & mask; ++ ++ x = l >> 4; ++ mask = (0 - x) & BN_MASK2; ++ mask = (0 - (mask >> (BN_BITS2 - 1))); ++ bits += 4 & mask; ++ l ^= (x ^ l) & mask; ++ ++ x = l >> 2; ++ mask = (0 - x) & BN_MASK2; ++ mask = (0 - (mask >> (BN_BITS2 - 1))); ++ bits += 2 & mask; ++ l ^= (x ^ l) & mask; ++ ++ x = l >> 1; ++ mask = (0 - x) & BN_MASK2; ++ mask = (0 - (mask >> (BN_BITS2 - 1))); ++ bits += 1 & mask; ++ ++ return bits; + } + + int BN_num_bits(const BIGNUM *a) +@@ -519,12 +492,18 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM + memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); + #endif + +- a->top = b->top; + a->neg = b->neg; ++ a->top = b->top; ++ a->flags |= b->flags & BN_FLG_FIXED_TOP; + bn_check_top(a); + return (a); + } + ++#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \ ++ | BN_FLG_CONSTTIME \ ++ | BN_FLG_FIXED_TOP)) ++#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED)) ++ + void BN_swap(BIGNUM *a, BIGNUM *b) + { + int flags_old_a, flags_old_b; +@@ -552,10 +531,8 @@ void BN_swap(BIGNUM *a, BIGNUM *b) + b->dmax = tmp_dmax; + b->neg = tmp_neg; + +- a->flags = +- (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA); +- b->flags = +- (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA); ++ a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b); ++ b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a); + bn_check_top(a); + bn_check_top(b); + } +@@ -637,6 +614,55 @@ BIGNUM *BN_bin2bn(const unsigned char *s + } + + /* ignore negative */ ++static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) ++{ ++ int n; ++ size_t i, lasti, j, atop, mask; ++ BN_ULONG l; ++ ++ /* ++ * In case |a| is fixed-top, BN_num_bytes can return bogus length, ++ * but it's assumed that fixed-top inputs ought to be "nominated" ++ * even for padded output, so it works out... ++ */ ++ n = BN_num_bytes(a); ++ if (tolen == -1) { ++ tolen = n; ++ } else if (tolen < n) { /* uncommon/unlike case */ ++ BIGNUM temp = *a; ++ ++ bn_correct_top(&temp); ++ n = BN_num_bytes(&temp); ++ if (tolen < n) ++ return -1; ++ } ++ ++ /* Swipe through whole available data and don't give away padded zero. */ ++ atop = a->dmax * BN_BYTES; ++ if (atop == 0) { ++ OPENSSL_cleanse(to, tolen); ++ return tolen; ++ } ++ ++ lasti = atop - 1; ++ atop = a->top * BN_BYTES; ++ for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) { ++ l = a->d[i / BN_BYTES]; ++ mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); ++ *--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); ++ i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ ++ } ++ ++ return tolen; ++} ++ ++int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) ++{ ++ if (tolen < 0) ++ return -1; ++ return bn2binpad(a, to, tolen); ++} ++ + int BN_bn2bin(const BIGNUM *a, unsigned char *to) + { + int n, i; +@@ -810,6 +836,9 @@ int bn_cmp_words(const BN_ULONG *a, cons + int i; + BN_ULONG aa, bb; + ++ if (n == 0) ++ return 0; ++ + aa = a[n - 1]; + bb = b[n - 1]; + if (aa != bb) +diff -up openssl-1.0.2k/crypto/bn/bn_mod.c.9-lives openssl-1.0.2k/crypto/bn/bn_mod.c +--- openssl-1.0.2k/crypto/bn/bn_mod.c.9-lives 2019-04-05 10:50:56.125104581 +0200 ++++ openssl-1.0.2k/crypto/bn/bn_mod.c 2019-04-05 10:50:56.136104388 +0200 +@@ -197,6 +197,7 @@ int bn_mod_add_fixed_top(BIGNUM *r, cons + ((volatile BN_ULONG *)tp)[i] = 0; + } + r->top = mtop; ++ r->flags |= BN_FLG_FIXED_TOP; + r->neg = 0; + + if (tp != storage) +@@ -225,6 +226,70 @@ int BN_mod_sub(BIGNUM *r, const BIGNUM * + } + + /* ++ * BN_mod_sub variant that may be used if both a and b are non-negative, ++ * a is less than m, while b is of same bit width as m. It's implemented ++ * as subtraction followed by two conditional additions. ++ * ++ * 0 <= a < m ++ * 0 <= b < 2^w < 2*m ++ * ++ * after subtraction ++ * ++ * -2*m < r = a - b < m ++ * ++ * Thus it takes up to two conditional additions to make |r| positive. ++ */ ++int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ++ const BIGNUM *m) ++{ ++ size_t i, ai, bi, mtop = m->top; ++ BN_ULONG borrow, carry, ta, tb, mask, *rp; ++ const BN_ULONG *ap, *bp; ++ ++ if (bn_wexpand(r, m->top) == NULL) ++ return 0; ++ ++ rp = r->d; ++ ap = a->d != NULL ? a->d : rp; ++ bp = b->d != NULL ? b->d : rp; ++ ++ for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) { ++ mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); ++ ta = ap[ai] & mask; ++ ++ mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); ++ tb = bp[bi] & mask; ++ rp[i] = ta - tb - borrow; ++ if (ta != tb) ++ borrow = (ta < tb); ++ ++ i++; ++ ai += (i - a->dmax) >> (8 * sizeof(i) - 1); ++ bi += (i - b->dmax) >> (8 * sizeof(i) - 1); ++ } ++ ap = m->d; ++ for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { ++ ta = ((ap[i] & mask) + carry) & BN_MASK2; ++ carry = (ta < carry); ++ rp[i] = (rp[i] + ta) & BN_MASK2; ++ carry += (rp[i] < ta); ++ } ++ borrow -= carry; ++ for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { ++ ta = ((ap[i] & mask) + carry) & BN_MASK2; ++ carry = (ta < carry); ++ rp[i] = (rp[i] + ta) & BN_MASK2; ++ carry += (rp[i] < ta); ++ } ++ ++ r->top = mtop; ++ r->flags |= BN_FLG_FIXED_TOP; ++ r->neg = 0; ++ ++ return 1; ++} ++ ++/* + * BN_mod_sub variant that may be used if both a and b are non-negative and + * less than m + */ +diff -up openssl-1.0.2k/crypto/bn/bn_mont.c.9-lives openssl-1.0.2k/crypto/bn/bn_mont.c +--- openssl-1.0.2k/crypto/bn/bn_mont.c.9-lives 2019-04-05 10:50:56.125104581 +0200 ++++ openssl-1.0.2k/crypto/bn/bn_mont.c 2019-04-05 10:50:56.137104370 +0200 +@@ -164,10 +164,10 @@ int bn_mul_mont_fixed_top(BIGNUM *r, con + + bn_check_top(tmp); + if (a == b) { +- if (!BN_sqr(tmp, a, ctx)) ++ if (!bn_sqr_fixed_top(tmp, a, ctx)) + goto err; + } else { +- if (!BN_mul(tmp, a, b, ctx)) ++ if (!bn_mul_fixed_top(tmp, a, b, ctx)) + goto err; + } + /* reduce from aRR to aR */ +@@ -190,6 +190,7 @@ static int bn_from_montgomery_word(BIGNU + BIGNUM *n; + BN_ULONG *ap, *np, *rp, n0, v, carry; + int nl, max, i; ++ unsigned int rtop; + + n = &(mont->N); + nl = n->top; +@@ -207,12 +208,10 @@ static int bn_from_montgomery_word(BIGNU + rp = r->d; + + /* clear the top words of T */ +-# if 1 +- for (i = r->top; i < max; i++) /* memset? XXX */ +- rp[i] = 0; +-# else +- memset(&(rp[r->top]), 0, (max - r->top) * sizeof(BN_ULONG)); +-# endif ++ for (rtop = r->top, i = 0; i < max; i++) { ++ v = (BN_ULONG)0 - ((i - rtop) >> (8 * sizeof(rtop) - 1)); ++ rp[i] &= v; ++ } + + r->top = max; + r->flags |= BN_FLG_FIXED_TOP; +@@ -263,6 +262,18 @@ static int bn_from_montgomery_word(BIGNU + int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) + { ++ int retn; ++ ++ retn = bn_from_mont_fixed_top(ret, a, mont, ctx); ++ bn_correct_top(ret); ++ bn_check_top(ret); ++ ++ return retn; ++} ++ ++int bn_from_mont_fixed_top(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, ++ BN_CTX *ctx) ++{ + int retn = 0; + #ifdef MONT_WORD + BIGNUM *t; +@@ -270,8 +281,6 @@ int BN_from_montgomery(BIGNUM *ret, cons + BN_CTX_start(ctx); + 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 */ +diff -up openssl-1.0.2k/crypto/bn/bn_mul.c.9-lives openssl-1.0.2k/crypto/bn/bn_mul.c +--- openssl-1.0.2k/crypto/bn/bn_mul.c.9-lives 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/bn/bn_mul.c 2019-04-05 10:50:56.137104370 +0200 +@@ -936,6 +936,16 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG * + + int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) + { ++ int ret = bn_mul_fixed_top(r, a, b, ctx); ++ ++ bn_correct_top(r); ++ bn_check_top(r); ++ ++ return ret; ++} ++ ++int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) ++{ + int ret = 0; + int top, al, bl; + BIGNUM *rr; +@@ -1032,46 +1042,6 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, c + rr->top = top; + goto end; + } +-# if 0 +- if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) { +- BIGNUM *tmp_bn = (BIGNUM *)b; +- if (bn_wexpand(tmp_bn, al) == NULL) +- goto err; +- tmp_bn->d[bl] = 0; +- bl++; +- i--; +- } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { +- BIGNUM *tmp_bn = (BIGNUM *)a; +- if (bn_wexpand(tmp_bn, bl) == NULL) +- goto err; +- tmp_bn->d[al] = 0; +- al++; +- i++; +- } +- if (i == 0) { +- /* symmetric and > 4 */ +- /* 16 or larger */ +- j = BN_num_bits_word((BN_ULONG)al); +- j = 1 << (j - 1); +- k = j + j; +- t = BN_CTX_get(ctx); +- if (al == j) { /* exact multiple */ +- if (bn_wexpand(t, k * 2) == NULL) +- goto err; +- if (bn_wexpand(rr, k * 2) == NULL) +- goto err; +- bn_mul_recursive(rr->d, a->d, b->d, al, t->d); +- } else { +- if (bn_wexpand(t, k * 4) == NULL) +- goto err; +- if (bn_wexpand(rr, k * 4) == NULL) +- goto err; +- bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d); +- } +- rr->top = top; +- goto end; +- } +-# endif + } + #endif /* BN_RECURSION */ + if (bn_wexpand(rr, top) == NULL) +@@ -1082,7 +1052,7 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, c + #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + end: + #endif +- bn_correct_top(rr); ++ rr->flags |= BN_FLG_FIXED_TOP; + if (r != rr && BN_copy(r, rr) == NULL) + goto err; + +diff -up openssl-1.0.2k/crypto/bn/bn_sqr.c.9-lives openssl-1.0.2k/crypto/bn/bn_sqr.c +--- openssl-1.0.2k/crypto/bn/bn_sqr.c.9-lives 2019-04-05 10:50:56.125104581 +0200 ++++ openssl-1.0.2k/crypto/bn/bn_sqr.c 2019-04-05 10:50:56.137104370 +0200 +@@ -66,6 +66,16 @@ + */ + int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) + { ++ int ret = bn_sqr_fixed_top(r, a, ctx); ++ ++ bn_correct_top(r); ++ bn_check_top(r); ++ ++ return ret; ++} ++ ++int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) ++{ + int max, al; + int ret = 0; + BIGNUM *tmp, *rr; +@@ -136,7 +146,7 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, B + + rr->neg = 0; + rr->top = max; +- bn_correct_top(rr); ++ rr->flags |= BN_FLG_FIXED_TOP; + if (r != rr && BN_copy(r, rr) == NULL) + goto err; + +diff -up openssl-1.0.2k/crypto/bn_int.h.9-lives openssl-1.0.2k/crypto/bn_int.h +--- openssl-1.0.2k/crypto/bn_int.h.9-lives 2019-04-05 10:50:56.125104581 +0200 ++++ openssl-1.0.2k/crypto/bn_int.h 2019-04-05 10:50:56.137104370 +0200 +@@ -7,7 +7,15 @@ + */ + int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); ++int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, 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); ++int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ++ const BIGNUM *m); ++int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); ++int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); ++ ++int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); +diff -up openssl-1.0.2k/crypto/constant_time_locl.h.9-lives openssl-1.0.2k/crypto/constant_time_locl.h +--- openssl-1.0.2k/crypto/constant_time_locl.h.9-lives 2019-04-05 10:50:55.545114779 +0200 ++++ openssl-1.0.2k/crypto/constant_time_locl.h 2019-04-05 10:50:56.137104370 +0200 +@@ -204,6 +204,12 @@ static inline int constant_time_select_i + return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); + } + ++/* ++ * Expected usage pattern is to unconditionally set error and then ++ * wipe it if there was no actual error. |clear| is 1 or 0. ++ */ ++void err_clear_last_constant_time(int clear); ++ + #ifdef __cplusplus + } + #endif +diff -up openssl-1.0.2k/crypto/err/err.c.9-lives openssl-1.0.2k/crypto/err/err.c +--- openssl-1.0.2k/crypto/err/err.c.9-lives 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/err/err.c 2019-04-05 10:50:56.138104353 +0200 +@@ -118,6 +118,7 @@ + #include + #include + #include ++#include "constant_time_locl.h" + + DECLARE_LHASH_OF(ERR_STRING_DATA); + DECLARE_LHASH_OF(ERR_STATE); +@@ -819,8 +820,24 @@ static unsigned long get_error_values(in + return ERR_R_INTERNAL_ERROR; + } + ++ while (es->bottom != es->top) { ++ if (es->err_flags[es->top] & ERR_FLAG_CLEAR) { ++ err_clear(es, es->top); ++ es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; ++ continue; ++ } ++ i = (es->bottom + 1) % ERR_NUM_ERRORS; ++ if (es->err_flags[i] & ERR_FLAG_CLEAR) { ++ es->bottom = i; ++ err_clear(es, es->bottom); ++ continue; ++ } ++ break; ++ } ++ + if (es->bottom == es->top) + return 0; ++ + if (top) + i = es->top; /* last error */ + else +@@ -1146,3 +1163,23 @@ int ERR_pop_to_mark(void) + es->err_flags[es->top] &= ~ERR_FLAG_MARK; + return 1; + } ++ ++void err_clear_last_constant_time(int clear) ++{ ++ ERR_STATE *es; ++ int top; ++ ++ es = ERR_get_state(); ++ if (es == NULL) ++ return; ++ ++ top = es->top; ++ ++ /* ++ * Flag error as cleared but remove it elsewhere to avoid two errors ++ * accessing the same error stack location, revealing timing information. ++ */ ++ clear = constant_time_select_int(constant_time_eq_int(clear, 0), ++ 0, ERR_FLAG_CLEAR); ++ es->err_flags[top] |= clear; ++} +diff -up openssl-1.0.2k/crypto/err/err.h.9-lives openssl-1.0.2k/crypto/err/err.h +--- openssl-1.0.2k/crypto/err/err.h.9-lives 2019-04-05 10:50:55.450116449 +0200 ++++ openssl-1.0.2k/crypto/err/err.h 2019-04-05 11:14:57.689757981 +0200 +@@ -143,6 +143,7 @@ extern "C" { + # define ERR_TXT_STRING 0x02 + + # define ERR_FLAG_MARK 0x01 ++# define ERR_FLAG_CLEAR 0x02 + + # define ERR_NUM_ERRORS 16 + typedef struct err_state_st { +diff -up openssl-1.0.2k/crypto/rsa/rsa_eay.c.9-lives openssl-1.0.2k/crypto/rsa/rsa_eay.c +--- openssl-1.0.2k/crypto/rsa/rsa_eay.c.9-lives 2019-04-05 10:50:55.998106814 +0200 ++++ openssl-1.0.2k/crypto/rsa/rsa_eay.c 2019-04-05 10:50:56.138104353 +0200 +@@ -118,6 +118,8 @@ + #ifdef OPENSSL_FIPS + # include + #endif ++#include "bn_int.h" ++#include "constant_time_locl.h" + + #ifndef RSA_NULL + +@@ -160,7 +162,7 @@ static int RSA_eay_public_encrypt(int fl + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f, *ret; +- int i, j, k, num = 0, r = -1; ++ int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + +@@ -252,15 +254,10 @@ static int RSA_eay_public_encrypt(int fl + goto err; + + /* +- * put in leading 0 bytes if the number is less than the length of the +- * modulus ++ * BN_bn2binpad puts in leading 0 bytes if the number is less than ++ * the length of the modulus. + */ +- j = BN_num_bytes(ret); +- i = BN_bn2bin(ret, &(to[num - j])); +- for (k = 0; k < (num - i); k++) +- to[k] = 0; +- +- r = num; ++ r = bn_bn2binpad(ret, to, num); + err: + if (ctx != NULL) { + BN_CTX_end(ctx); +@@ -369,7 +366,7 @@ static int RSA_eay_private_encrypt(int f + unsigned char *to, RSA *rsa, int padding) + { + BIGNUM *f, *ret, *res; +- int i, j, k, num = 0, r = -1; ++ int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; +@@ -437,6 +434,11 @@ static int RSA_eay_private_encrypt(int f + goto err; + } + ++ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) ++ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, ++ rsa->n, ctx)) ++ goto err; ++ + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { +@@ -471,11 +473,6 @@ static int RSA_eay_private_encrypt(int f + } else + d = rsa->d; + +- if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) +- if (!BN_MONT_CTX_set_locked +- (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) +- goto err; +- + if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; +@@ -495,15 +492,10 @@ static int RSA_eay_private_encrypt(int f + res = ret; + + /* +- * put in leading 0 bytes if the number is less than the length of the +- * modulus ++ * BN_bn2binpad puts in leading 0 bytes if the number is less than ++ * the length of the modulus. + */ +- j = BN_num_bytes(res); +- i = BN_bn2bin(res, &(to[num - j])); +- for (k = 0; k < (num - i); k++) +- to[k] = 0; +- +- r = num; ++ r = bn_bn2binpad(res, to, num); + err: + if (ctx != NULL) { + BN_CTX_end(ctx); +@@ -521,7 +513,6 @@ static int RSA_eay_private_decrypt(int f + { + BIGNUM *f, *ret; + int j, num = 0, r = -1; +- unsigned char *p; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; +@@ -628,8 +619,7 @@ static int RSA_eay_private_decrypt(int f + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + +- p = buf; +- j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */ ++ j = bn_bn2binpad(ret, buf, num); + + switch (padding) { + case RSA_PKCS1_PADDING: +@@ -644,14 +634,14 @@ static int RSA_eay_private_decrypt(int f + r = RSA_padding_check_SSLv23(to, num, buf, j, num); + break; + case RSA_NO_PADDING: +- r = RSA_padding_check_none(to, num, buf, j, num); ++ memcpy(to, buf, (r = j)); + break; + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } +- if (r < 0) +- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); ++ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); ++ err_clear_last_constant_time(1 & ~constant_time_msb(r)); + + err: + if (ctx != NULL) { +@@ -671,7 +661,6 @@ static int RSA_eay_public_decrypt(int fl + { + BIGNUM *f, *ret; + int i, num = 0, r = -1; +- unsigned char *p; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + +@@ -752,8 +741,7 @@ static int RSA_eay_public_decrypt(int fl + if (!BN_sub(ret, rsa->n, ret)) + goto err; + +- p = buf; +- i = BN_bn2bin(ret, p); ++ i = bn_bn2binpad(ret, buf, num); + + switch (padding) { + case RSA_PKCS1_PADDING: +@@ -763,7 +751,7 @@ static int RSA_eay_public_decrypt(int fl + r = RSA_padding_check_X931(to, num, buf, i, num); + break; + case RSA_NO_PADDING: +- r = RSA_padding_check_none(to, num, buf, i, num); ++ memcpy(to, buf, (r = i)); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); +@@ -789,7 +777,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c + BIGNUM *r1, *m1, *vrfy; + BIGNUM local_dmp1, local_dmq1, local_c, local_r1; + BIGNUM *dmp1, *dmq1, *c, *pr1; +- int ret = 0; ++ int ret = 0, smooth = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); +@@ -824,6 +812,9 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx)) + goto err; ++ ++ smooth = (rsa->meth->bn_mod_exp == BN_mod_exp_mont) ++ && (BN_num_bits(q) == BN_num_bits(p)); + } + } + +@@ -832,6 +823,47 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c + (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + ++ if (smooth) { ++ /* ++ * Conversion from Montgomery domain, a.k.a. Montgomery reduction, ++ * accepts values in [0-m*2^w) range. w is m's bit width rounded up ++ * to limb width. So that at the very least if |I| is fully reduced, ++ * i.e. less than p*q, we can count on from-to round to perform ++ * below modulo operations on |I|. Unlike BN_mod it's constant time. ++ */ ++ if (/* m1 = I moq q */ ++ !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) ++ || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) ++ /* m1 = m1^dmq1 mod q */ ++ || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, ++ rsa->_method_mod_q) ++ /* r1 = I mod p */ ++ || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) ++ || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) ++ /* r1 = r1^dmp1 mod p */ ++ || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, ++ rsa->_method_mod_p) ++ /* r1 = (r1 - m1) mod p */ ++ /* ++ * bn_mod_sub_fixed_top is not regular modular subtraction, ++ * it can tolerate subtrahend to be larger than modulus, but ++ * not bit-wise wider. This makes up for uncommon q>p case, ++ * when |m1| can be larger than |rsa->p|. ++ */ ++ || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) ++ ++ /* r1 = r1 * iqmp mod p */ ++ || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) ++ || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, ++ ctx) ++ /* r0 = r1 * q + m1 */ ++ || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) ++ || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) ++ goto err; ++ ++ goto tail; ++ } ++ + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + c = &local_c; +@@ -909,10 +941,18 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c + if (!BN_add(r0, r1, m1)) + goto err; + ++ tail: + if (rsa->e && rsa->n) { +- if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, +- rsa->_method_mod_n)) +- goto err; ++ if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) { ++ if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, ++ rsa->_method_mod_n)) ++ goto err; ++ } else { ++ bn_correct_top(r0); ++ if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, ++ rsa->_method_mod_n)) ++ goto err; ++ } + /* + * If 'I' was greater than (or equal to) rsa->n, the operation will + * be equivalent to using 'I mod n'. However, the result of the +@@ -921,6 +961,11 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c + */ + if (!BN_sub(vrfy, vrfy, I)) + goto err; ++ if (BN_is_zero(vrfy)) { ++ bn_correct_top(r0); ++ ret = 1; ++ goto err; /* not actually error */ ++ } + if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) + goto err; + if (BN_is_negative(vrfy)) +@@ -946,6 +991,15 @@ static int RSA_eay_mod_exp(BIGNUM *r0, c + goto err; + } + } ++ /* ++ * It's unfortunate that we have to bn_correct_top(r0). What hopefully ++ * saves the day is that correction is highly unlike, and private key ++ * operations are customarily performed on blinded message. Which means ++ * that attacker won't observe correlation with chosen plaintext. ++ * Secondly, remaining code would still handle it in same computational ++ * time and even conceal memory access pattern around corrected top. ++ */ ++ bn_correct_top(r0); + ret = 1; + err: + BN_CTX_end(ctx); +diff -up openssl-1.0.2k/crypto/rsa/rsa_oaep.c.9-lives openssl-1.0.2k/crypto/rsa/rsa_oaep.c +--- openssl-1.0.2k/crypto/rsa/rsa_oaep.c.9-lives 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/rsa/rsa_oaep.c 2019-04-05 10:50:56.138104353 +0200 +@@ -120,8 +120,8 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(un + int plen, const EVP_MD *md, + const EVP_MD *mgf1md) + { +- int i, dblen, mlen = -1, one_index = 0, msg_index; +- unsigned int good, found_one_byte; ++ int i, dblen = 0, mlen = -1, one_index = 0, msg_index; ++ unsigned int good = 0, found_one_byte, mask; + const unsigned char *maskedseed, *maskeddb; + /* + * |em| is the encoded message, zero-padded to exactly |num| bytes: em = +@@ -144,31 +144,42 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(un + * |num| is the length of the modulus; |flen| is the length of the + * encoded message. Therefore, for any |from| that was obtained by + * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, +- * num < 2 * mdlen + 2 must hold for the modulus irrespective of ++ * |num| >= 2 * |mdlen| + 2 must hold for the modulus irrespective of + * the ciphertext, see PKCS #1 v2.2, section 7.1.2. + * This does not leak any side-channel information. + */ +- if (num < flen || num < 2 * mdlen + 2) +- goto decoding_err; ++ if (num < flen || num < 2 * mdlen + 2) { ++ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ++ RSA_R_OAEP_DECODING_ERROR); ++ return -1; ++ } + + dblen = num - mdlen - 1; + db = OPENSSL_malloc(dblen); +- em = OPENSSL_malloc(num); +- if (db == NULL || em == NULL) { ++ if (db == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); + goto cleanup; + } + ++ em = OPENSSL_malloc(num); ++ if (em == NULL) { ++ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ++ ERR_R_MALLOC_FAILURE); ++ goto cleanup; ++ } ++ + /* +- * Always do this zero-padding copy (even when num == flen) to avoid +- * leaking that information. The copy still leaks some side-channel +- * information, but it's impossible to have a fixed memory access +- * pattern since we can't read out of the bounds of |from|. +- * +- * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL. +- */ +- memset(em, 0, num); +- memcpy(em + num - flen, from, flen); ++ * Caller is encouraged to pass zero-padded message created with ++ * BN_bn2binpad. Trouble is that since we can't read out of |from|'s ++ * bounds, it's impossible to have an invariant memory access pattern ++ * in case |from| was not zero-padded in advance. ++ */ ++ for (from += flen, em += num, i = 0; i < num; i++) { ++ mask = ~constant_time_is_zero(flen); ++ flen -= 1 & mask; ++ from -= 1 & mask; ++ *--em = *from & mask; ++ } + + /* + * The first byte must be zero, however we must not leak if this is +@@ -215,33 +226,53 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(un + * so plaintext-awareness ensures timing side-channels are no longer a + * concern. + */ +- if (!good) +- goto decoding_err; +- + msg_index = one_index + 1; + mlen = dblen - msg_index; + +- if (tlen < mlen) { +- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE); +- mlen = -1; +- } else { +- memcpy(to, db + msg_index, mlen); +- goto cleanup; ++ /* ++ * For good measure, do this check in constant time as well. ++ */ ++ good &= constant_time_ge(tlen, mlen); ++ ++ /* ++ * Move the result in-place by |dblen|-|mdlen|-1-|mlen| bytes to the left. ++ * Then if |good| move |mlen| bytes from |db|+|mdlen|+1 to |to|. ++ * Otherwise leave |to| unchanged. ++ * Copy the memory back in a way that does not reveal the size of ++ * the data being copied via a timing side channel. This requires copying ++ * parts of the buffer multiple times based on the bits set in the real ++ * length. Clear bits do a non-copy with identical access pattern. ++ * The loop below has overall complexity of O(N*log(N)). ++ */ ++ tlen = constant_time_select_int(constant_time_lt(dblen - mdlen - 1, tlen), ++ dblen - mdlen - 1, tlen); ++ for (msg_index = 1; msg_index < dblen - mdlen - 1; msg_index <<= 1) { ++ mask = ~constant_time_eq(msg_index & (dblen - mdlen - 1 - mlen), 0); ++ for (i = mdlen + 1; i < dblen - msg_index; i++) ++ db[i] = constant_time_select_8(mask, db[i + msg_index], db[i]); ++ } ++ for (i = 0; i < tlen; i++) { ++ mask = good & constant_time_lt(i, mlen); ++ to[i] = constant_time_select_8(mask, db[i + mdlen + 1], to[i]); + } + +- decoding_err: + /* + * To avoid chosen ciphertext attacks, the error message should not + * reveal which kind of decoding error happened. + */ + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, + RSA_R_OAEP_DECODING_ERROR); ++ err_clear_last_constant_time(1 & good); + cleanup: ++ OPENSSL_cleanse(seed, sizeof(seed)); + if (db != NULL) +- OPENSSL_free(db); ++ OPENSSL_cleanse(db, dblen); ++ OPENSSL_free(db); + if (em != NULL) +- OPENSSL_free(em); +- return mlen; ++ OPENSSL_cleanse(em, num); ++ OPENSSL_free(em); ++ ++ return constant_time_select_int(good, mlen, -1); + } + + int PKCS1_MGF1(unsigned char *mask, long len, +diff -up openssl-1.0.2k/crypto/rsa/rsa_pk1.c.9-lives openssl-1.0.2k/crypto/rsa/rsa_pk1.c +--- openssl-1.0.2k/crypto/rsa/rsa_pk1.c.9-lives 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/rsa/rsa_pk1.c 2019-04-05 10:50:56.139104335 +0200 +@@ -98,6 +98,27 @@ int RSA_padding_check_PKCS1_type_1(unsig + const unsigned char *p; + + p = from; ++ ++ /* ++ * The format is ++ * 00 || 01 || PS || 00 || D ++ * PS - padding string, at least 8 bytes of FF ++ * D - data. ++ */ ++ ++ if (num < 11) ++ return -1; ++ ++ /* Accept inputs with and without the leading 0-byte. */ ++ if (num == flen) { ++ if ((*p++) != 0x00) { ++ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, ++ RSA_R_INVALID_PADDING); ++ return -1; ++ } ++ flen--; ++ } ++ + if ((num != (flen + 1)) || (*(p++) != 01)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BLOCK_TYPE_IS_NOT_01); +@@ -186,7 +207,7 @@ int RSA_padding_check_PKCS1_type_2(unsig + int i; + /* |em| is the encoded message, zero-padded to exactly |num| bytes */ + unsigned char *em = NULL; +- unsigned int good, found_zero_byte; ++ unsigned int good, found_zero_byte, mask; + int zero_index = 0, msg_index, mlen = -1; + + if (tlen < 0 || flen < 0) +@@ -197,37 +218,40 @@ int RSA_padding_check_PKCS1_type_2(unsig + * section 7.2.2. + */ + +- if (flen > num) +- goto err; +- +- if (num < 11) +- goto err; ++ if (flen > num || num < 11) { ++ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ++ RSA_R_PKCS_DECODING_ERROR); ++ return -1; ++ } + + em = OPENSSL_malloc(num); + if (em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); + return -1; + } +- memset(em, 0, num); + /* +- * Always do this zero-padding copy (even when num == flen) to avoid +- * leaking that information. The copy still leaks some side-channel +- * information, but it's impossible to have a fixed memory access +- * pattern since we can't read out of the bounds of |from|. +- * +- * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL. +- */ +- memcpy(em + num - flen, from, flen); ++ * Caller is encouraged to pass zero-padded message created with ++ * BN_bn2binpad. Trouble is that since we can't read out of |from|'s ++ * bounds, it's impossible to have an invariant memory access pattern ++ * in case |from| was not zero-padded in advance. ++ */ ++ for (from += flen, em += num, i = 0; i < num; i++) { ++ mask = ~constant_time_is_zero(flen); ++ flen -= 1 & mask; ++ from -= 1 & mask; ++ *--em = *from & mask; ++ } + + good = constant_time_is_zero(em[0]); + good &= constant_time_eq(em[1], 2); + ++ /* scan over padding data */ + found_zero_byte = 0; + for (i = 2; i < num; i++) { + unsigned int equals0 = constant_time_is_zero(em[i]); +- zero_index = +- constant_time_select_int(~found_zero_byte & equals0, i, +- zero_index); ++ ++ zero_index = constant_time_select_int(~found_zero_byte & equals0, ++ i, zero_index); + found_zero_byte |= equals0; + } + +@@ -236,7 +260,7 @@ int RSA_padding_check_PKCS1_type_2(unsig + * If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ +- good &= constant_time_ge((unsigned int)(zero_index), 2 + 8); ++ good &= constant_time_ge(zero_index, 2 + 8); + + /* + * Skip the zero byte. This is incorrect if we never found a zero-byte +@@ -246,30 +270,36 @@ int RSA_padding_check_PKCS1_type_2(unsig + mlen = num - msg_index; + + /* +- * For good measure, do this check in constant time as well; it could +- * leak something if |tlen| was assuming valid padding. ++ * For good measure, do this check in constant time as well. + */ +- good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen)); ++ good &= constant_time_ge(tlen, mlen); + + /* +- * We can't continue in constant-time because we need to copy the result +- * and we cannot fake its length. This unavoidably leaks timing +- * information at the API boundary. +- * TODO(emilia): this could be addressed at the call site, +- * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. +- */ +- if (!good) { +- mlen = -1; +- goto err; +- } ++ * Move the result in-place by |num|-11-|mlen| bytes to the left. ++ * Then if |good| move |mlen| bytes from |em|+11 to |to|. ++ * Otherwise leave |to| unchanged. ++ * Copy the memory back in a way that does not reveal the size of ++ * the data being copied via a timing side channel. This requires copying ++ * parts of the buffer multiple times based on the bits set in the real ++ * length. Clear bits do a non-copy with identical access pattern. ++ * The loop below has overall complexity of O(N*log(N)). ++ */ ++ tlen = constant_time_select_int(constant_time_lt(num - 11, tlen), ++ num - 11, tlen); ++ for (msg_index = 1; msg_index < num - 11; msg_index <<= 1) { ++ mask = ~constant_time_eq(msg_index & (num - 11 - mlen), 0); ++ for (i = 11; i < num - msg_index; i++) ++ em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]); ++ } ++ for (i = 0; i < tlen; i++) { ++ mask = good & constant_time_lt(i, mlen); ++ to[i] = constant_time_select_8(mask, em[i + 11], to[i]); ++ } ++ ++ OPENSSL_cleanse(em, num); ++ OPENSSL_free(em); ++ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); ++ err_clear_last_constant_time(1 & good); + +- memcpy(to, em + msg_index, mlen); +- +- err: +- if (em != NULL) +- OPENSSL_free(em); +- if (mlen == -1) +- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, +- RSA_R_PKCS_DECODING_ERROR); +- return mlen; ++ return constant_time_select_int(good, mlen, -1); + } +diff -up openssl-1.0.2k/crypto/rsa/rsa_ssl.c.9-lives openssl-1.0.2k/crypto/rsa/rsa_ssl.c +--- openssl-1.0.2k/crypto/rsa/rsa_ssl.c.9-lives 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/crypto/rsa/rsa_ssl.c 2019-04-05 10:50:56.139104335 +0200 +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include "constant_time_locl.h" + + int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen) +@@ -101,49 +102,119 @@ int RSA_padding_add_SSLv23(unsigned char + return (1); + } + ++/* ++ * Copy of RSA_padding_check_PKCS1_type_2 with a twist that rejects padding ++ * if nul delimiter is not preceded by 8 consecutive 0x03 bytes. It also ++ * preserves error code reporting for backward compatibility. ++ */ + int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) + { +- int i, j, k; +- const unsigned char *p; ++ int i; ++ /* |em| is the encoded message, zero-padded to exactly |num| bytes */ ++ unsigned char *em = NULL; ++ unsigned int good, found_zero_byte, mask, threes_in_row; ++ int zero_index = 0, msg_index, mlen = -1, err; + +- p = from; +- if (flen < 10) { ++ if (tlen <= 0 || flen <= 0) ++ return -1; ++ ++ if (flen > num || num < 11) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); + return (-1); + } +- if ((num != (flen + 1)) || (*(p++) != 02)) { +- RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02); +- return (-1); +- } + +- /* scan over padding data */ +- j = flen - 1; /* one for type */ +- for (i = 0; i < j; i++) +- if (*(p++) == 0) +- break; +- +- if ((i == j) || (i < 8)) { +- RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, +- RSA_R_NULL_BEFORE_BLOCK_MISSING); +- return (-1); +- } +- for (k = -9; k < -1; k++) { +- if (p[k] != 0x03) +- break; +- } +- if (k == -1) { +- RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK); +- return (-1); +- } ++ em = OPENSSL_malloc(num); ++ if (em == NULL) { ++ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, ERR_R_MALLOC_FAILURE); ++ return -1; ++ } ++ /* ++ * Caller is encouraged to pass zero-padded message created with ++ * BN_bn2binpad. Trouble is that since we can't read out of |from|'s ++ * bounds, it's impossible to have an invariant memory access pattern ++ * in case |from| was not zero-padded in advance. ++ */ ++ for (from += flen, em += num, i = 0; i < num; i++) { ++ mask = ~constant_time_is_zero(flen); ++ flen -= 1 & mask; ++ from -= 1 & mask; ++ *--em = *from & mask; ++ } ++ ++ good = constant_time_is_zero(em[0]); ++ good &= constant_time_eq(em[1], 2); ++ err = constant_time_select_int(good, 0, RSA_R_BLOCK_TYPE_IS_NOT_02); ++ mask = ~good; + +- i++; /* Skip over the '\0' */ +- j -= i; +- if (j > tlen) { +- RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE); +- return (-1); +- } +- memcpy(to, p, (unsigned int)j); ++ /* scan over padding data */ ++ found_zero_byte = 0; ++ threes_in_row = 0; ++ for (i = 2; i < num; i++) { ++ unsigned int equals0 = constant_time_is_zero(em[i]); ++ ++ zero_index = constant_time_select_int(~found_zero_byte & equals0, ++ i, zero_index); ++ found_zero_byte |= equals0; ++ ++ threes_in_row += 1 & ~found_zero_byte; ++ threes_in_row &= found_zero_byte | constant_time_eq(em[i], 3); ++ } ++ ++ /* ++ * PS must be at least 8 bytes long, and it starts two bytes into |em|. ++ * If we never found a 0-byte, then |zero_index| is 0 and the check ++ * also fails. ++ */ ++ good &= constant_time_ge(zero_index, 2 + 8); ++ err = constant_time_select_int(mask | good, err, ++ RSA_R_NULL_BEFORE_BLOCK_MISSING); ++ mask = ~good; ++ ++ good &= constant_time_ge(threes_in_row, 8); ++ err = constant_time_select_int(mask | good, err, ++ RSA_R_SSLV3_ROLLBACK_ATTACK); ++ mask = ~good; ++ ++ /* ++ * Skip the zero byte. This is incorrect if we never found a zero-byte ++ * but in this case we also do not copy the message out. ++ */ ++ msg_index = zero_index + 1; ++ mlen = num - msg_index; ++ ++ /* ++ * For good measure, do this check in constant time as well. ++ */ ++ good &= constant_time_ge(tlen, mlen); ++ err = constant_time_select_int(mask | good, err, RSA_R_DATA_TOO_LARGE); ++ ++ /* ++ * Move the result in-place by |num|-11-|mlen| bytes to the left. ++ * Then if |good| move |mlen| bytes from |em|+11 to |to|. ++ * Otherwise leave |to| unchanged. ++ * Copy the memory back in a way that does not reveal the size of ++ * the data being copied via a timing side channel. This requires copying ++ * parts of the buffer multiple times based on the bits set in the real ++ * length. Clear bits do a non-copy with identical access pattern. ++ * The loop below has overall complexity of O(N*log(N)). ++ */ ++ tlen = constant_time_select_int(constant_time_lt(num - 11, tlen), ++ num - 11, tlen); ++ for (msg_index = 1; msg_index < num - 11; msg_index <<= 1) { ++ mask = ~constant_time_eq(msg_index & (num - 11 - mlen), 0); ++ for (i = 11; i < num - msg_index; i++) ++ em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]); ++ } ++ for (i = 0; i < tlen; i++) { ++ mask = good & constant_time_lt(i, mlen); ++ to[i] = constant_time_select_8(mask, em[i + 11], to[i]); ++ } ++ ++ OPENSSL_cleanse(em, num); ++ OPENSSL_free(em); ++ RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, err); ++ err_clear_last_constant_time(1 & good); + +- return (j); ++ return constant_time_select_int(good, mlen, -1); + } +diff -up openssl-1.0.2k/doc/crypto/RSA_padding_add_PKCS1_type_1.pod.9-lives openssl-1.0.2k/doc/crypto/RSA_padding_add_PKCS1_type_1.pod +--- openssl-1.0.2k/doc/crypto/RSA_padding_add_PKCS1_type_1.pod.9-lives 2017-01-26 14:22:04.000000000 +0100 ++++ openssl-1.0.2k/doc/crypto/RSA_padding_add_PKCS1_type_1.pod 2019-04-05 10:50:56.139104335 +0200 +@@ -104,6 +104,18 @@ The RSA_padding_check_xxx() functions re + recovered data, -1 on error. Error codes can be obtained by calling + L. + ++=head1 WARNING ++ ++The RSA_padding_check_PKCS1_type_2() padding check leaks timing ++information which can potentially be used to mount a Bleichenbacher ++padding oracle attack. This is an inherent weakness in the PKCS #1 ++v1.5 padding design. Prefer PKCS1_OAEP padding. Otherwise it can ++be recommended to pass zero-padded B, so that B equals to ++B, and if fixed by protocol, B being set to the ++expected length. In such case leakage would be minimal, it would ++take attacker's ability to observe memory access pattern with byte ++granilarity as it occurs, post-factum timing analysis won't do. ++ + =head1 SEE ALSO + + L, diff --git a/SOURCES/openssl-1.0.2k-fix-one-and-done.patch b/SOURCES/openssl-1.0.2k-fix-one-and-done.patch new file mode 100644 index 0000000..dc66cb2 --- /dev/null +++ b/SOURCES/openssl-1.0.2k-fix-one-and-done.patch @@ -0,0 +1,167 @@ +diff -up openssl-1.0.2k/crypto/bn/bn_exp.c.one-and-done openssl-1.0.2k/crypto/bn/bn_exp.c +--- openssl-1.0.2k/crypto/bn/bn_exp.c.one-and-done 2019-04-04 16:46:21.287257363 +0200 ++++ openssl-1.0.2k/crypto/bn/bn_exp.c 2019-04-04 16:45:32.875130057 +0200 +@@ -579,7 +579,6 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI + return (ret); + } + +-#if defined(SPARC_T4_MONT) + static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos) + { + BN_ULONG ret = 0; +@@ -598,7 +597,6 @@ static BN_ULONG bn_get_bits(const BIGNUM + + return ret & BN_MASK2; + } +-#endif + + /* + * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific +@@ -697,7 +695,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont) + { +- int i, bits, ret = 0, window, wvalue; ++ int i, bits, ret = 0, window, wvalue, wmask, window0; + int top; + BN_MONT_CTX *mont = NULL; + +@@ -945,20 +943,27 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + top /= 2; + bn_flip_t4(np, mont->N.d, top); + +- bits--; +- for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) +- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); ++ /* ++ * The exponent may not have a whole number of fixed-size windows. ++ * To simplify the main loop, the initial window has between 1 and ++ * full-window-size bits such that what remains is always a whole ++ * number of windows ++ */ ++ window0 = (bits - 1) % 5 + 1; ++ wmask = (1 << window0) - 1; ++ bits -= window0; ++ wvalue = bn_get_bits(p, bits) & wmask; + bn_gather5_t4(tmp.d, top, powerbuf, wvalue); + + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ +- while (bits >= 0) { ++ while (bits > 0) { + if (bits < stride) +- stride = bits + 1; ++ stride = bits; + bits -= stride; +- wvalue = bn_get_bits(p, bits + 1); ++ wvalue = bn_get_bits(p, bits); + + if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride)) + continue; +@@ -1066,32 +1071,36 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + bn_scatter5(tmp.d, top, powerbuf, i); + } + # endif +- bits--; +- for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) +- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); ++ /* ++ * The exponent may not have a whole number of fixed-size windows. ++ * To simplify the main loop, the initial window has between 1 and ++ * full-window-size bits such that what remains is always a whole ++ * number of windows ++ */ ++ window0 = (bits - 1) % 5 + 1; ++ wmask = (1 << window0) - 1; ++ bits -= window0; ++ wvalue = bn_get_bits(p, bits) & wmask; + bn_gather5(tmp.d, top, powerbuf, wvalue); + + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ +- if (top & 7) +- while (bits >= 0) { +- for (wvalue = 0, i = 0; i < 5; i++, bits--) +- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); +- ++ if (top & 7) { ++ while (bits > 0) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, +- wvalue); ++ bn_get_bits5(p->d, bits -= 5)); ++ } + } else { +- while (bits >= 0) { +- wvalue = bn_get_bits5(p->d, bits - 4); +- bits -= 5; +- bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); ++ while (bits > 0) { ++ bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, ++ bn_get_bits5(p->d, bits -= 5)); + } + } + +@@ -1133,28 +1142,45 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + } + } + +- bits--; +- for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) +- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); ++ /* ++ * The exponent may not have a whole number of fixed-size windows. ++ * To simplify the main loop, the initial window has between 1 and ++ * full-window-size bits such that what remains is always a whole ++ * number of windows ++ */ ++ window0 = (bits - 1) % window + 1; ++ wmask = (1 << window0) - 1; ++ bits -= window0; ++ wvalue = bn_get_bits(p, bits) & wmask; + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue, + window)) + goto err; + ++ wmask = (1 << window) - 1; + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ +- while (bits >= 0) { +- wvalue = 0; /* The 'value' of the window */ ++ while (bits > 0) { + +- /* Scan the window, squaring the result as we go */ +- for (i = 0; i < window; i++, bits--) { ++ /* Square the result window-size times */ ++ for (i = 0; i < window; i++) + if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx)) + goto err; +- wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); +- } + + /* ++ * Get a window's worth of bits from the exponent ++ * This avoids calling BN_is_bit_set for each bit, which ++ * is not only slower but also makes each bit vulnerable to ++ * EM (and likely other) side-channel attacks like One&Done ++ * (for details see "One&Done: A Single-Decryption EM-Based ++ * Attack on OpenSSL's Constant-Time Blinded RSA" by M. Alam, ++ * H. Khan, M. Dey, N. Sinha, R. Callan, A. Zajic, and ++ * M. Prvulovic, in USENIX Security'18) ++ */ ++ bits -= window; ++ wvalue = bn_get_bits(p, bits) & wmask; ++ /* + * Fetch the appropriate pre-computed value from the pre-buf + */ + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, diff --git a/SOURCES/openssl-1.0.2k-long-hello.patch b/SOURCES/openssl-1.0.2k-long-hello.patch new file mode 100644 index 0000000..358b027 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-name-sensitive.patch b/SOURCES/openssl-1.0.2k-name-sensitive.patch new file mode 100644 index 0000000..909ce30 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-no-ssl2.patch b/SOURCES/openssl-1.0.2k-no-ssl2.patch new file mode 100644 index 0000000..c668417 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-ppc-update.patch b/SOURCES/openssl-1.0.2k-ppc-update.patch new file mode 100644 index 0000000..a5efdfa --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-req-x509.patch b/SOURCES/openssl-1.0.2k-req-x509.patch new file mode 100644 index 0000000..0be9167 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-rsa-check.patch b/SOURCES/openssl-1.0.2k-rsa-check.patch new file mode 100644 index 0000000..a7ccd9c --- /dev/null +++ b/SOURCES/openssl-1.0.2k-rsa-check.patch @@ -0,0 +1,18 @@ +diff -up openssl-1.0.2k/crypto/rsa/rsa_gen.c.rsa-check openssl-1.0.2k/crypto/rsa/rsa_gen.c +--- openssl-1.0.2k/crypto/rsa/rsa_gen.c.rsa-check 2019-02-06 12:58:50.570844207 +0100 ++++ openssl-1.0.2k/crypto/rsa/rsa_gen.c 2019-02-06 13:10:57.058468214 +0100 +@@ -94,11 +94,11 @@ int fips_check_rsa(RSA *rsa) + + /* Perform pairwise consistency signature test */ + if (!fips_pkey_signature_test(pk, tbs, -1, +- NULL, 0, EVP_sha1(), ++ NULL, 0, EVP_sha256(), + EVP_MD_CTX_FLAG_PAD_PKCS1, NULL) +- || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(), ++ || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha256(), + EVP_MD_CTX_FLAG_PAD_X931, NULL) +- || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha1(), ++ || !fips_pkey_signature_test(pk, tbs, -1, NULL, 0, EVP_sha256(), + EVP_MD_CTX_FLAG_PAD_PSS, NULL)) + goto err; + /* Now perform pairwise consistency encrypt/decrypt test */ diff --git a/SOURCES/openssl-1.0.2k-s390x-update.patch b/SOURCES/openssl-1.0.2k-s390x-update.patch new file mode 100644 index 0000000..8712de5 --- /dev/null +++ b/SOURCES/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/SOURCES/openssl-1.0.2k-starttls.patch b/SOURCES/openssl-1.0.2k-starttls.patch new file mode 100644 index 0000000..da987f8 --- /dev/null +++ b/SOURCES/openssl-1.0.2k-starttls.patch @@ -0,0 +1,604 @@ +diff -up openssl-1.0.2k/apps/apps.c.starttls openssl-1.0.2k/apps/apps.c +--- openssl-1.0.2k/apps/apps.c.starttls 2017-01-26 14:22:03.000000000 +0100 ++++ openssl-1.0.2k/apps/apps.c 2017-03-09 17:35:35.519765927 +0100 +@@ -3277,3 +3277,11 @@ int raw_write_stdout(const void *buf, in + return write(fileno_stdout(), buf, siz); + } + #endif ++ ++void make_uppercase(char *string) ++{ ++ int i; ++ ++ for (i = 0; string[i] != '\0'; i++) ++ string[i] = toupper((unsigned char)string[i]); ++} +diff -up openssl-1.0.2k/apps/apps.h.starttls openssl-1.0.2k/apps/apps.h +--- openssl-1.0.2k/apps/apps.h.starttls 2017-03-09 17:35:28.632604234 +0100 ++++ openssl-1.0.2k/apps/apps.h 2017-03-09 17:35:35.520765950 +0100 +@@ -384,6 +384,8 @@ int raw_write_stdout(const void *, int); + # define TM_STOP 1 + double app_tminterval(int stop, int usertime); + ++void make_uppercase(char *string); ++ + # define OPENSSL_NO_SSL_INTERN + + #endif +diff -up openssl-1.0.2k/apps/s_client.c.starttls openssl-1.0.2k/apps/s_client.c +--- openssl-1.0.2k/apps/s_client.c.starttls 2017-03-09 17:35:28.684605455 +0100 ++++ openssl-1.0.2k/apps/s_client.c 2017-03-09 17:52:59.153207946 +0100 +@@ -134,7 +134,8 @@ + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ +- ++/* for strcasestr */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -202,6 +203,7 @@ static char *krb5svc = NULL; + + #undef BUFSIZZ + #define BUFSIZZ 1024*8 ++#define S_CLIENT_IRC_READ_TIMEOUT 8 + + extern int verify_depth; + extern int verify_error; +@@ -228,6 +230,7 @@ static void print_stuff(BIO *berr, SSL * + #ifndef OPENSSL_NO_TLSEXT + static int ocsp_resp_cb(SSL *s, void *arg); + #endif ++static int ldap_ExtendedResponse_parse(const char *buf, long rem); + static BIO *bio_c_out = NULL; + static BIO *bio_c_msg = NULL; + static int c_quiet = 0; +@@ -402,8 +405,14 @@ static void sc_usage(void) + BIO_printf(bio_err, + " 'prot' defines which one to assume. Currently,\n"); + BIO_printf(bio_err, +- " only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n"); +- BIO_printf(bio_err, " are supported.\n"); ++ " only \"smtp\", \"pop3\", \"imap\", \"ftp\", \"xmpp\",\n"); ++ BIO_printf(bio_err, ++ " \"xmpp-server\", \"irc\", \"postgres\", \"lmtp\", \"nntp\",\n"); ++ BIO_printf(bio_err, " \"sieve\" and \"ldap\" are supported.\n"); ++ BIO_printf(bio_err, ++ " -xmpphost host - Host to use with \"-starttls xmpp[-server]\"\n"); ++ BIO_printf(bio_err, ++ " -name host - Hostname to use for \"-starttls lmtp\" or \"-starttls smtp\"\n"); + #ifndef OPENSSL_NO_KRB5 + BIO_printf(bio_err, " -krb5svc arg - Kerberos service name\n"); + #endif +@@ -657,7 +666,15 @@ enum { + PROTO_POP3, + PROTO_IMAP, + PROTO_FTP, +- PROTO_XMPP ++ PROTO_TELNET, ++ PROTO_XMPP, ++ PROTO_XMPP_SERVER, ++ PROTO_IRC, ++ PROTO_POSTGRES, ++ PROTO_LMTP, ++ PROTO_NNTP, ++ PROTO_SIEVE, ++ PROTO_LDAP + }; + + int MAIN(int, char **); +@@ -726,6 +743,8 @@ int MAIN(int argc, char **argv) + #endif + char *sess_in = NULL; + char *sess_out = NULL; ++ char *xmpphost = NULL; ++ const char *ehlo = "openssl.client.net"; + struct sockaddr peer; + int peerlen = sizeof(peer); + int fallback_scsv = 0; +@@ -1097,8 +1116,32 @@ int MAIN(int argc, char **argv) + starttls_proto = PROTO_FTP; + else if (strcmp(*argv, "xmpp") == 0) + starttls_proto = PROTO_XMPP; ++ else if (strcmp(*argv, "xmpp-server") == 0) ++ starttls_proto = PROTO_XMPP_SERVER; ++ else if (strcmp(*argv, "telnet") == 0) ++ starttls_proto = PROTO_TELNET; ++ else if (strcmp(*argv, "irc") == 0) ++ starttls_proto = PROTO_IRC; ++ else if (strcmp(*argv, "postgres") == 0) ++ starttls_proto = PROTO_POSTGRES; ++ else if (strcmp(*argv, "lmtp") == 0) ++ starttls_proto = PROTO_LMTP; ++ else if (strcmp(*argv, "nntp") == 0) ++ starttls_proto = PROTO_NNTP; ++ else if (strcmp(*argv, "sieve") == 0) ++ starttls_proto = PROTO_SIEVE; ++ else if (strcmp(*argv, "ldap") == 0) ++ starttls_proto = PROTO_LDAP; + else + goto bad; ++ } else if (strcmp(*argv, "-xmpphost") == 0) { ++ if (--argc < 1) ++ goto bad; ++ xmpphost = *(++argv); ++ } else if (strcmp(*argv, "-name") == 0) { ++ if (--argc < 1) ++ goto bad; ++ ehlo = *(++argv); + } + #ifndef OPENSSL_NO_ENGINE + else if (strcmp(*argv, "-engine") == 0) { +@@ -1599,19 +1642,24 @@ int MAIN(int argc, char **argv) + * BIO into the chain that is removed again later on to not disturb the + * rest of the s_client operation. + */ +- if (starttls_proto == PROTO_SMTP) { ++ if (starttls_proto == PROTO_SMTP || starttls_proto == PROTO_LMTP) { + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); + BIO_push(fbio, sbio); +- /* wait for multi-line response to end from SMTP */ ++ /* Wait for multi-line response to end from LMTP or SMTP */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } + while (mbuf_len > 3 && mbuf[3] == '-'); +- /* STARTTLS command requires EHLO... */ +- BIO_printf(fbio, "EHLO openssl.client.net\r\n"); ++ if (starttls_proto == PROTO_LMTP) ++ BIO_printf(fbio, "LHLO %s\r\n", ehlo); ++ else ++ BIO_printf(fbio, "EHLO %s\r\n", ehlo); + (void)BIO_flush(fbio); +- /* wait for multi-line response to end EHLO SMTP response */ ++ /* ++ * Wait for multi-line response to end LHLO LMTP or EHLO SMTP ++ * response. ++ */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (strstr(mbuf, "STARTTLS")) +@@ -1630,10 +1678,15 @@ int MAIN(int argc, char **argv) + } else if (starttls_proto == PROTO_POP3) { + BIO_read(sbio, mbuf, BUFSIZZ); + BIO_printf(sbio, "STLS\r\n"); +- BIO_read(sbio, sbuf, BUFSIZZ); ++ mbuf_len = BIO_read(sbio, sbuf, BUFSIZZ); ++ if (mbuf_len < 0) { ++ BIO_printf(bio_err, "BIO_read failed\n"); ++ goto end; ++ } + } else if (starttls_proto == PROTO_IMAP) { + int foundit = 0; + BIO *fbio = BIO_new(BIO_f_buffer()); ++ + BIO_push(fbio, sbio); + BIO_gets(fbio, mbuf, BUFSIZZ); + /* STARTTLS command requires CAPABILITY... */ +@@ -1669,27 +1722,287 @@ int MAIN(int argc, char **argv) + BIO_printf(sbio, "AUTH TLS\r\n"); + BIO_read(sbio, sbuf, BUFSIZZ); + } +- if (starttls_proto == PROTO_XMPP) { ++ else if (starttls_proto == PROTO_XMPP || starttls_proto == PROTO_XMPP_SERVER) { + int seen = 0; + BIO_printf(sbio, "", host); ++ "xmlns='jabber:%s' to='%s' version='1.0'>", ++ starttls_proto == PROTO_XMPP ? "client" : "server", ++ xmpphost ? xmpphost : host); + seen = BIO_read(sbio, mbuf, BUFSIZZ); ++ if (seen < 0) { ++ BIO_printf(bio_err, "BIO_read failed\n"); ++ goto end; ++ } + mbuf[seen] = 0; +- while (!strstr +- (mbuf, "")) +- goto shut; ++ while (!strcasestr ++ (mbuf, ""); + seen = BIO_read(sbio, sbuf, BUFSIZZ); ++ if (seen < 0) { ++ BIO_printf(bio_err, "BIO_read failed\n"); ++ goto shut; ++ } + sbuf[seen] = 0; + if (!strstr(sbuf, " 1 && mbuf[0] != '.'); ++ (void)BIO_flush(fbio); ++ BIO_pop(fbio); ++ BIO_free(fbio); ++ if (!foundit) ++ BIO_printf(bio_err, ++ "Didn't find STARTTLS in server response," ++ " trying anyway...\n"); ++ BIO_printf(sbio, "STARTTLS\r\n"); ++ mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); ++ if (mbuf_len < 0) { ++ BIO_printf(bio_err, "BIO_read failed\n"); ++ goto end; ++ } ++ mbuf[mbuf_len] = '\0'; ++ if (strstr(mbuf, "382") == NULL) { ++ BIO_printf(bio_err, "STARTTLS failed: %s", mbuf); ++ goto shut; ++ } ++ } else if (starttls_proto == PROTO_SIEVE) { ++ int foundit = 0; ++ BIO *fbio = BIO_new(BIO_f_buffer()); ++ ++ BIO_push(fbio, sbio); ++ /* wait for multi-line response to end from Sieve */ ++ do { ++ mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); ++ /* ++ * According to RFC 5804 § 1.7, capability ++ * is case-insensitive, make it uppercase ++ */ ++ if (mbuf_len > 1 && mbuf[0] == '"') { ++ make_uppercase(mbuf); ++ if (strncmp(mbuf, "\"STARTTLS\"", 10) == 0) ++ foundit = 1; ++ } ++ } while (mbuf_len > 1 && mbuf[0] == '"'); ++ (void)BIO_flush(fbio); ++ BIO_pop(fbio); ++ BIO_free(fbio); ++ if (!foundit) ++ BIO_printf(bio_err, ++ "Didn't find STARTTLS in server response," ++ " trying anyway...\n"); ++ BIO_printf(sbio, "STARTTLS\r\n"); ++ mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); ++ if (mbuf_len < 0) { ++ BIO_printf(bio_err, "BIO_read failed\n"); ++ goto end; ++ } ++ mbuf[mbuf_len] = '\0'; ++ if (mbuf_len < 2) { ++ BIO_printf(bio_err, "STARTTLS failed: %s", mbuf); ++ goto shut; ++ } ++ /* ++ * According to RFC 5804 § 2.2, response codes are case- ++ * insensitive, make it uppercase but preserve the response. ++ */ ++ strncpy(sbuf, mbuf, 2); ++ make_uppercase(sbuf); ++ if (strncmp(sbuf, "OK", 2) != 0) { ++ BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf); ++ goto shut; ++ } ++ } else if (starttls_proto == PROTO_LDAP) { ++ /* StartTLS Operation according to RFC 4511 */ ++ static char ldap_tls_genconf[] = "asn1=SEQUENCE:LDAPMessage\n" ++ "[LDAPMessage]\n" ++ "messageID=INTEGER:1\n" ++ "extendedReq=EXPLICIT:23A,IMPLICIT:0C," ++ "FORMAT:ASCII,OCT:1.3.6.1.4.1.1466.20037\n"; ++ long errline = -1; ++ char *genstr = NULL; ++ int result = -1; ++ ASN1_TYPE *atyp = NULL; ++ BIO *ldapbio = BIO_new(BIO_s_mem()); ++ CONF *cnf = NCONF_new(NULL); ++ ++ if (cnf == NULL) { ++ BIO_free(ldapbio); ++ goto end; ++ } ++ BIO_puts(ldapbio, ldap_tls_genconf); ++ if (NCONF_load_bio(cnf, ldapbio, &errline) <= 0) { ++ BIO_free(ldapbio); ++ NCONF_free(cnf); ++ if (errline <= 0) { ++ BIO_printf(bio_err, "NCONF_load_bio failed\n"); ++ goto end; ++ } else { ++ BIO_printf(bio_err, "Error on line %ld\n", errline); ++ goto end; ++ } ++ } ++ BIO_free(ldapbio); ++ genstr = NCONF_get_string(cnf, "default", "asn1"); ++ if (genstr == NULL) { ++ NCONF_free(cnf); ++ BIO_printf(bio_err, "NCONF_get_string failed\n"); ++ goto end; ++ } ++ atyp = ASN1_generate_nconf(genstr, cnf); ++ if (atyp == NULL) { ++ NCONF_free(cnf); ++ BIO_printf(bio_err, "ASN1_generate_nconf failed\n"); ++ goto end; ++ } ++ NCONF_free(cnf); ++ /* Send SSLRequest packet */ ++ BIO_write(sbio, atyp->value.sequence->data, ++ atyp->value.sequence->length); ++ (void)BIO_flush(sbio); ++ ASN1_TYPE_free(atyp); ++ ++ mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); ++ if (mbuf_len < 0) { ++ BIO_printf(bio_err, "BIO_read failed\n"); ++ goto end; ++ } ++ result = ldap_ExtendedResponse_parse(mbuf, mbuf_len); ++ if (result < 0) { ++ BIO_printf(bio_err, "ldap_ExtendedResponse_parse failed\n"); ++ goto shut; ++ } else if (result > 0) { ++ BIO_printf(bio_err, "STARTTLS failed, LDAP Result Code: %i\n", ++ result); ++ goto shut; ++ } ++ mbuf_len = 0; + } + + for (;;) { +@@ -1738,7 +2051,7 @@ int MAIN(int argc, char **argv) + full_log--; + + if (starttls_proto) { +- BIO_printf(bio_err, "%s", mbuf); ++ BIO_write(bio_err, mbuf, mbuf_len); + /* We don't need to know any more */ + starttls_proto = PROTO_OFF; + } +@@ -2372,3 +2685,87 @@ static int ocsp_resp_cb(SSL *s, void *ar + } + + #endif ++ ++static int ldap_ExtendedResponse_parse(const char *buf, long rem) ++{ ++ const unsigned char *cur, *end; ++ long len; ++ int tag, xclass, inf, ret = -1; ++ ++ cur = (const unsigned char *)buf; ++ end = cur + rem; ++ ++ /* ++ * From RFC 4511: ++ * ++ * LDAPMessage ::= SEQUENCE { ++ * messageID MessageID, ++ * protocolOp CHOICE { ++ * ... ++ * extendedResp ExtendedResponse, ++ * ... }, ++ * controls [0] Controls OPTIONAL } ++ * ++ * ExtendedResponse ::= [APPLICATION 24] SEQUENCE { ++ * COMPONENTS OF LDAPResult, ++ * responseName [10] LDAPOID OPTIONAL, ++ * responseValue [11] OCTET STRING OPTIONAL } ++ * ++ * LDAPResult ::= SEQUENCE { ++ * resultCode ENUMERATED { ++ * success (0), ++ * ... ++ * other (80), ++ * ... }, ++ * matchedDN LDAPDN, ++ * diagnosticMessage LDAPString, ++ * referral [3] Referral OPTIONAL } ++ */ ++ ++ /* pull SEQUENCE */ ++ inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem); ++ if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE || ++ (rem = end - cur, len > rem)) { ++ BIO_printf(bio_err, "Unexpected LDAP response\n"); ++ goto end; ++ } ++ ++ rem = len; /* ensure that we don't overstep the SEQUENCE */ ++ ++ /* pull MessageID */ ++ inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem); ++ if (inf != V_ASN1_UNIVERSAL || tag != V_ASN1_INTEGER || ++ (rem = end - cur, len > rem)) { ++ BIO_printf(bio_err, "No MessageID\n"); ++ goto end; ++ } ++ ++ cur += len; /* shall we check for MessageId match or just skip? */ ++ ++ /* pull [APPLICATION 24] */ ++ rem = end - cur; ++ inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem); ++ if (inf != V_ASN1_CONSTRUCTED || xclass != V_ASN1_APPLICATION || ++ tag != 24) { ++ BIO_printf(bio_err, "Not ExtendedResponse\n"); ++ goto end; ++ } ++ ++ /* pull resultCode */ ++ rem = end - cur; ++ inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem); ++ if (inf != V_ASN1_UNIVERSAL || tag != V_ASN1_ENUMERATED || len == 0 || ++ (rem = end - cur, len > rem)) { ++ BIO_printf(bio_err, "Not LDAPResult\n"); ++ goto end; ++ } ++ ++ /* len should always be one, but just in case... */ ++ for (ret = 0, inf = 0; inf < len; inf++) { ++ ret <<= 8; ++ ret |= cur[inf]; ++ } ++ /* There is more data, but we don't care... */ ++ end: ++ return ret; ++} +diff -up openssl-1.0.2k/doc/apps/s_client.pod.starttls openssl-1.0.2k/doc/apps/s_client.pod +--- openssl-1.0.2k/doc/apps/s_client.pod.starttls 2017-03-09 17:35:28.684605455 +0100 ++++ openssl-1.0.2k/doc/apps/s_client.pod 2017-03-09 17:42:54.455070967 +0100 +@@ -46,6 +46,8 @@ B B + [B<-krb5svc service>] + [B<-serverpref>] + [B<-starttls protocol>] ++[B<-xmpphost hostname>] ++[B<-name hostname>] + [B<-engine id>] + [B<-tlsextdebug>] + [B<-no_ticket>] +@@ -239,7 +241,20 @@ need keys for that principal in its keyt + + send the protocol-specific message(s) to switch to TLS for communication. + B is a keyword for the intended protocol. Currently, the only +-supported keywords are "smtp", "pop3", "imap", and "ftp". ++supported keywords are "smtp", "pop3", "imap", "ftp", "xmpp", "xmpp-server", ++"irc", "postgres", "lmtp", "nntp", "sieve" and "ldap". ++ ++=item B<-xmpphost hostname> ++ ++This option, when used with "-starttls xmpp" or "-starttls xmpp-server", ++specifies the host for the "to" attribute of the stream element. ++If this option is not specified, then the host specified with "-connect" ++will be used. ++ ++=item B<-name hostname> ++ ++the host name to use with "-starttls smtp". ++If this option is not specified, the default "openssl.client.net" will be used. + + =item B<-tlsextdebug> + diff --git a/SOURCES/openssl-thread-test.c b/SOURCES/openssl-thread-test.c new file mode 100644 index 0000000..3b90285 --- /dev/null +++ b/SOURCES/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/SOURCES/opensslconf-new-warning.h b/SOURCES/opensslconf-new-warning.h new file mode 100644 index 0000000..de091c8 --- /dev/null +++ b/SOURCES/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/SOURCES/opensslconf-new.h b/SOURCES/opensslconf-new.h new file mode 100644 index 0000000..04363c3 --- /dev/null +++ b/SOURCES/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/SOURCES/renew-dummy-cert b/SOURCES/renew-dummy-cert new file mode 100755 index 0000000..50f9931 --- /dev/null +++ b/SOURCES/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/SPECS/openssl.spec b/SPECS/openssl.spec new file mode 100644 index 0000000..254858c --- /dev/null +++ b/SPECS/openssl.spec @@ -0,0 +1,1998 @@ +# 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 +%define soversion 10 + +# Number of threads to spawn when testing some threading fixes. +%define thread_test_threads %{?threads:%{threads}}%{!?threads:1} + +# Arches on which we need to prevent arch conflicts on opensslconf.h, must +# also be handled in opensslconf-new.h. +%define multilib_arches %{ix86} ia64 %{mips} ppc ppc64 s390 s390x sparcv9 sparc64 x86_64 + +%global _performance_build 1 + +Summary: Utilities from the general purpose cryptography library with TLS implementation +Name: openssl +Version: 1.0.2k +Release: 19%{?dist} +Epoch: 1 +# 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 +Source5: README.legacy-settings +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 +Patch106: openssl-1.0.2k-rsa-check.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 +Patch107: openssl-1.0.2k-cve-2018-5407.patch +Patch108: openssl-1.0.2k-cve-2018-0734.patch +Patch109: openssl-1.0.2k-cve-2019-1559.patch +Patch110: openssl-1.0.2k-fix-one-and-done.patch +Patch111: openssl-1.0.2k-fix-9-lives.patch + +License: OpenSSL +Group: System Environment/Libraries +URL: http://www.openssl.org/ +BuildRoot: %{_tmppath}/%{name}-%{version}-root +BuildRequires: coreutils, krb5-devel, perl, sed, zlib-devel, /usr/bin/cmp +BuildRequires: lksctp-tools-devel +BuildRequires: /usr/bin/rename +BuildRequires: /usr/bin/pod2man +Requires: coreutils, make +Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release} + +%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. + +%package libs +Summary: A general purpose cryptography library with TLS implementation +Group: System Environment/Libraries +Requires: ca-certificates >= 2008-5 +# Needed obsoletes due to the base/lib subpackage split +Obsoletes: openssl < 1:1.0.1-0.3.beta3 + +%description libs +OpenSSL is a toolkit for supporting cryptography. The openssl-libs +package contains the libraries that are used by various applications which +support cryptographic algorithms and protocols. + +%package devel +Summary: Files for development of applications which will use OpenSSL +Group: Development/Libraries +Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release} +Requires: krb5-devel%{?_isa}, zlib-devel%{?_isa} +Requires: pkgconfig + +%description devel +OpenSSL is a toolkit for supporting cryptography. The openssl-devel +package contains include files needed to develop applications which +support various cryptographic algorithms and protocols. + +%package static +Summary: Libraries for static linking of applications which will use OpenSSL +Group: Development/Libraries +Requires: %{name}-devel%{?_isa} = %{epoch}:%{version}-%{release} + +%description static +OpenSSL is a toolkit for supporting cryptography. The openssl-static +package contains static libraries needed for static linking of +applications which support various cryptographic algorithms and +protocols. + +%package perl +Summary: Perl scripts provided with OpenSSL +Group: Applications/Internet +Requires: perl +Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} + +%description perl +OpenSSL is a toolkit for supporting cryptography. The openssl-perl +package provides Perl scripts for converting certificates and keys +from other formats to the formats used by the OpenSSL toolkit. + +%prep +%setup -q -n %{name}-%{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 +%patch106 -p1 -b .rsa-check + +%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 +%patch107 -p1 -b .ecc-ladder +%patch108 -p1 -b .dsa-signing +%patch109 -p1 -b .padding-oracle +%patch110 -p1 -b .one-and-done +%patch111 -p1 -b .9-lives + +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} + +%build +# Figure out which flags we want to use. +# default +sslarch=%{_os}-%{_target_cpu} +%ifarch %ix86 +sslarch=linux-elf +if ! echo %{_target} | grep -q i686 ; then + sslflags="no-asm 386" +fi +%endif +%ifarch x86_64 +sslflags=enable-ec_nistp_64_gcc_128 +%endif +%ifarch sparcv9 +sslarch=linux-sparcv9 +sslflags=no-asm +%endif +%ifarch sparc64 +sslarch=linux64-sparcv9 +sslflags=no-asm +%endif +%ifarch alpha alphaev56 alphaev6 alphaev67 +sslarch=linux-alpha-gcc +%endif +%ifarch s390 sh3eb sh4eb +sslarch="linux-generic32 -DB_ENDIAN" +%endif +%ifarch s390x +sslarch="linux64-s390x" +%endif +%ifarch %{arm} +sslarch=linux-armv4 +%endif +%ifarch aarch64 +sslarch=linux-aarch64 +sslflags=enable-ec_nistp_64_gcc_128 +%endif +%ifarch sh3 sh4 +sslarch=linux-generic32 +%endif +%ifarch ppc64 ppc64p7 +sslarch=linux-ppc64 +%endif +%ifarch ppc64le +sslarch="linux-ppc64le" +sslflags=enable-ec_nistp_64_gcc_128 +%endif +%ifarch mips mipsel +sslarch="linux-mips32 -mips32r2" +%endif +%ifarch mips64 mips64el +sslarch="linux64-mips64 -mips64r2" +%endif +%ifarch mips64el +sslflags=enable-ec_nistp_64_gcc_128 +%endif +%ifarch riscv64 +sslarch=linux-generic64 +%endif + +# ia64, x86_64, ppc are OK by default +# Configure the build tree. Override OpenSSL defaults with known-good defaults +# usable on all platforms. The Configure script already knows to use -fPIC and +# RPM_OPT_FLAGS, so we can skip specifiying them here. +./Configure \ + --prefix=%{_prefix} --openssldir=%{_sysconfdir}/pki/tls ${sslflags} \ + zlib sctp enable-camellia enable-seed enable-tlsext enable-rfc3779 \ + enable-cms enable-md2 enable-rc5 \ + no-mdc2 no-ec2m no-gost no-srp \ + --with-krb5-flavor=MIT --enginesdir=%{_libdir}/openssl/engines \ + --with-krb5-dir=/usr shared ${sslarch} %{?!nofips:fips} + +# Add -Wa,--noexecstack here so that libcrypto's assembler modules will be +# marked as not requiring an executable stack. +# Also add -DPURIFY to make using valgrind with openssl easier as we do not +# want to depend on the uninitialized memory as a source of entropy anyway. +RPM_OPT_FLAGS="$RPM_OPT_FLAGS -Wa,--noexecstack -DPURIFY" +make depend +make all + +# Generate hashes for the included certs. +make rehash + +# Overwrite FIPS README and copy README.legacy-settings +cp -f %{SOURCE5} %{SOURCE11} . + +# Clean up the .pc files +for i in libcrypto.pc libssl.pc openssl.pc ; do + sed -i '/^Libs.private:/{s/-L[^ ]* //;s/-Wl[^ ]* //}' $i +done + +%check +# Verify that what was compiled actually works. + +# We must revert patch33 before tests otherwise they will fail +patch -p1 -R < %{PATCH33} + +LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +export LD_LIBRARY_PATH +OPENSSL_ENABLE_MD5_VERIFY= +export OPENSSL_ENABLE_MD5_VERIFY +make -C test apps tests +%{__cc} -o openssl-thread-test \ + `krb5-config --cflags` \ + -I./include \ + $RPM_OPT_FLAGS \ + %{SOURCE8} \ + -L. \ + -lssl -lcrypto \ + `krb5-config --libs` \ + -lpthread -lz -ldl +./openssl-thread-test --threads %{thread_test_threads} + +# 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} \ + crypto/fips/fips_standalone_hmac $RPM_BUILD_ROOT%{_libdir}/libcrypto.so.%{version} >$RPM_BUILD_ROOT%{_libdir}/.libcrypto.so.%{version}.hmac \ + ln -sf .libcrypto.so.%{version}.hmac $RPM_BUILD_ROOT%{_libdir}/.libcrypto.so.%{soversion}.hmac \ + crypto/fips/fips_standalone_hmac $RPM_BUILD_ROOT%{_libdir}/libssl.so.%{version} >$RPM_BUILD_ROOT%{_libdir}/.libssl.so.%{version}.hmac \ + ln -sf .libssl.so.%{version}.hmac $RPM_BUILD_ROOT%{_libdir}/.libssl.so.%{soversion}.hmac \ +%{nil} + +%define __provides_exclude_from %{_libdir}/openssl + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +# Install OpenSSL. +install -d $RPM_BUILD_ROOT{%{_bindir},%{_includedir},%{_libdir},%{_mandir},%{_libdir}/openssl} +make INSTALL_PREFIX=$RPM_BUILD_ROOT install +make INSTALL_PREFIX=$RPM_BUILD_ROOT install_docs +mv $RPM_BUILD_ROOT%{_libdir}/engines $RPM_BUILD_ROOT%{_libdir}/openssl +mv $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/man/* $RPM_BUILD_ROOT%{_mandir}/ +rmdir $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/man +rename so.%{soversion} so.%{version} $RPM_BUILD_ROOT%{_libdir}/*.so.%{soversion} +mkdir $RPM_BUILD_ROOT/%{_lib} +for lib in $RPM_BUILD_ROOT%{_libdir}/*.so.%{version} ; do + chmod 755 ${lib} + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/`basename ${lib} .%{version}` + ln -s -f `basename ${lib}` $RPM_BUILD_ROOT%{_libdir}/`basename ${lib} .%{version}`.%{soversion} +done + +# Install a makefile for generating keys and self-signed certs, and a script +# for generating them on the fly. +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/certs +install -m644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/certs/Makefile +install -m755 %{SOURCE6} $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/certs/make-dummy-cert +install -m755 %{SOURCE7} $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/certs/renew-dummy-cert + +# Make sure we actually include the headers we built against. +for header in $RPM_BUILD_ROOT%{_includedir}/openssl/* ; do + if [ -f ${header} -a -f include/openssl/$(basename ${header}) ] ; then + install -m644 include/openssl/`basename ${header}` ${header} + fi +done + +# Rename man pages so that they don't conflict with other system man pages. +pushd $RPM_BUILD_ROOT%{_mandir} +ln -s -f config.5 man5/openssl.cnf.5 +for manpage in man*/* ; do + if [ -L ${manpage} ]; then + TARGET=`ls -l ${manpage} | awk '{ print $NF }'` + ln -snf ${TARGET}ssl ${manpage}ssl + rm -f ${manpage} + else + mv ${manpage} ${manpage}ssl + fi +done +for conflict in passwd rand ; do + rename ${conflict} ssl${conflict} man*/${conflict}* +done +popd + +# Pick a CA script. +pushd $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/misc +mv CA.sh CA +popd + +mkdir -m755 $RPM_BUILD_ROOT%{_sysconfdir}/pki/CA +mkdir -m700 $RPM_BUILD_ROOT%{_sysconfdir}/pki/CA/private +mkdir -m755 $RPM_BUILD_ROOT%{_sysconfdir}/pki/CA/certs +mkdir -m755 $RPM_BUILD_ROOT%{_sysconfdir}/pki/CA/crl +mkdir -m755 $RPM_BUILD_ROOT%{_sysconfdir}/pki/CA/newcerts + +# Ensure the openssl.cnf timestamp is identical across builds to avoid +# mulitlib conflicts and unnecessary renames on upgrade +touch -r %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/openssl.cnf + +# Determine which arch opensslconf.h is going to try to #include. +basearch=%{_arch} +%ifarch %{ix86} +basearch=i386 +%endif +%ifarch sparcv9 +basearch=sparc +%endif +%ifarch sparc64 +basearch=sparc64 +%endif + +%ifarch %{multilib_arches} +# Do an opensslconf.h switcheroo to avoid file conflicts on systems where you +# can have both a 32- and 64-bit version of the library, and they each need +# their own correct-but-different versions of opensslconf.h to be usable. +install -m644 %{SOURCE10} \ + $RPM_BUILD_ROOT/%{_prefix}/include/openssl/opensslconf-${basearch}.h +cat $RPM_BUILD_ROOT/%{_prefix}/include/openssl/opensslconf.h >> \ + $RPM_BUILD_ROOT/%{_prefix}/include/openssl/opensslconf-${basearch}.h +install -m644 %{SOURCE9} \ + $RPM_BUILD_ROOT/%{_prefix}/include/openssl/opensslconf.h +%endif + +# Remove unused files from upstream fips support +rm -rf $RPM_BUILD_ROOT/%{_bindir}/openssl_fips_fingerprint +rm -rf $RPM_BUILD_ROOT/%{_libdir}/fips_premain.* +rm -rf $RPM_BUILD_ROOT/%{_libdir}/fipscanister.* + +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%{!?_licensedir:%global license %%doc} +%license LICENSE +%doc FAQ NEWS README +%doc README.FIPS +%doc README.legacy-settings +%{_sysconfdir}/pki/tls/certs/make-dummy-cert +%{_sysconfdir}/pki/tls/certs/renew-dummy-cert +%{_sysconfdir}/pki/tls/certs/Makefile +%{_sysconfdir}/pki/tls/misc/CA +%dir %{_sysconfdir}/pki/CA +%dir %{_sysconfdir}/pki/CA/private +%dir %{_sysconfdir}/pki/CA/certs +%dir %{_sysconfdir}/pki/CA/crl +%dir %{_sysconfdir}/pki/CA/newcerts +%{_sysconfdir}/pki/tls/misc/c_* +%attr(0755,root,root) %{_bindir}/openssl +%attr(0644,root,root) %{_mandir}/man1*/* +%exclude %{_mandir}/man1*/*.pl* +%exclude %{_mandir}/man1*/c_rehash* +%exclude %{_mandir}/man1*/tsget* +%attr(0644,root,root) %{_mandir}/man5*/* +%attr(0644,root,root) %{_mandir}/man7*/* + +%files libs +%defattr(-,root,root) +%{!?_licensedir:%global license %%doc} +%license LICENSE +%dir %{_sysconfdir}/pki/tls +%dir %{_sysconfdir}/pki/tls/certs +%dir %{_sysconfdir}/pki/tls/misc +%dir %{_sysconfdir}/pki/tls/private +%config(noreplace) %{_sysconfdir}/pki/tls/openssl.cnf +%attr(0755,root,root) %{_libdir}/libcrypto.so.%{version} +%attr(0755,root,root) %{_libdir}/libcrypto.so.%{soversion} +%attr(0755,root,root) %{_libdir}/libssl.so.%{version} +%attr(0755,root,root) %{_libdir}/libssl.so.%{soversion} +%attr(0644,root,root) %{_libdir}/.libcrypto.so.*.hmac +%attr(0644,root,root) %{_libdir}/.libssl.so.*.hmac +%attr(0755,root,root) %{_libdir}/openssl + +%files devel +%defattr(-,root,root) +%doc doc/c-indentation.el doc/openssl.txt CHANGES +%{_prefix}/include/openssl +%attr(0755,root,root) %{_libdir}/*.so +%attr(0644,root,root) %{_mandir}/man3*/* +%attr(0644,root,root) %{_libdir}/pkgconfig/*.pc + +%files static +%defattr(-,root,root) +%attr(0644,root,root) %{_libdir}/*.a + +%files perl +%defattr(-,root,root) +%attr(0755,root,root) %{_bindir}/c_rehash +%attr(0644,root,root) %{_mandir}/man1*/*.pl* +%attr(0644,root,root) %{_mandir}/man1*/c_rehash* +%attr(0644,root,root) %{_mandir}/man1*/tsget* +%{_sysconfdir}/pki/tls/misc/*.pl +%{_sysconfdir}/pki/tls/misc/tsget + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + +%changelog +* Tue Apr 9 2019 Tomáš Mráz 1.0.2k-19 +- close the RSA decryption 9 lives of Bleichenbacher cat + timing side channel (#1649568) + +* Fri Apr 5 2019 Tomáš Mráz 1.0.2k-18 +- fix CVE-2018-0734 - DSA signature local timing side channel +- fix CVE-2019-1559 - 0-byte record padding oracle +- close the RSA decryption One & done EM side channel (#1619558) + +* Wed Feb 6 2019 Tomáš Mráz 1.0.2k-17 +- use SHA-256 in FIPS RSA pairwise key check +- fix CVE-2018-5407 (and CVE-2018-0735) - EC signature local + timing side-channel key extraction + +* Tue Aug 14 2018 Tomáš Mráz 1.0.2k-16 +- fix CVE-2018-0495 - ROHNP - Key Extraction Side Channel on DSA, ECDSA +- fix incorrect error message on FIPS DSA parameter generation (#1603597) + +* Tue Jun 19 2018 Tomáš Mráz 1.0.2k-14 +- ppc64le is not multilib architecture (#1585004) + +* Mon Jun 18 2018 Tomáš Mráz 1.0.2k-13 +- add S390x assembler updates +- make CA name list comparison function case sensitive (#1548401) +- fix CVE-2017-3735 - possible one byte overread with X.509 IPAdressFamily +- fix CVE-2018-0732 - large prime DH DoS of TLS client +- fix CVE-2018-0737 - RSA key generation cache timing vulnerability +- fix CVE-2018-0739 - stack overflow parsing recursive ASN.1 structure + +* Wed Dec 13 2017 Tomáš Mráz 1.0.2k-12 +- fix CVE-2017-3737 - incorrect handling of fatal error state +- fix CVE-2017-3738 - AVX2 Montgomery multiplication bug with 1024 bit modulus + +* Wed Dec 6 2017 Tomáš Mráz 1.0.2k-11 +- fix deadlock in RNG in the FIPS mode in mariadb + +* Tue Nov 7 2017 Tomáš Mráz 1.0.2k-9 +- fix CVE-2017-3736 - carry propagation bug in Montgomery multiplication + +* Wed May 17 2017 Tomáš Mráz 1.0.2k-8 +- fix regression in openssl req -x509 command (#1450015) + +* Thu Apr 13 2017 Tomáš Mráz 1.0.2k-7 +- handle incorrect size gracefully in aes_p8_cbc_encrypt() + +* Mon Mar 27 2017 Tomáš Mráz 1.0.2k-6 +- allow long client hellos to be received by server + +* Mon Mar 27 2017 Tomáš Mráz 1.0.2k-5 +- fix CPU features detection on new AMD processors + +* Thu Mar 9 2017 Tomáš Mráz 1.0.2k-4 +- add support for additional STARTTLS protocols to s_client + original backported patch by Robert Scheck (#1396209) + +* Wed Mar 1 2017 Tomáš Mráz 1.0.2k-3 +- properly document the SSLv2 support removal + +* Mon Feb 20 2017 Tomáš Mráz 1.0.2k-2 +- add PPC assembler updates + +* Tue Feb 7 2017 Tomáš Mráz 1.0.2k-1 +- minor upstream release 1.0.2k fixing security issues + +* Tue Jan 10 2017 Tomáš Mráz 1.0.2j-2 +- deprecate and disable verification of insecure hash algorithms +- add support for /etc/pki/tls/legacy-settings also for minimum DH length + accepted by SSL client +- compare the encrypt and tweak key in XTS as required by FIPS + +* Thu Jan 5 2017 Tomáš Mráz 1.0.2j-1 +- rebase to latest upstream release from the 1.0.2 branch, ABI compatible + +* Thu Sep 22 2016 Tomáš Mráz 1.0.1e-60 +- fix CVE-2016-2177 - possible integer overflow +- fix CVE-2016-2178 - non-constant time DSA operations +- fix CVE-2016-2179 - further DoS issues in DTLS +- fix CVE-2016-2180 - OOB read in TS_OBJ_print_bio() +- fix CVE-2016-2181 - DTLS1 replay protection and unprocessed records issue +- fix CVE-2016-2182 - possible buffer overflow in BN_bn2dec() +- fix CVE-2016-6302 - insufficient TLS session ticket HMAC length check +- fix CVE-2016-6304 - unbound memory growth with OCSP status request +- fix CVE-2016-6306 - certificate message OOB reads +- mitigate CVE-2016-2183 - degrade all 64bit block ciphers and RC4 to + 112 bit effective strength + +* Tue Jun 21 2016 Tomáš Mráz 1.0.1e-58 +- replace expired testing certificates + +* Fri Apr 29 2016 Tomáš Mráz 1.0.1e-57 +- fix CVE-2016-2105 - possible overflow in base64 encoding +- fix CVE-2016-2106 - possible overflow in EVP_EncryptUpdate() +- fix CVE-2016-2107 - padding oracle in stitched AES-NI CBC-MAC +- fix CVE-2016-2108 - memory corruption in ASN.1 encoder +- fix CVE-2016-2109 - possible DoS when reading ASN.1 data from BIO + +* Thu Apr 7 2016 Tomáš Mráz 1.0.1e-56 +- fix 1-byte memory leak in pkcs12 parse (#1312112) +- document some options of the speed command (#1312110) +- fix high-precision timestamps in timestamping authority +- enable SCTP support in DTLS +- use correct digest when exporting keying material in TLS1.2 (#1289620) +- fix CVE-2016-0799 - memory issues in BIO_printf +- add support for setting Kerberos service and keytab in + s_server and s_client + +* Wed Feb 24 2016 Tomáš Mráz 1.0.1e-55 +- fix CVE-2016-0702 - side channel attack on modular exponentiation +- fix CVE-2016-0705 - double-free in DSA private key parsing +- fix CVE-2016-0797 - heap corruption in BN_hex2bn and BN_dec2bn + +* Tue Feb 16 2016 Tomáš Mráz 1.0.1e-54 +- fix CVE-2015-3197 - SSLv2 ciphersuite enforcement +- disable SSLv2 in the generic TLS method + +* Mon Dec 21 2015 Tomáš Mráz 1.0.1e-53 +- fix CVE-2015-7575 - disallow use of MD5 in TLS1.2 + +* Fri Dec 4 2015 Tomáš Mráz 1.0.1e-52 +- fix CVE-2015-3194 - certificate verify crash with missing PSS parameter +- fix CVE-2015-3195 - X509_ATTRIBUTE memory leak +- fix CVE-2015-3196 - race condition when handling PSK identity hint + +* Tue Jun 23 2015 Tomáš Mráz 1.0.1e-51 +- fix the CVE-2015-1791 fix (broken server side renegotiation) + +* Thu Jun 11 2015 Tomáš Mráz 1.0.1e-50 +- improved fix for CVE-2015-1791 +- add missing parts of CVE-2015-0209 fix for corectness although unexploitable + +* Tue Jun 9 2015 Tomáš Mráz 1.0.1e-49 +- fix CVE-2014-8176 - invalid free in DTLS buffering code +- fix CVE-2015-1789 - out-of-bounds read in X509_cmp_time +- fix CVE-2015-1790 - PKCS7 crash with missing EncryptedContent +- fix CVE-2015-1791 - race condition handling NewSessionTicket +- fix CVE-2015-1792 - CMS verify infinite loop with unknown hash function + +* Wed Jun 3 2015 Tomáš Mráz 1.0.1e-48 +- fix CVE-2015-3216 - regression in RAND locking that can cause segfaults on + read in multithreaded applications + +* Mon May 25 2015 Tomáš Mráz 1.0.1e-47 +- fix CVE-2015-4000 - prevent the logjam attack on client - restrict + the DH key size to at least 768 bits (limit will be increased in future) + +* Wed Mar 25 2015 Tomáš Mráz 1.0.1e-46 +- drop the AES-GCM restriction of 2^32 operations because the IV is + always 96 bits (32 bit fixed field + 64 bit invocation field) + +* Thu Mar 19 2015 Tomáš Mráz 1.0.1e-45 +- update fix for CVE-2015-0287 to what was released upstream + +* Wed Mar 18 2015 Tomáš Mráz 1.0.1e-44 +- fix CVE-2015-0209 - potential use after free in d2i_ECPrivateKey() +- fix CVE-2015-0286 - improper handling of ASN.1 boolean comparison +- fix CVE-2015-0287 - ASN.1 structure reuse decoding memory corruption +- fix CVE-2015-0288 - X509_to_X509_REQ NULL pointer dereference +- fix CVE-2015-0289 - NULL dereference decoding invalid PKCS#7 data +- fix CVE-2015-0292 - integer underflow in base64 decoder +- fix CVE-2015-0293 - triggerable assert in SSLv2 server + +* Mon Mar 16 2015 Tomáš Mráz 1.0.1e-43 +- fix broken error detection when unwrapping unpadded key + +* Mon Mar 2 2015 Tomáš Mráz 1.0.1e-42.1 +- fix the RFC 5649 for key material that does not need padding + +* Thu Jan 15 2015 Tomáš Mráz 1.0.1e-42 +- test in the non-FIPS RSA keygen for minimal distance of p and q + similarly to the FIPS RSA keygen + +* Tue Jan 13 2015 Tomáš Mráz 1.0.1e-41 +- fix CVE-2014-3570 - incorrect computation in BN_sqr() +- fix CVE-2014-3571 - possible crash in dtls1_get_record() +- fix CVE-2014-3572 - possible downgrade of ECDH ciphersuite to non-PFS state +- fix CVE-2014-8275 - various certificate fingerprint issues +- fix CVE-2015-0204 - remove support for RSA ephemeral keys for non-export + ciphersuites and on server +- fix CVE-2015-0205 - do not allow unauthenticated client DH certificate +- fix CVE-2015-0206 - possible memory leak when buffering DTLS records + +* Tue Oct 21 2014 Tomáš Mráz 1.0.1e-40 +- use FIPS approved method for computation of d in RSA +- copy digest algorithm when handling SNI context switch + +* Wed Oct 15 2014 Tomáš Mráz 1.0.1e-39 +- fix CVE-2014-3567 - memory leak when handling session tickets +- fix CVE-2014-3513 - memory leak in srtp support +- add support for fallback SCSV to partially mitigate CVE-2014-3566 + (padding attack on SSL3) + +* Wed Sep 24 2014 Tomáš Mráz 1.0.1e-38 +- do FIPS algorithm selftest before the integrity check + +* Thu Sep 18 2014 Tomáš Mráz 1.0.1e-37 +- add support for RFC 5649 (#1119738) +- do not pass the FIPS integrity check if the .hmac files are empty (#1128849) +- add ECC TLS extensions to DTLS (#1119803) +- do not send ECC ciphersuites in SSLv2 client hello (#1090955) +- properly propagate encryption failure in BIO_f_cipher (#1072439) +- fix CVE-2014-0224 fix that broke EAP-FAST session resumption support +- improve documentation of ciphersuites - patch by Hubert Kario (#1108026) +- use case insensitive comparison for servername in s_server (#1081163) +- add support for automatic ECDH curve selection on server (#1080128) +- FIPS mode: make the limitations on DSA, DH, and RSA keygen + length enforced only if OPENSSL_ENFORCE_MODULUS_BITS environment + variable is set + +* Wed Aug 13 2014 Tomáš Mráz 1.0.1e-36 +- add support for ppc64le architecture +- add Power 8 optimalizations + +* Fri Aug 8 2014 Tomáš Mráz 1.0.1e-35 +- fix CVE-2014-3505 - doublefree in DTLS packet processing +- fix CVE-2014-3506 - avoid memory exhaustion in DTLS +- fix CVE-2014-3507 - avoid memory leak in DTLS +- fix CVE-2014-3508 - fix OID handling to avoid information leak +- fix CVE-2014-3509 - fix race condition when parsing server hello +- fix CVE-2014-3510 - fix DoS in anonymous (EC)DH handling in DTLS +- fix CVE-2014-3511 - disallow protocol downgrade via fragmentation + +* Tue Jun 3 2014 Tomáš Mráz 1.0.1e-34.3 +- fix CVE-2010-5298 - possible use of memory after free +- fix CVE-2014-0195 - buffer overflow via invalid DTLS fragment +- fix CVE-2014-0198 - possible NULL pointer dereference +- fix CVE-2014-0221 - DoS from invalid DTLS handshake packet +- fix CVE-2014-0224 - SSL/TLS MITM vulnerability +- fix CVE-2014-3470 - client-side DoS when using anonymous ECDH + +* Tue Apr 8 2014 Tomáš Mráz 1.0.1e-34 +- fix CVE-2014-0160 - information disclosure in TLS heartbeat extension + +* Fri Feb 14 2014 Tomáš Mráz 1.0.1e-33 +- use the key length from configuration file if req -newkey rsa is invoked + +* Thu Feb 13 2014 Tomáš Mráz 1.0.1e-32 +- avoid unnecessary reseeding in BN_rand in the FIPS mode + +* Wed Feb 12 2014 Tomáš Mráz 1.0.1e-31 +- print ephemeral key size negotiated in TLS handshake (#1057715) +- add DH_compute_key_padded needed for FIPS CAVS testing +- make expiration and key length changeable by DAYS and KEYLEN + variables in the certificate Makefile (#1058108) +- change default hash to sha256 (#1062325) +- lower the actual 3des strength so it is sorted behind aes128 (#1056616) + +* Fri Jan 24 2014 Daniel Mach - 1:1.0.1e-30 +- Mass rebuild 2014-01-24 + +* Wed Jan 15 2014 Tomáš Mráz 1.0.1e-29 +- rebuild with -O3 on ppc64 architecture + +* Tue Jan 7 2014 Tomáš Mráz 1.0.1e-28 +- fix CVE-2013-4353 - Invalid TLS handshake crash +- fix CVE-2013-6450 - possible MiTM attack on DTLS1 + +* Fri Dec 27 2013 Daniel Mach - 1:1.0.1e-27 +- Mass rebuild 2013-12-27 + +* Fri Dec 20 2013 Tomáš Mráz 1.0.1e-26 +- fix CVE-2013-6449 - crash when version in SSL structure is incorrect +- drop weak ciphers from the default TLS ciphersuite list +- add back some symbols that were dropped with update to 1.0.1 branch +- more FIPS validation requirement changes + +* Tue Nov 19 2013 Tomáš Mráz 1.0.1e-25 +- fix locking and reseeding problems with FIPS drbg + +* Fri Nov 15 2013 Tomáš Mráz 1.0.1e-24 +- additional changes required for FIPS validation +- disable verification of certificate, CRL, and OCSP signatures + using MD5 if OPENSSL_ENABLE_MD5_VERIFY environment variable + is not set + +* Fri Nov 8 2013 Tomáš Mráz 1.0.1e-23 +- add back support for secp521r1 EC curve +- add aarch64 to Configure (#969692) + +* Thu Oct 24 2013 Tomáš Mráz 1.0.1e-22 +- do not advertise ECC curves we do not support (#1022493) + +* Fri Oct 4 2013 Tomáš Mráz 1.0.1e-21 +- make DTLS1 work in FIPS mode +- avoid RSA and DSA 512 bits and Whirlpool in 'openssl speed' in FIPS mode +- drop the -fips subpackage, installation of dracut-fips marks that the FIPS + module is installed +- avoid dlopening libssl.so from libcrypto +- fix small memory leak in FIPS aes selftest +- fix segfault in openssl speed hmac in the FIPS mode + +* Thu Sep 12 2013 Tomáš Mráz 1.0.1e-20 +- document the nextprotoneg option in manual pages + original patch by Hubert Kario +- try to avoid some races when updating the -fips subpackage + +* Mon Sep 2 2013 Tomas Mraz 1.0.1e-19 +- use version-release in .hmac suffix to avoid overwrite + during upgrade + +* Thu Aug 29 2013 Tomas Mraz 1.0.1e-18 +- always perform the FIPS selftests in library constructor + if FIPS module is installed + +* Tue Aug 27 2013 Tomas Mraz 1.0.1e-16 +- add -fips subpackage that contains the FIPS module files + +* Fri Aug 16 2013 Tomas Mraz 1.0.1e-15 +- fix use of rdrand if available +- more commits cherry picked from upstream +- documentation fixes + +* Fri Jul 26 2013 Tomas Mraz 1.0.1e-14 +- additional manual page fix +- use symbol versioning also for the textual version + +* Thu Jul 25 2013 Tomas Mraz 1.0.1e-13 +- additional manual page fixes +- cleanup speed command output for ECDH ECDSA + +* Fri Jul 19 2013 Tomas Mraz 1.0.1e-12 +- use _prefix macro + +* Thu Jul 11 2013 Tomas Mraz 1.0.1e-11 +- add openssl.cnf.5 manpage symlink to config.5 + +* Wed Jul 10 2013 Tomas Mraz 1.0.1e-10 +- add relro linking flag + +* Wed Jul 10 2013 Tomas Mraz 1.0.1e-9 +- add support for the -trusted_first option for certificate chain verification + +* Fri May 10 2013 Tomáš Mráz 1.0.1e-8 +- disable GOST engine + +* Thu May 9 2013 Tomáš Mráz 1.0.1e-7 +- add symbol version for ECC functions + +* Fri May 3 2013 Tomáš Mráz 1.0.1e-6 +- update the FIPS selftests to use 256 bit curves + +* Tue Apr 30 2013 Tomas Mraz 1.0.1e-5 +- enabled NIST Suite B ECC curves and algorithms + +* Mon Mar 18 2013 Tomas Mraz 1.0.1e-4 +- fix random bad record mac errors (#918981) + +* Tue Feb 19 2013 Tomas Mraz 1.0.1e-3 +- fix up the SHLIB_VERSION_NUMBER + +* Tue Feb 19 2013 Tomas Mraz 1.0.1e-2 +- disable ZLIB loading by default (due to CRIME attack) + +* Tue Feb 19 2013 Tomas Mraz 1.0.1e-1 +- new upstream version + +* Wed Jan 30 2013 Tomas Mraz 1.0.1c-12 +- more fixes from upstream +- fix errors in manual causing build failure (#904777) + +* Fri Dec 21 2012 Tomas Mraz 1.0.1c-11 +- add script for renewal of a self-signed cert by Philip Prindeville (#871566) +- allow X509_issuer_and_serial_hash() produce correct result in + the FIPS mode (#881336) + +* Thu Dec 6 2012 Tomas Mraz 1.0.1c-10 +- do not load default verify paths if CApath or CAfile specified (#884305) + +* Tue Nov 20 2012 Tomas Mraz 1.0.1c-9 +- more fixes from upstream CVS +- fix DSA key pairwise check (#878597) + +* Thu Nov 15 2012 Tomas Mraz 1.0.1c-8 +- use 1024 bit DH parameters in s_server as 512 bit is not allowed + in FIPS mode and it is quite weak anyway + +* Mon Sep 10 2012 Tomas Mraz 1.0.1c-7 +- add missing initialization of str in aes_ccm_init_key (#853963) +- add important patches from upstream CVS +- use the secure_getenv() with new glibc + +* Fri Jul 20 2012 Fedora Release Engineering - 1:1.0.1c-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jul 13 2012 Tomas Mraz 1.0.1c-5 +- use __getenv_secure() instead of __libc_enable_secure + +* Fri Jul 13 2012 Tomas Mraz 1.0.1c-4 +- do not move libcrypto to /lib +- do not use environment variables if __libc_enable_secure is on +- fix strict aliasing problems in modes + +* Thu Jul 12 2012 Tomas Mraz 1.0.1c-3 +- fix DSA key generation in FIPS mode (#833866) +- allow duplicate FIPS_mode_set(1) +- enable build on ppc64 subarch (#834652) + +* Wed Jul 11 2012 Tomas Mraz 1.0.1c-2 +- fix s_server with new glibc when no global IPv6 address (#839031) +- make it build with new Perl + +* Tue May 15 2012 Tomas Mraz 1.0.1c-1 +- new upstream version + +* Thu Apr 26 2012 Tomas Mraz 1.0.1b-1 +- new upstream version + +* Fri Apr 20 2012 Tomas Mraz 1.0.1a-1 +- new upstream version fixing CVE-2012-2110 + +* Wed Apr 11 2012 Tomas Mraz 1.0.1-3 +- add Kerberos 5 libraries to pkgconfig for static linking (#807050) + +* Thu Apr 5 2012 Tomas Mraz 1.0.1-2 +- backports from upstream CVS +- fix segfault when /dev/urandom is not available (#809586) + +* Wed Mar 14 2012 Tomas Mraz 1.0.1-1 +- new upstream release + +* Mon Mar 5 2012 Tomas Mraz 1.0.1-0.3.beta3 +- add obsoletes to assist multilib updates (#799636) + +* Wed Feb 29 2012 Tomas Mraz 1.0.1-0.2.beta3 +- epoch bumped to 1 due to revert to 1.0.0g on Fedora 17 +- new upstream release from the 1.0.1 branch +- fix s390x build (#798411) +- versioning for the SSLeay symbol (#794950) +- add -DPURIFY to build flags (#797323) +- filter engine provides +- split the libraries to a separate -libs package +- add make to requires on the base package (#783446) + +* Tue Feb 7 2012 Tomas Mraz 1.0.1-0.1.beta2 +- new upstream release from the 1.0.1 branch, ABI compatible +- add documentation for the -no_ign_eof option + +* Thu Jan 19 2012 Tomas Mraz 1.0.0g-1 +- new upstream release fixing CVE-2012-0050 - DoS regression in + DTLS support introduced by the previous release (#782795) + +* Thu Jan 5 2012 Tomas Mraz 1.0.0f-1 +- new upstream release fixing multiple CVEs + +* Tue Nov 22 2011 Tomas Mraz 1.0.0e-4 +- move the libraries needed for static linking to Libs.private + +* Thu Nov 3 2011 Tomas Mraz 1.0.0e-3 +- do not use AVX instructions when osxsave bit not set +- add direct known answer tests for SHA2 algorithms + +* Wed Sep 21 2011 Tomas Mraz 1.0.0e-2 +- fix missing initialization of variable in CHIL engine + +* Wed Sep 7 2011 Tomas Mraz 1.0.0e-1 +- new upstream release fixing CVE-2011-3207 (#736088) + +* Wed Aug 24 2011 Tomas Mraz 1.0.0d-8 +- drop the separate engine for Intel acceleration improvements + and merge in the AES-NI, SHA1, and RC4 optimizations +- add support for OPENSSL_DISABLE_AES_NI environment variable + that disables the AES-NI support + +* Tue Jul 26 2011 Tomas Mraz 1.0.0d-7 +- correct openssl cms help output (#636266) +- more tolerant starttls detection in XMPP protocol (#608239) + +* Wed Jul 20 2011 Tomas Mraz 1.0.0d-6 +- add support for newest Intel acceleration improvements backported + from upstream by Intel in form of a separate engine + +* Thu Jun 9 2011 Tomas Mraz 1.0.0d-5 +- allow the AES-NI engine in the FIPS mode + +* Tue May 24 2011 Tomas Mraz 1.0.0d-4 +- add API necessary for CAVS testing of the new DSA parameter generation + +* Thu Apr 28 2011 Tomas Mraz 1.0.0d-3 +- add support for VIA Padlock on 64bit arch from upstream (#617539) +- do not return bogus values from load_certs (#652286) + +* Tue Apr 5 2011 Tomas Mraz 1.0.0d-2 +- clarify apps help texts for available digest algorithms (#693858) + +* Thu Feb 10 2011 Tomas Mraz 1.0.0d-1 +- new upstream release fixing CVE-2011-0014 (OCSP stapling vulnerability) + +* Tue Feb 08 2011 Fedora Release Engineering - 1.0.0c-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Feb 4 2011 Tomas Mraz 1.0.0c-3 +- add -x931 parameter to openssl genrsa command to use the ANSI X9.31 + key generation method +- use FIPS-186-3 method for DSA parameter generation +- add OPENSSL_FIPS_NON_APPROVED_MD5_ALLOW environment variable + to allow using MD5 when the system is in the maintenance state + even if the /proc fips flag is on +- make openssl pkcs12 command work by default in the FIPS mode + +* Mon Jan 24 2011 Tomas Mraz 1.0.0c-2 +- listen on ipv6 wildcard in s_server so we accept connections + from both ipv4 and ipv6 (#601612) +- fix openssl speed command so it can be used in the FIPS mode + with FIPS allowed ciphers + +* Fri Dec 3 2010 Tomas Mraz 1.0.0c-1 +- new upstream version fixing CVE-2010-4180 + +* Tue Nov 23 2010 Tomas Mraz 1.0.0b-3 +- replace the revert for the s390x bignum asm routines with + fix from upstream + +* Mon Nov 22 2010 Tomas Mraz 1.0.0b-2 +- revert upstream change in s390x bignum asm routines + +* Tue Nov 16 2010 Tomas Mraz 1.0.0b-1 +- new upstream version fixing CVE-2010-3864 (#649304) + +* Tue Sep 7 2010 Tomas Mraz 1.0.0a-3 +- make SHLIB_VERSION reflect the library suffix + +* Wed Jun 30 2010 Tomas Mraz 1.0.0a-2 +- openssl man page fix (#609484) + +* Fri Jun 4 2010 Tomas Mraz 1.0.0a-1 +- new upstream patch release, fixes CVE-2010-0742 (#598738) + and CVE-2010-1633 (#598732) + +* Wed May 19 2010 Tomas Mraz 1.0.0-5 +- pkgconfig files now contain the correct libdir (#593723) + +* Tue May 18 2010 Tomas Mraz 1.0.0-4 +- make CA dir readable - the private keys are in private subdir (#584810) + +* Fri Apr 9 2010 Tomas Mraz 1.0.0-3 +- a few fixes from upstream CVS +- move libcrypto to /lib (#559953) + +* Tue Apr 6 2010 Tomas Mraz 1.0.0-2 +- set UTC timezone on pod2man run (#578842) +- make X509_NAME_hash_old work in FIPS mode + +* Tue Mar 30 2010 Tomas Mraz 1.0.0-1 +- update to final 1.0.0 upstream release + +* Tue Feb 16 2010 Tomas Mraz 1.0.0-0.22.beta5 +- make TLS work in the FIPS mode + +* Fri Feb 12 2010 Tomas Mraz 1.0.0-0.21.beta5 +- gracefully handle zero length in assembler implementations of + OPENSSL_cleanse (#564029) +- do not fail in s_server if client hostname not resolvable (#561260) + +* Wed Jan 20 2010 Tomas Mraz 1.0.0-0.20.beta5 +- new upstream release + +* Thu Jan 14 2010 Tomas Mraz 1.0.0-0.19.beta4 +- fix CVE-2009-4355 - leak in applications incorrectly calling + CRYPTO_free_all_ex_data() before application exit (#546707) +- upstream fix for future TLS protocol version handling + +* Wed Jan 13 2010 Tomas Mraz 1.0.0-0.18.beta4 +- add support for Intel AES-NI + +* Thu Jan 7 2010 Tomas Mraz 1.0.0-0.17.beta4 +- upstream fix compression handling on session resumption +- various null checks and other small fixes from upstream +- upstream changes for the renegotiation info according to the latest draft + +* Mon Nov 23 2009 Tomas Mraz 1.0.0-0.16.beta4 +- fix non-fips mingw build (patch by Kalev Lember) +- add IPV6 fix for DTLS + +* Fri Nov 20 2009 Tomas Mraz 1.0.0-0.15.beta4 +- add better error reporting for the unsafe renegotiation + +* Fri Nov 20 2009 Tomas Mraz 1.0.0-0.14.beta4 +- fix build on s390x + +* Wed Nov 18 2009 Tomas Mraz 1.0.0-0.13.beta4 +- disable enforcement of the renegotiation extension on the client (#537962) +- add fixes from the current upstream snapshot + +* Fri Nov 13 2009 Tomas Mraz 1.0.0-0.12.beta4 +- keep the beta status in version number at 3 so we do not have to rebuild + openssh and possibly other dependencies with too strict version check + +* Thu Nov 12 2009 Tomas Mraz 1.0.0-0.11.beta4 +- update to new upstream version, no soname bump needed +- fix CVE-2009-3555 - note that the fix is bypassed if SSL_OP_ALL is used + so the compatibility with unfixed clients is not broken. The + protocol extension is also not final. + +* Fri Oct 16 2009 Tomas Mraz 1.0.0-0.10.beta3 +- fix use of freed memory if SSL_CTX_free() is called before + SSL_free() (#521342) + +* Thu Oct 8 2009 Tomas Mraz 1.0.0-0.9.beta3 +- fix typo in DTLS1 code (#527015) +- fix leak in error handling of d2i_SSL_SESSION() + +* Wed Sep 30 2009 Tomas Mraz 1.0.0-0.8.beta3 +- fix RSA and DSA FIPS selftests +- reenable fixed x86_64 camellia assembler code (#521127) + +* Fri Sep 4 2009 Tomas Mraz 1.0.0-0.7.beta3 +- temporarily disable x86_64 camellia assembler code (#521127) + +* Mon Aug 31 2009 Tomas Mraz 1.0.0-0.6.beta3 +- fix openssl dgst -dss1 (#520152) + +* Wed Aug 26 2009 Tomas Mraz 1.0.0-0.5.beta3 +- drop the compat symlink hacks + +* Sat Aug 22 2009 Tomas Mraz 1.0.0-0.4.beta3 +- constify SSL_CIPHER_description() + +* Fri Aug 21 2009 Tomas Mraz 1.0.0-0.3.beta3 +- fix WWW:Curl:Easy reference in tsget + +* Fri Aug 21 2009 Tomas Mraz 1.0.0-0.2.beta3 +- enable MD-2 + +* Thu Aug 20 2009 Tomas Mraz 1.0.0-0.1.beta3 +- update to new major upstream release + +* Sat Jul 25 2009 Fedora Release Engineering - 0.9.8k-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 22 2009 Bill Nottingham +- do not build special 'optimized' versions for i686, as that's the base + arch in Fedora now + +* Tue Jun 30 2009 Tomas Mraz 0.9.8k-6 +- abort if selftests failed and random number generator is polled +- mention EVP_aes and EVP_sha2xx routines in the manpages +- add README.FIPS +- make CA dir absolute path (#445344) +- change default length for RSA key generation to 2048 (#484101) + +* Thu May 21 2009 Tomas Mraz 0.9.8k-5 +- fix CVE-2009-1377 CVE-2009-1378 CVE-2009-1379 + (DTLS DoS problems) (#501253, #501254, #501572) + +* Tue Apr 21 2009 Tomas Mraz 0.9.8k-4 +- support compatibility DTLS mode for CISCO AnyConnect (#464629) + +* Fri Apr 17 2009 Tomas Mraz 0.9.8k-3 +- correct the SHLIB_VERSION define + +* Wed Apr 15 2009 Tomas Mraz 0.9.8k-2 +- add support for multiple CRLs with same subject +- load only dynamic engine support in FIPS mode + +* Wed Mar 25 2009 Tomas Mraz 0.9.8k-1 +- update to new upstream release (minor bug fixes, security + fixes and machine code optimizations only) + +* Thu Mar 19 2009 Tomas Mraz 0.9.8j-10 +- move libraries to /usr/lib (#239375) + +* Fri Mar 13 2009 Tomas Mraz 0.9.8j-9 +- add a static subpackage + +* Thu Feb 26 2009 Fedora Release Engineering - 0.9.8j-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Mon Feb 2 2009 Tomas Mraz 0.9.8j-7 +- must also verify checksum of libssl.so in the FIPS mode +- obtain the seed for FIPS rng directly from the kernel device +- drop the temporary symlinks + +* Mon Jan 26 2009 Tomas Mraz 0.9.8j-6 +- drop the temporary triggerpostun and symlinking in post +- fix the pkgconfig files and drop the unnecessary buildrequires + on pkgconfig as it is a rpmbuild dependency (#481419) + +* Sat Jan 17 2009 Tomas Mraz 0.9.8j-5 +- add temporary triggerpostun to reinstate the symlinks + +* Sat Jan 17 2009 Tomas Mraz 0.9.8j-4 +- no pairwise key tests in non-fips mode (#479817) + +* Fri Jan 16 2009 Tomas Mraz 0.9.8j-3 +- even more robust test for the temporary symlinks + +* Fri Jan 16 2009 Tomas Mraz 0.9.8j-2 +- try to ensure the temporary symlinks exist + +* Thu Jan 15 2009 Tomas Mraz 0.9.8j-1 +- new upstream version with necessary soname bump (#455753) +- temporarily provide symlink to old soname to make it possible to rebuild + the dependent packages in rawhide +- add eap-fast support (#428181) +- add possibility to disable zlib by setting +- add fips mode support for testing purposes +- do not null dereference on some invalid smime files +- add buildrequires pkgconfig (#479493) + +* Sun Aug 10 2008 Tomas Mraz 0.9.8g-11 +- do not add tls extensions to server hello for SSLv3 either + +* Mon Jun 2 2008 Joe Orton 0.9.8g-10 +- move root CA bundle to ca-certificates package + +* Wed May 28 2008 Tomas Mraz 0.9.8g-9 +- fix CVE-2008-0891 - server name extension crash (#448492) +- fix CVE-2008-1672 - server key exchange message omit crash (#448495) + +* Tue May 27 2008 Tomas Mraz 0.9.8g-8 +- super-H arch support +- drop workaround for bug 199604 as it should be fixed in gcc-4.3 + +* Mon May 19 2008 Tom "spot" Callaway 0.9.8g-7 +- sparc handling + +* Mon Mar 10 2008 Joe Orton 0.9.8g-6 +- update to new root CA bundle from mozilla.org (r1.45) + +* Wed Feb 20 2008 Fedora Release Engineering - 0.9.8g-5 +- Autorebuild for GCC 4.3 + +* Thu Jan 24 2008 Tomas Mraz 0.9.8g-4 +- merge review fixes (#226220) +- adjust the SHLIB_VERSION_NUMBER to reflect library name (#429846) + +* Thu Dec 13 2007 Tomas Mraz 0.9.8g-3 +- set default paths when no explicit paths are set (#418771) +- do not add tls extensions to client hello for SSLv3 (#422081) + +* Tue Dec 4 2007 Tomas Mraz 0.9.8g-2 +- enable some new crypto algorithms and features +- add some more important bug fixes from openssl CVS + +* Mon Dec 3 2007 Tomas Mraz 0.9.8g-1 +- update to latest upstream release, SONAME bumped to 7 + +* Mon Oct 15 2007 Joe Orton 0.9.8b-17 +- update to new CA bundle from mozilla.org + +* Fri Oct 12 2007 Tomas Mraz 0.9.8b-16 +- fix CVE-2007-5135 - off-by-one in SSL_get_shared_ciphers (#309801) +- fix CVE-2007-4995 - out of order DTLS fragments buffer overflow (#321191) +- add alpha sub-archs (#296031) + +* Tue Aug 21 2007 Tomas Mraz 0.9.8b-15 +- rebuild + +* Fri Aug 3 2007 Tomas Mraz 0.9.8b-14 +- use localhost in testsuite, hopefully fixes slow build in koji +- CVE-2007-3108 - fix side channel attack on private keys (#250577) +- make ssl session cache id matching strict (#233599) + +* Wed Jul 25 2007 Tomas Mraz 0.9.8b-13 +- allow building on ARM architectures (#245417) +- use reference timestamps to prevent multilib conflicts (#218064) +- -devel package must require pkgconfig (#241031) + +* Mon Dec 11 2006 Tomas Mraz 0.9.8b-12 +- detect duplicates in add_dir properly (#206346) + +* Thu Nov 30 2006 Tomas Mraz 0.9.8b-11 +- the previous change still didn't make X509_NAME_cmp transitive + +* Thu Nov 23 2006 Tomas Mraz 0.9.8b-10 +- make X509_NAME_cmp transitive otherwise certificate lookup + is broken (#216050) + +* Thu Nov 2 2006 Tomas Mraz 0.9.8b-9 +- aliasing bug in engine loading, patch by IBM (#213216) + +* Mon Oct 2 2006 Tomas Mraz 0.9.8b-8 +- CVE-2006-2940 fix was incorrect (#208744) + +* Mon Sep 25 2006 Tomas Mraz 0.9.8b-7 +- fix CVE-2006-2937 - mishandled error on ASN.1 parsing (#207276) +- fix CVE-2006-2940 - parasitic public keys DoS (#207274) +- fix CVE-2006-3738 - buffer overflow in SSL_get_shared_ciphers (#206940) +- fix CVE-2006-4343 - sslv2 client DoS (#206940) + +* Tue Sep 5 2006 Tomas Mraz 0.9.8b-6 +- fix CVE-2006-4339 - prevent attack on PKCS#1 v1.5 signatures (#205180) + +* Wed Aug 2 2006 Tomas Mraz - 0.9.8b-5 +- set buffering to none on stdio/stdout FILE when bufsize is set (#200580) + patch by IBM + +* Fri Jul 28 2006 Alexandre Oliva - 0.9.8b-4.1 +- rebuild with new binutils (#200330) + +* Fri Jul 21 2006 Tomas Mraz - 0.9.8b-4 +- add a temporary workaround for sha512 test failure on s390 (#199604) + +* Thu Jul 20 2006 Tomas Mraz +- add ipv6 support to s_client and s_server (by Jan Pazdziora) (#198737) +- add patches for BN threadsafety, AES cache collision attack hazard fix and + pkcs7 code memleak fix from upstream CVS + +* Wed Jul 12 2006 Jesse Keating - 0.9.8b-3.1 +- rebuild + +* Wed Jun 21 2006 Tomas Mraz - 0.9.8b-3 +- dropped libica and ica engine from build + +* Wed Jun 21 2006 Joe Orton +- update to new CA bundle from mozilla.org; adds CA certificates + from netlock.hu and startcom.org + +* Mon Jun 5 2006 Tomas Mraz - 0.9.8b-2 +- fixed a few rpmlint warnings +- better fix for #173399 from upstream +- upstream fix for pkcs12 + +* Thu May 11 2006 Tomas Mraz - 0.9.8b-1 +- upgrade to new version, stays ABI compatible +- there is no more linux/config.h (it was empty anyway) + +* Tue Apr 4 2006 Tomas Mraz - 0.9.8a-6 +- fix stale open handles in libica (#177155) +- fix build if 'rand' or 'passwd' in buildroot path (#178782) +- initialize VIA Padlock engine (#186857) + +* Fri Feb 10 2006 Jesse Keating - 0.9.8a-5.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 0.9.8a-5.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Dec 15 2005 Tomas Mraz 0.9.8a-5 +- don't include SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG + in SSL_OP_ALL (#175779) + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Tue Nov 29 2005 Tomas Mraz 0.9.8a-4 +- fix build (-lcrypto was erroneusly dropped) of the updated libica +- updated ICA engine to 1.3.6-rc3 + +* Tue Nov 22 2005 Tomas Mraz 0.9.8a-3 +- disable builtin compression methods for now until they work + properly (#173399) + +* Wed Nov 16 2005 Tomas Mraz 0.9.8a-2 +- don't set -rpath for openssl binary + +* Tue Nov 8 2005 Tomas Mraz 0.9.8a-1 +- new upstream version +- patches partially renumbered + +* Fri Oct 21 2005 Tomas Mraz 0.9.7f-11 +- updated IBM ICA engine library and patch to latest upstream version + +* Wed Oct 12 2005 Tomas Mraz 0.9.7f-10 +- fix CAN-2005-2969 - remove SSL_OP_MSIE_SSLV2_RSA_PADDING which + disables the countermeasure against man in the middle attack in SSLv2 + (#169863) +- use sha1 as default for CA and cert requests - CAN-2005-2946 (#169803) + +* Tue Aug 23 2005 Tomas Mraz 0.9.7f-9 +- add *.so.soversion as symlinks in /lib (#165264) +- remove unpackaged symlinks (#159595) +- fixes from upstream (constant time fixes for DSA, + bn assembler div on ppc arch, initialize memory on realloc) + +* Thu Aug 11 2005 Phil Knirsch 0.9.7f-8 +- Updated ICA engine IBM patch to latest upstream version. + +* Thu May 19 2005 Tomas Mraz 0.9.7f-7 +- fix CAN-2005-0109 - use constant time/memory access mod_exp + so bits of private key aren't leaked by cache eviction (#157631) +- a few more fixes from upstream 0.9.7g + +* Wed Apr 27 2005 Tomas Mraz 0.9.7f-6 +- use poll instead of select in rand (#128285) +- fix Makefile.certificate to point to /etc/pki/tls +- change the default string mask in ASN1 to PrintableString+UTF8String + +* Mon Apr 25 2005 Joe Orton 0.9.7f-5 +- update to revision 1.37 of Mozilla CA bundle + +* Thu Apr 21 2005 Tomas Mraz 0.9.7f-4 +- move certificates to _sysconfdir/pki/tls (#143392) +- move CA directories to _sysconfdir/pki/CA +- patch the CA script and the default config so it points to the + CA directories + +* Fri Apr 1 2005 Tomas Mraz 0.9.7f-3 +- uninitialized variable mustn't be used as input in inline + assembly +- reenable the x86_64 assembly again + +* Thu Mar 31 2005 Tomas Mraz 0.9.7f-2 +- add back RC4_CHAR on ia64 and x86_64 so the ABI isn't broken +- disable broken bignum assembly on x86_64 + +* Wed Mar 30 2005 Tomas Mraz 0.9.7f-1 +- reenable optimizations on ppc64 and assembly code on ia64 +- upgrade to new upstream version (no soname bump needed) +- disable thread test - it was testing the backport of the + RSA blinding - no longer needed +- added support for changing serial number to + Makefile.certificate (#151188) +- make ca-bundle.crt a config file (#118903) + +* Tue Mar 1 2005 Tomas Mraz 0.9.7e-3 +- libcrypto shouldn't depend on libkrb5 (#135961) + +* Mon Feb 28 2005 Tomas Mraz 0.9.7e-2 +- rebuild + +* Mon Feb 28 2005 Tomas Mraz 0.9.7e-1 +- new upstream source, updated patches +- added patch so we are hopefully ABI compatible with upcoming + 0.9.7f + +* Thu Feb 10 2005 Tomas Mraz +- Support UTF-8 charset in the Makefile.certificate (#134944) +- Added cmp to BuildPrereq + +* Thu Jan 27 2005 Joe Orton 0.9.7a-46 +- generate new ca-bundle.crt from Mozilla certdata.txt (revision 1.32) + +* Thu Dec 23 2004 Phil Knirsch 0.9.7a-45 +- Fixed and updated libica-1.3.4-urandom.patch patch (#122967) + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-44 +- rebuild + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-43 +- rebuild + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-42 +- rebuild + +* Fri Nov 19 2004 Nalin Dahyabhai 0.9.7a-41 +- remove der_chop, as upstream cvs has done (CAN-2004-0975, #140040) + +* Tue Oct 05 2004 Phil Knirsch 0.9.7a-40 +- Include latest libica version with important bugfixes + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Mon Jun 14 2004 Phil Knirsch 0.9.7a-38 +- Updated ICA engine IBM patch to latest upstream version. + +* Mon Jun 7 2004 Nalin Dahyabhai 0.9.7a-37 +- build for linux-alpha-gcc instead of alpha-gcc on alpha (Jeff Garzik) + +* Tue May 25 2004 Nalin Dahyabhai 0.9.7a-36 +- handle %%{_arch}=i486/i586/i686/athlon cases in the intermediate + header (#124303) + +* Thu Mar 25 2004 Joe Orton 0.9.7a-35 +- add security fixes for CAN-2004-0079, CAN-2004-0112 + +* Tue Mar 16 2004 Phil Knirsch +- Fixed libica filespec. + +* Thu Mar 11 2004 Nalin Dahyabhai 0.9.7a-34 +- ppc/ppc64 define __powerpc__/__powerpc64__, not __ppc__/__ppc64__, fix + the intermediate header + +* Wed Mar 10 2004 Nalin Dahyabhai 0.9.7a-33 +- add an intermediate which points to the right + arch-specific opensslconf.h on multilib arches + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Thu Feb 26 2004 Phil Knirsch 0.9.7a-32 +- Updated libica to latest upstream version 1.3.5. + +* Tue Feb 17 2004 Phil Knirsch 0.9.7a-31 +- Update ICA crypto engine patch from IBM to latest version. + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Phil Knirsch 0.9.7a-29 +- rebuilt + +* Wed Feb 11 2004 Phil Knirsch 0.9.7a-28 +- Fixed libica build. + +* Wed Feb 4 2004 Nalin Dahyabhai +- add "-ldl" to link flags added for Linux-on-ARM (#99313) + +* Wed Feb 4 2004 Joe Orton 0.9.7a-27 +- updated ca-bundle.crt: removed expired GeoTrust roots, added + freessl.com root, removed trustcenter.de Class 0 root + +* Sun Nov 30 2003 Tim Waugh 0.9.7a-26 +- Fix link line for libssl (bug #111154). + +* Fri Oct 24 2003 Nalin Dahyabhai 0.9.7a-25 +- add dependency on zlib-devel for the -devel package, which depends on zlib + symbols because we enable zlib for libssl (#102962) + +* Fri Oct 24 2003 Phil Knirsch 0.9.7a-24 +- Use /dev/urandom instead of PRNG for libica. +- Apply libica-1.3.5 fix for /dev/urandom in icalinux.c +- Use latest ICA engine patch from IBM. + +* Sat Oct 4 2003 Nalin Dahyabhai 0.9.7a-22.1 +- rebuild + +* Wed Oct 1 2003 Nalin Dahyabhai 0.9.7a-22 +- rebuild (22 wasn't actually built, fun eh?) + +* Tue Sep 30 2003 Nalin Dahyabhai 0.9.7a-23 +- re-disable optimizations on ppc64 + +* Tue Sep 30 2003 Joe Orton +- add a_mbstr.c fix for 64-bit platforms from CVS + +* Tue Sep 30 2003 Nalin Dahyabhai 0.9.7a-22 +- add -Wa,--noexecstack to RPM_OPT_FLAGS so that assembled modules get tagged + as not needing executable stacks + +* Mon Sep 29 2003 Nalin Dahyabhai 0.9.7a-21 +- rebuild + +* Thu Sep 25 2003 Nalin Dahyabhai +- re-enable optimizations on ppc64 + +* Thu Sep 25 2003 Nalin Dahyabhai +- remove exclusivearch + +* Wed Sep 24 2003 Nalin Dahyabhai 0.9.7a-20 +- only parse a client cert if one was requested +- temporarily exclusivearch for %%{ix86} + +* Tue Sep 23 2003 Nalin Dahyabhai +- add security fixes for protocol parsing bugs (CAN-2003-0543, CAN-2003-0544) + and heap corruption (CAN-2003-0545) +- update RHNS-CA-CERT files +- ease back on the number of threads used in the threading test + +* Wed Sep 17 2003 Matt Wilson 0.9.7a-19 +- rebuild to fix gzipped file md5sums (#91211) + +* Mon Aug 25 2003 Phil Knirsch 0.9.7a-18 +- Updated libica to version 1.3.4. + +* Thu Jul 17 2003 Nalin Dahyabhai 0.9.7a-17 +- rebuild + +* Tue Jul 15 2003 Nalin Dahyabhai 0.9.7a-10.9 +- free the kssl_ctx structure when we free an SSL structure (#99066) + +* Fri Jul 11 2003 Nalin Dahyabhai 0.9.7a-16 +- rebuild + +* Thu Jul 10 2003 Nalin Dahyabhai 0.9.7a-15 +- lower thread test count on s390x + +* Tue Jul 8 2003 Nalin Dahyabhai 0.9.7a-14 +- rebuild + +* Thu Jun 26 2003 Nalin Dahyabhai 0.9.7a-13 +- disable assembly on arches where it seems to conflict with threading + +* Thu Jun 26 2003 Phil Knirsch 0.9.7a-12 +- Updated libica to latest upstream version 1.3.0 + +* Wed Jun 11 2003 Nalin Dahyabhai 0.9.7a-9.9 +- rebuild + +* Wed Jun 11 2003 Nalin Dahyabhai 0.9.7a-11 +- rebuild + +* Tue Jun 10 2003 Nalin Dahyabhai 0.9.7a-10 +- ubsec: don't stomp on output data which might also be input data + +* Tue Jun 10 2003 Nalin Dahyabhai 0.9.7a-9 +- temporarily disable optimizations on ppc64 + +* Mon Jun 9 2003 Nalin Dahyabhai +- backport fix for engine-used-for-everything from 0.9.7b +- backport fix for prng not being seeded causing problems, also from 0.9.7b +- add a check at build-time to ensure that RSA is thread-safe +- keep perlpath from stomping on the libica configure scripts + +* Fri Jun 6 2003 Nalin Dahyabhai +- thread-safety fix for RSA blinding + +* Wed Jun 04 2003 Elliot Lee 0.9.7a-8 +- rebuilt + +* Fri May 30 2003 Phil Knirsch 0.9.7a-7 +- Added libica-1.2 to openssl (featurerequest). + +* Wed Apr 16 2003 Nalin Dahyabhai 0.9.7a-6 +- fix building with incorrect flags on ppc64 + +* Wed Mar 19 2003 Nalin Dahyabhai 0.9.7a-5 +- add patch to harden against Klima-Pokorny-Rosa extension of Bleichenbacher's + attack (CAN-2003-0131) + +* Mon Mar 17 2003 Nalin Dahyabhai 0.9.7a-4 +- add patch to enable RSA blinding by default, closing a timing attack + (CAN-2003-0147) + +* Wed Mar 5 2003 Nalin Dahyabhai 0.9.7a-3 +- disable use of BN assembly module on x86_64, but continue to allow inline + assembly (#83403) + +* Thu Feb 27 2003 Nalin Dahyabhai 0.9.7a-2 +- disable EC algorithms + +* Wed Feb 19 2003 Nalin Dahyabhai 0.9.7a-1 +- update to 0.9.7a + +* Wed Feb 19 2003 Nalin Dahyabhai 0.9.7-8 +- add fix to guard against attempts to allocate negative amounts of memory +- add patch for CAN-2003-0078, fixing a timing attack + +* Thu Feb 13 2003 Elliot Lee 0.9.7-7 +- Add openssl-ppc64.patch + +* Mon Feb 10 2003 Nalin Dahyabhai 0.9.7-6 +- EVP_DecryptInit should call EVP_CipherInit() instead of EVP_CipherInit_ex(), + to get the right behavior when passed uninitialized context structures + (#83766) +- build with -mcpu=ev5 on alpha family (#83828) + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Fri Jan 17 2003 Phil Knirsch 0.9.7-4 +- Added IBM hw crypto support patch. + +* Wed Jan 15 2003 Nalin Dahyabhai +- add missing builddep on sed + +* Thu Jan 9 2003 Bill Nottingham 0.9.7-3 +- debloat +- fix broken manpage symlinks + +* Wed Jan 8 2003 Nalin Dahyabhai 0.9.7-2 +- fix double-free in 'openssl ca' + +* Fri Jan 3 2003 Nalin Dahyabhai 0.9.7-1 +- update to 0.9.7 final + +* Tue Dec 17 2002 Nalin Dahyabhai 0.9.7-0 +- update to 0.9.7 beta6 (DO NOT USE UNTIL UPDATED TO FINAL 0.9.7) + +* Wed Dec 11 2002 Nalin Dahyabhai +- update to 0.9.7 beta5 (DO NOT USE UNTIL UPDATED TO FINAL 0.9.7) + +* Tue Oct 22 2002 Nalin Dahyabhai 0.9.6b-30 +- add configuration stanza for x86_64 and use it on x86_64 +- build for linux-ppc on ppc +- start running the self-tests again + +* Wed Oct 02 2002 Elliot Lee 0.9.6b-29hammer.3 +- Merge fixes from previous hammer packages, including general x86-64 and + multilib + +* Tue Aug 6 2002 Nalin Dahyabhai 0.9.6b-29 +- rebuild + +* Thu Aug 1 2002 Nalin Dahyabhai 0.9.6b-28 +- update asn patch to fix accidental reversal of a logic check + +* Wed Jul 31 2002 Nalin Dahyabhai 0.9.6b-27 +- update asn patch to reduce chance that compiler optimization will remove + one of the added tests + +* Wed Jul 31 2002 Nalin Dahyabhai 0.9.6b-26 +- rebuild + +* Mon Jul 29 2002 Nalin Dahyabhai 0.9.6b-25 +- add patch to fix ASN.1 vulnerabilities + +* Thu Jul 25 2002 Nalin Dahyabhai 0.9.6b-24 +- add backport of Ben Laurie's patches for OpenSSL 0.9.6d + +* Wed Jul 17 2002 Nalin Dahyabhai 0.9.6b-23 +- own {_datadir}/ssl/misc + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Sun May 26 2002 Tim Powers +- automated rebuild + +* Fri May 17 2002 Nalin Dahyabhai 0.9.6b-20 +- free ride through the build system (whee!) + +* Thu May 16 2002 Nalin Dahyabhai 0.9.6b-19 +- rebuild in new environment + +* Thu Apr 4 2002 Nalin Dahyabhai 0.9.6b-17, 0.9.6b-18 +- merge RHL-specific bits into stronghold package, rename + +* Tue Apr 02 2002 Gary Benson stronghold-0.9.6c-2 +- add support for Chrysalis Luna token + +* Tue Mar 26 2002 Gary Benson +- disable AEP random number generation, other AEP fixes + +* Fri Mar 15 2002 Nalin Dahyabhai 0.9.6b-15 +- only build subpackages on primary arches + +* Thu Mar 14 2002 Nalin Dahyabhai 0.9.6b-13 +- on ia32, only disable use of assembler on i386 +- enable assembly on ia64 + +* Mon Jan 7 2002 Florian La Roche 0.9.6b-11 +- fix sparcv9 entry + +* Mon Jan 7 2002 Gary Benson stronghold-0.9.6c-1 +- upgrade to 0.9.6c +- bump BuildArch to i686 and enable assembler on all platforms +- synchronise with shrimpy and rawhide +- bump soversion to 3 + +* Wed Oct 10 2001 Florian La Roche +- delete BN_LLONG for s390x, patch from Oliver Paukstadt + +* Mon Sep 17 2001 Nalin Dahyabhai 0.9.6b-9 +- update AEP driver patch + +* Mon Sep 10 2001 Nalin Dahyabhai +- adjust RNG disabling patch to match version of patch from Broadcom + +* Fri Sep 7 2001 Nalin Dahyabhai 0.9.6b-8 +- disable the RNG in the ubsec engine driver + +* Tue Aug 28 2001 Nalin Dahyabhai 0.9.6b-7 +- tweaks to the ubsec engine driver + +* Fri Aug 24 2001 Nalin Dahyabhai 0.9.6b-6 +- tweaks to the ubsec engine driver + +* Thu Aug 23 2001 Nalin Dahyabhai 0.9.6b-5 +- update ubsec engine driver from Broadcom + +* Fri Aug 10 2001 Nalin Dahyabhai 0.9.6b-4 +- move man pages back to %%{_mandir}/man?/foo.?ssl from + %%{_mandir}/man?ssl/foo.? +- add an [ engine ] section to the default configuration file + +* Thu Aug 9 2001 Nalin Dahyabhai +- add a patch for selecting a default engine in SSL_library_init() + +* Mon Jul 23 2001 Nalin Dahyabhai 0.9.6b-3 +- add patches for AEP hardware support +- add patch to keep trying when we fail to load a cert from a file and + there are more in the file +- add missing prototype for ENGINE_ubsec() in engine_int.h + +* Wed Jul 18 2001 Nalin Dahyabhai 0.9.6b-2 +- actually add hw_ubsec to the engine list + +* Tue Jul 17 2001 Nalin Dahyabhai +- add in the hw_ubsec driver from CVS + +* Wed Jul 11 2001 Nalin Dahyabhai 0.9.6b-1 +- update to 0.9.6b + +* Thu Jul 5 2001 Nalin Dahyabhai +- move .so symlinks back to %%{_libdir} + +* Tue Jul 3 2001 Nalin Dahyabhai +- move shared libraries to /lib (#38410) + +* Mon Jun 25 2001 Nalin Dahyabhai +- switch to engine code base + +* Mon Jun 18 2001 Nalin Dahyabhai +- add a script for creating dummy certificates +- move man pages from %%{_mandir}/man?/foo.?ssl to %%{_mandir}/man?ssl/foo.? + +* Thu Jun 07 2001 Florian La Roche +- add s390x support + +* Fri Jun 1 2001 Nalin Dahyabhai +- change two memcpy() calls to memmove() +- don't define L_ENDIAN on alpha + +* Wed May 23 2001 Joe Orton stronghold-0.9.6a-1 +- Add 'stronghold-' prefix to package names. +- Obsolete standard openssl packages. + +* Wed May 16 2001 Joe Orton +- Add BuildArch: i586 as per Nalin's advice. + +* Tue May 15 2001 Joe Orton +- Enable assembler on ix86 (using new .tar.bz2 which does + include the asm directories). + +* Tue May 15 2001 Nalin Dahyabhai +- make subpackages depend on the main package + +* Tue May 1 2001 Nalin Dahyabhai +- adjust the hobble script to not disturb symlinks in include/ (fix from + Joe Orton) + +* Fri Apr 27 2001 Nalin Dahyabhai +- drop the m2crypo patch we weren't using + +* Tue Apr 24 2001 Nalin Dahyabhai +- configure using "shared" as well + +* Sun Apr 8 2001 Nalin Dahyabhai +- update to 0.9.6a +- use the build-shared target to build shared libraries +- bump the soversion to 2 because we're no longer compatible with + our 0.9.5a packages or our 0.9.6 packages +- drop the patch for making rsatest a no-op when rsa null support is used +- put all man pages into
ssl instead of
+- break the m2crypto modules into a separate package + +* Tue Mar 13 2001 Nalin Dahyabhai +- use BN_LLONG on s390 + +* Mon Mar 12 2001 Nalin Dahyabhai +- fix the s390 changes for 0.9.6 (isn't supposed to be marked as 64-bit) + +* Sat Mar 3 2001 Nalin Dahyabhai +- move c_rehash to the perl subpackage, because it's a perl script now + +* Fri Mar 2 2001 Nalin Dahyabhai +- update to 0.9.6 +- enable MD2 +- use the libcrypto.so and libssl.so targets to build shared libs with +- bump the soversion to 1 because we're no longer compatible with any of + the various 0.9.5a packages circulating around, which provide lib*.so.0 + +* Wed Feb 28 2001 Florian La Roche +- change hobble-openssl for disabling MD2 again + +* Tue Feb 27 2001 Nalin Dahyabhai +- re-disable MD2 -- the EVP_MD_CTX structure would grow from 100 to 152 + bytes or so, causing EVP_DigestInit() to zero out stack variables in + apps built against a version of the library without it + +* Mon Feb 26 2001 Nalin Dahyabhai +- disable some inline assembly, which on x86 is Pentium-specific +- re-enable MD2 (see http://www.ietf.org/ietf/IPR/RSA-MD-all) + +* Thu Feb 08 2001 Florian La Roche +- fix s390 patch + +* Fri Dec 8 2000 Than Ngo +- added support s390 + +* Mon Nov 20 2000 Nalin Dahyabhai +- remove -Wa,* and -m* compiler flags from the default Configure file (#20656) +- add the CA.pl man page to the perl subpackage + +* Thu Nov 2 2000 Nalin Dahyabhai +- always build with -mcpu=ev5 on alpha + +* Tue Oct 31 2000 Nalin Dahyabhai +- add a symlink from cert.pem to ca-bundle.crt + +* Wed Oct 25 2000 Nalin Dahyabhai +- add a ca-bundle file for packages like Samba to reference for CA certificates + +* Tue Oct 24 2000 Nalin Dahyabhai +- remove libcrypto's crypt(), which doesn't handle md5crypt (#19295) + +* Mon Oct 2 2000 Nalin Dahyabhai +- add unzip as a buildprereq (#17662) +- update m2crypto to 0.05-snap4 + +* Tue Sep 26 2000 Bill Nottingham +- fix some issues in building when it's not installed + +* Wed Sep 6 2000 Nalin Dahyabhai +- make sure the headers we include are the ones we built with (aaaaarrgh!) + +* Fri Sep 1 2000 Nalin Dahyabhai +- add Richard Henderson's patch for BN on ia64 +- clean up the changelog + +* Tue Aug 29 2000 Nalin Dahyabhai +- fix the building of python modules without openssl-devel already installed + +* Wed Aug 23 2000 Nalin Dahyabhai +- byte-compile python extensions without the build-root +- adjust the makefile to not remove temporary files (like .key files when + building .csr files) by marking them as .PRECIOUS + +* Sat Aug 19 2000 Nalin Dahyabhai +- break out python extensions into a subpackage + +* Mon Jul 17 2000 Nalin Dahyabhai +- tweak the makefile some more + +* Tue Jul 11 2000 Nalin Dahyabhai +- disable MD2 support + +* Thu Jul 6 2000 Nalin Dahyabhai +- disable MDC2 support + +* Sun Jul 2 2000 Nalin Dahyabhai +- tweak the disabling of RC5, IDEA support +- tweak the makefile + +* Thu Jun 29 2000 Nalin Dahyabhai +- strip binaries and libraries +- rework certificate makefile to have the right parts for Apache + +* Wed Jun 28 2000 Nalin Dahyabhai +- use %%{_perl} instead of /usr/bin/perl +- disable alpha until it passes its own test suite + +* Fri Jun 9 2000 Nalin Dahyabhai +- move the passwd.1 man page out of the passwd package's way + +* Fri Jun 2 2000 Nalin Dahyabhai +- update to 0.9.5a, modified for U.S. +- add perl as a build-time requirement +- move certificate makefile to another package +- disable RC5, IDEA, RSA support +- remove optimizations for now + +* Wed Mar 1 2000 Florian La Roche +- Bero told me to move the Makefile into this package + +* Wed Mar 1 2000 Florian La Roche +- add lib*.so symlinks to link dynamically against shared libs + +* Tue Feb 29 2000 Florian La Roche +- update to 0.9.5 +- run ldconfig directly in post/postun +- add FAQ + +* Sat Dec 18 1999 Bernhard Rosenkrdnzer +- Fix build on non-x86 platforms + +* Fri Nov 12 1999 Bernhard Rosenkrdnzer +- move /usr/share/ssl/* from -devel to main package + +* Tue Oct 26 1999 Bernhard Rosenkrdnzer +- inital packaging +- changes from base: + - Move /usr/local/ssl to /usr/share/ssl for FHS compliance + - handle RPM_OPT_FLAGS