diff --git a/SOURCES/Makefile.certificate b/SOURCES/Makefile.certificate new file mode 100644 index 00000000..cc88c52e --- /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 00000000..bf3229b7 --- /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 00000000..cf7068e7 --- /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 00000000..ea3a4798 --- /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 00000000..701e706e --- /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 00000000..8750ad6d --- /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 00000000..f5f04535 --- /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-0.9.6-x509.patch b/SOURCES/openssl-0.9.6-x509.patch new file mode 100755 index 00000000..7b3f49f9 --- /dev/null +++ b/SOURCES/openssl-0.9.6-x509.patch @@ -0,0 +1,29 @@ +Do not treat duplicate certs as an error. + +--- openssl-0.9.6/crypto/x509/by_file.c Wed Sep 27 15:09:05 2000 ++++ openssl-0.9.6/crypto/x509/by_file.c Wed Sep 27 14:21:20 2000 +@@ -163,8 +163,12 @@ + } + } + 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; + } +@@ -179,7 +183,8 @@ + goto err; + } + i=X509_STORE_add_cert(ctx->store_ctx,x); +- if (!i) goto err; ++ if (!i) ++ ERR_clear_error(); + ret=i; + } + else diff --git a/SOURCES/openssl-0.9.8a-no-rpath.patch b/SOURCES/openssl-0.9.8a-no-rpath.patch new file mode 100755 index 00000000..8f8fb912 --- /dev/null +++ b/SOURCES/openssl-0.9.8a-no-rpath.patch @@ -0,0 +1,11 @@ +--- openssl-0.9.8a/Makefile.shared.no-rpath 2005-06-23 22:47:54.000000000 +0200 ++++ openssl-0.9.8a/Makefile.shared 2005-11-16 22:35:37.000000000 +0100 +@@ -153,7 +153,7 @@ + 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-0.9.8b-test-use-localhost.patch b/SOURCES/openssl-0.9.8b-test-use-localhost.patch new file mode 100755 index 00000000..08adf1cb --- /dev/null +++ b/SOURCES/openssl-0.9.8b-test-use-localhost.patch @@ -0,0 +1,24 @@ +diff -up openssl-0.9.8b/ssl/ssltest.c.use-localhost openssl-0.9.8b/ssl/ssltest.c +--- openssl-0.9.8b/ssl/ssltest.c.use-localhost 2006-02-24 18:58:35.000000000 +0100 ++++ openssl-0.9.8b/ssl/ssltest.c 2007-08-03 14:06:16.000000000 +0200 +@@ -839,19 +839,8 @@ bad: + #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); +- } ++ "localhost"); + } + #endif /* OPENSSL_NO_KRB5 */ + diff --git a/SOURCES/openssl-0.9.8j-version-add-engines.patch b/SOURCES/openssl-0.9.8j-version-add-engines.patch new file mode 100755 index 00000000..f54326cb --- /dev/null +++ b/SOURCES/openssl-0.9.8j-version-add-engines.patch @@ -0,0 +1,48 @@ +diff -up openssl-0.9.8j/apps/version.c.version-add-engines openssl-0.9.8j/apps/version.c +--- openssl-0.9.8j/apps/version.c.version-add-engines 2008-10-20 14:53:33.000000000 +0200 ++++ openssl-0.9.8j/apps/version.c 2009-01-13 23:22:03.000000000 +0100 +@@ -131,6 +131,7 @@ + #ifndef OPENSSL_NO_BF + # include + #endif ++#include + + #undef PROG + #define PROG version_main +@@ -140,7 +141,7 @@ 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 +165,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"); +@@ -211,6 +212,18 @@ int MAIN(int argc, char **argv) + } + if (cflags) 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.0-beta4-ca-dir.patch b/SOURCES/openssl-1.0.0-beta4-ca-dir.patch new file mode 100644 index 00000000..751cabdd --- /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-beta5-enginesdir.patch b/SOURCES/openssl-1.0.0-beta5-enginesdir.patch new file mode 100755 index 00000000..d942d6e2 --- /dev/null +++ b/SOURCES/openssl-1.0.0-beta5-enginesdir.patch @@ -0,0 +1,52 @@ +diff -up openssl-1.0.0-beta5/Configure.enginesdir openssl-1.0.0-beta5/Configure +--- openssl-1.0.0-beta5/Configure.enginesdir 2010-01-20 18:07:05.000000000 +0100 ++++ openssl-1.0.0-beta5/Configure 2010-01-20 18:10:48.000000000 +0100 +@@ -622,6 +622,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=""; +@@ -833,6 +834,10 @@ PROCESS_ARGS: + { + $openssldir=$1; + } ++ elsif (/^--enginesdir=(.*)$/) ++ { ++ $enginesdir=$1; ++ } + elsif (/^--install.prefix=(.*)$/) + { + $install_prefix=$1; +@@ -1053,7 +1058,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"; + +@@ -1673,7 +1678,7 @@ while () + } + elsif (/^#define\s+ENGINESDIR/) + { +- my $foo = "$prefix/$libdir/engines"; ++ my $foo = "$enginesdir"; + $foo =~ s/\\/\\\\/g; + print OUT "#define ENGINESDIR \"$foo\"\n"; + } +diff -up openssl-1.0.0-beta5/engines/Makefile.enginesdir openssl-1.0.0-beta5/engines/Makefile +--- openssl-1.0.0-beta5/engines/Makefile.enginesdir 2010-01-16 21:06:09.000000000 +0100 ++++ openssl-1.0.0-beta5/engines/Makefile 2010-01-20 18:07:05.000000000 +0100 +@@ -124,7 +124,7 @@ install: + sfx=".so"; \ + cp cyg$$l.dll $(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.0-beta5-readme-warning.patch b/SOURCES/openssl-1.0.0-beta5-readme-warning.patch new file mode 100755 index 00000000..0d897203 --- /dev/null +++ b/SOURCES/openssl-1.0.0-beta5-readme-warning.patch @@ -0,0 +1,39 @@ +diff -up openssl-1.0.0-beta5/README.warning openssl-1.0.0-beta5/README +--- openssl-1.0.0-beta5/README.warning 2010-01-20 16:00:47.000000000 +0100 ++++ openssl-1.0.0-beta5/README 2010-01-21 09:06:11.000000000 +0100 +@@ -5,6 +5,35 @@ + 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 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: ++ * There are added changes forward ported from the upstream OpenSSL ++ 0.9.8 FIPS branch however the FIPS integrity verification check ++ is implemented differently from the upstream FIPS validated OpenSSL ++ module. It verifies HMAC-SHA256 checksum of the whole shared ++ libraries. For this reason the changes are ported to files in the ++ crypto directory and not in a separate fips subdirectory. Also ++ note that the FIPS integrity verification check requires unmodified ++ libcrypto and libssl shared library files which means that it will ++ fail if these files are modified for example by prelink. ++ * 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. 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. ++ + DESCRIPTION + ----------- + diff --git a/SOURCES/openssl-1.0.0-timezone.patch b/SOURCES/openssl-1.0.0-timezone.patch new file mode 100644 index 00000000..b1d66828 --- /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.0c-rsa-x931.patch b/SOURCES/openssl-1.0.0c-rsa-x931.patch new file mode 100755 index 00000000..a60bbcb2 --- /dev/null +++ b/SOURCES/openssl-1.0.0c-rsa-x931.patch @@ -0,0 +1,36 @@ +diff -up openssl-1.0.0c/apps/genrsa.c.x931 openssl-1.0.0c/apps/genrsa.c +--- openssl-1.0.0c/apps/genrsa.c.x931 2010-03-01 15:22:02.000000000 +0100 ++++ openssl-1.0.0c/apps/genrsa.c 2011-02-01 18:32:05.000000000 +0100 +@@ -95,6 +95,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; +@@ -138,6 +139,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) + { +@@ -273,7 +276,14 @@ bad: + 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.0d-apps-dgst.patch b/SOURCES/openssl-1.0.0d-apps-dgst.patch new file mode 100755 index 00000000..da20481a --- /dev/null +++ b/SOURCES/openssl-1.0.0d-apps-dgst.patch @@ -0,0 +1,110 @@ +diff -up openssl-1.0.0d/apps/ca.c.dgst openssl-1.0.0d/apps/ca.c +--- openssl-1.0.0d/apps/ca.c.dgst 2009-12-02 15:41:24.000000000 +0100 ++++ openssl-1.0.0d/apps/ca.c 2011-04-05 21:09:42.000000000 +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.0d/apps/enc.c.dgst openssl-1.0.0d/apps/enc.c +--- openssl-1.0.0d/apps/enc.c.dgst 2010-06-15 19:25:02.000000000 +0200 ++++ openssl-1.0.0d/apps/enc.c 2011-04-05 21:11:54.000000000 +0200 +@@ -302,7 +302,7 @@ bad: + BIO_printf(bio_err,"%-14s passphrase is the next argument\n","-k"); + BIO_printf(bio_err,"%-14s passphrase is the first line of the file argument\n","-kfile"); + BIO_printf(bio_err,"%-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",""); ++ BIO_printf(bio_err,"%-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"); + BIO_printf(bio_err,"%-14s key/iv in hex is the next argument\n","-K/-iv"); + BIO_printf(bio_err,"%-14s print the iv/key (then exit if -P)\n","-[pP]"); +diff -up openssl-1.0.0d/apps/req.c.dgst openssl-1.0.0d/apps/req.c +--- openssl-1.0.0d/apps/req.c.dgst 2010-03-10 14:48:21.000000000 +0100 ++++ openssl-1.0.0d/apps/req.c 2011-04-05 21:12:33.000000000 +0200 +@@ -421,7 +421,7 @@ bad: + #ifndef OPENSSL_NO_ECDSA + BIO_printf(bio_err," -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"); ++ BIO_printf(bio_err," -[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"); + BIO_printf(bio_err," -multivalue-rdn enable support for multivalued RDNs\n"); +diff -up openssl-1.0.0d/apps/ts.c.dgst openssl-1.0.0d/apps/ts.c +--- openssl-1.0.0d/apps/ts.c.dgst 2009-10-18 16:42:26.000000000 +0200 ++++ openssl-1.0.0d/apps/ts.c 2011-04-05 21:16:07.000000000 +0200 +@@ -368,7 +368,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.0d/apps/x509.c.dgst openssl-1.0.0d/apps/x509.c +--- openssl-1.0.0d/apps/x509.c.dgst 2011-04-05 21:13:42.000000000 +0200 ++++ openssl-1.0.0d/apps/x509.c 2011-04-05 21:13:17.000000000 +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.0d/doc/apps/ca.pod.dgst openssl-1.0.0d/doc/apps/ca.pod +--- openssl-1.0.0d/doc/apps/ca.pod.dgst 2009-04-10 13:25:53.000000000 +0200 ++++ openssl-1.0.0d/doc/apps/ca.pod 2011-04-05 21:16:39.000000000 +0200 +@@ -160,7 +160,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.0d/doc/apps/ocsp.pod.dgst openssl-1.0.0d/doc/apps/ocsp.pod +--- openssl-1.0.0d/doc/apps/ocsp.pod.dgst 2008-02-25 19:11:47.000000000 +0100 ++++ openssl-1.0.0d/doc/apps/ocsp.pod 2011-04-05 21:18:17.000000000 +0200 +@@ -210,7 +210,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.0d/doc/apps/req.pod.dgst openssl-1.0.0d/doc/apps/req.pod +--- openssl-1.0.0d/doc/apps/req.pod.dgst 2009-04-10 18:42:28.000000000 +0200 ++++ openssl-1.0.0d/doc/apps/req.pod 2011-04-05 21:20:47.000000000 +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.0d/doc/apps/x509.pod.dgst openssl-1.0.0d/doc/apps/x509.pod +--- openssl-1.0.0d/doc/apps/x509.pod.dgst 2010-01-12 18:27:11.000000000 +0100 ++++ openssl-1.0.0d/doc/apps/x509.pod 2011-04-05 21:19:56.000000000 +0200 +@@ -101,6 +101,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.0d-xmpp-starttls.patch b/SOURCES/openssl-1.0.0d-xmpp-starttls.patch new file mode 100755 index 00000000..b3999ccc --- /dev/null +++ b/SOURCES/openssl-1.0.0d-xmpp-starttls.patch @@ -0,0 +1,12 @@ +diff -ru openssl-1.0.0d.old/apps/s_client.c openssl-1.0.0d/apps/s_client.c +--- openssl-1.0.0d.old/apps/s_client.c 2011-07-17 21:05:19.934181169 +0200 ++++ openssl-1.0.0d/apps/s_client.c 2011-07-17 21:11:42.747824990 +0200 +@@ -1186,7 +1186,7 @@ + "xmlns='jabber:client' to='%s' version='1.0'>", host); + seen = BIO_read(sbio,mbuf,BUFSIZZ); + mbuf[seen] = 0; +- while (!strstr(mbuf, "")) + goto shut; diff --git a/SOURCES/openssl-1.0.0e-chil-fixes.patch b/SOURCES/openssl-1.0.0e-chil-fixes.patch new file mode 100755 index 00000000..58a035f0 --- /dev/null +++ b/SOURCES/openssl-1.0.0e-chil-fixes.patch @@ -0,0 +1,24 @@ +diff -up openssl-1.0.0e/engines/e_chil.c.chil openssl-1.0.0e/engines/e_chil.c +--- openssl-1.0.0e/engines/e_chil.c.chil 2010-06-15 19:25:12.000000000 +0200 ++++ openssl-1.0.0e/engines/e_chil.c 2011-09-21 17:32:03.000000000 +0200 +@@ -1261,6 +1261,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) + { +@@ -1287,7 +1292,7 @@ static int hwcrhk_insert_card(const char + + if (ui) + { +- char answer; ++ char answer = '\0'; + char buf[BUFSIZ]; + /* Despite what the documentation says wrong_info can be + * an empty string. diff --git a/SOURCES/openssl-1.0.0e-doc-noeof.patch b/SOURCES/openssl-1.0.0e-doc-noeof.patch new file mode 100755 index 00000000..96865755 --- /dev/null +++ b/SOURCES/openssl-1.0.0e-doc-noeof.patch @@ -0,0 +1,23 @@ +diff -up openssl-1.0.0e/doc/apps/s_client.pod.doc-noeof openssl-1.0.0e/doc/apps/s_client.pod +--- openssl-1.0.0e/doc/apps/s_client.pod.doc-noeof 2009-06-26 13:28:51.000000000 +0200 ++++ openssl-1.0.0e/doc/apps/s_client.pod 2011-11-03 08:30:35.000000000 +0100 +@@ -27,6 +27,7 @@ B B + [B<-nbio>] + [B<-crlf>] + [B<-ign_eof>] ++[B<-no_ign_eof>] + [B<-quiet>] + [B<-ssl2>] + [B<-ssl3>] +@@ -161,6 +162,11 @@ by some servers. + inhibit shutting down the connection when end of file is reached in the + input. + ++=item B<-no_ign_eof> ++ ++shut down the connection when end of file is reached in the ++input. Can be used to override the implicit B<-ign_eof> after B<-quiet>. ++ + =item B<-quiet> + + inhibit printing of session and certificate information. This implicitly diff --git a/SOURCES/openssl-1.0.1-beta2-dtls1-abi.patch b/SOURCES/openssl-1.0.1-beta2-dtls1-abi.patch new file mode 100755 index 00000000..6a556be7 --- /dev/null +++ b/SOURCES/openssl-1.0.1-beta2-dtls1-abi.patch @@ -0,0 +1,23 @@ +diff -up openssl-1.0.1-beta2/ssl/dtls1.h.dtls1-abi openssl-1.0.1-beta2/ssl/dtls1.h +--- openssl-1.0.1-beta2/ssl/dtls1.h.dtls1-abi 2012-02-06 17:07:34.630336118 +0100 ++++ openssl-1.0.1-beta2/ssl/dtls1.h 2012-02-06 17:10:08.956623707 +0100 +@@ -222,9 +222,6 @@ typedef struct dtls1_state_st + */ + record_pqueue buffered_app_data; + +- /* Is set when listening for new connections with dtls1_listen() */ +- unsigned int listen; +- + unsigned int mtu; /* max DTLS packet size */ + + struct hm_header_st w_msg_hdr; +@@ -248,6 +245,9 @@ typedef struct dtls1_state_st + unsigned int retransmitting; + unsigned int change_cipher_spec_ok; + ++ /* Is set when listening for new connections with dtls1_listen() */ ++ unsigned int listen; ++ + #ifndef OPENSSL_NO_SCTP + /* used when SSL_ST_XX_FLUSH is entered */ + int next_state; diff --git a/SOURCES/openssl-1.0.1-beta2-fips-md5-allow.patch b/SOURCES/openssl-1.0.1-beta2-fips-md5-allow.patch new file mode 100755 index 00000000..d6547301 --- /dev/null +++ b/SOURCES/openssl-1.0.1-beta2-fips-md5-allow.patch @@ -0,0 +1,21 @@ +diff -up openssl-1.0.1-beta2/crypto/md5/md5_dgst.c.md5-allow openssl-1.0.1-beta2/crypto/md5/md5_dgst.c +--- openssl-1.0.1-beta2/crypto/md5/md5_dgst.c.md5-allow 2012-02-06 20:09:56.000000000 +0100 ++++ openssl-1.0.1-beta2/crypto/md5/md5_dgst.c 2012-02-06 20:14:02.332117603 +0100 +@@ -71,7 +71,16 @@ const char MD5_version[]="MD5" OPENSSL_V + #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.1-beta2-padlock64.patch b/SOURCES/openssl-1.0.1-beta2-padlock64.patch new file mode 100755 index 00000000..4b7f7da3 --- /dev/null +++ b/SOURCES/openssl-1.0.1-beta2-padlock64.patch @@ -0,0 +1,193 @@ +diff -up openssl-1.0.1-beta2/engines/e_padlock.c.padlock64 openssl-1.0.1-beta2/engines/e_padlock.c +--- openssl-1.0.1-beta2/engines/e_padlock.c.padlock64 2011-06-21 18:42:15.000000000 +0200 ++++ openssl-1.0.1-beta2/engines/e_padlock.c 2012-02-06 20:18:52.039537799 +0100 +@@ -101,7 +101,10 @@ + compiler choice is limited to GCC and Microsoft C. */ + #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 +@@ -137,7 +140,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 + +@@ -304,6 +307,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 +@@ -383,21 +387,6 @@ padlock_available(void) + return padlock_use_ace + padlock_use_rng; + } + +-#ifndef OPENSSL_NO_AES +-/* 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 +- + /* Force key reload from memory to the CPU microcode. + Loading EFLAGS from the stack clears EFLAGS[30] + which does the trick. */ +@@ -455,12 +444,127 @@ 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 */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */ ++ ++/* 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 + + /* The RNG call itself */ +@@ -491,8 +595,8 @@ padlock_xstore(void *addr, unsigned int + 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 { *d++ = *s++; } while (--n); diff --git a/SOURCES/openssl-1.0.1-beta2-ssl-op-all.patch b/SOURCES/openssl-1.0.1-beta2-ssl-op-all.patch new file mode 100755 index 00000000..3259d8c8 --- /dev/null +++ b/SOURCES/openssl-1.0.1-beta2-ssl-op-all.patch @@ -0,0 +1,21 @@ +diff -up openssl-1.0.1-beta2/ssl/ssl.h.op-all openssl-1.0.1-beta2/ssl/ssl.h +--- openssl-1.0.1-beta2/ssl/ssl.h.op-all 2012-02-02 12:49:00.828035916 +0100 ++++ openssl-1.0.1-beta2/ssl/ssl.h 2012-02-02 12:52:27.297818182 +0100 +@@ -540,7 +540,7 @@ struct ssl_session_st + #define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L + /* Allow initial connection to servers that don't support RI */ + #define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L +-#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L ++#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L /* no effect since 1.0.0c due to CVE-2010-4180 */ + #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L + #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L + #define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x00000040L /* no effect since 0.9.7h and 0.9.8b */ +@@ -558,7 +558,7 @@ struct ssl_session_st + + /* SSL_OP_ALL: various bug workarounds that should be rather harmless. + * This used to be 0x000FFFFFL before 0.9.7. */ +-#define SSL_OP_ALL 0x80000BFFL ++#define SSL_OP_ALL 0x80000BF7L /* we still have to include SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */ + + /* DTLS options */ + #define SSL_OP_NO_QUERY_MTU 0x00001000L diff --git a/SOURCES/openssl-1.0.1-pkgconfig-krb5.patch b/SOURCES/openssl-1.0.1-pkgconfig-krb5.patch new file mode 100755 index 00000000..14a17bf9 --- /dev/null +++ b/SOURCES/openssl-1.0.1-pkgconfig-krb5.patch @@ -0,0 +1,30 @@ +diff -up openssl-1.0.1/Makefile.org.krb5 openssl-1.0.1/Makefile.org +--- openssl-1.0.1/Makefile.org.krb5 2012-03-14 21:15:04.000000000 +0100 ++++ openssl-1.0.1/Makefile.org 2012-04-11 16:28:31.254725422 +0200 +@@ -370,7 +370,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)'; \ +@@ -383,7 +383,7 @@ libssl.pc: Makefile + echo 'Version: '$(VERSION); \ + echo 'Requires: '; \ + echo 'Libs: -L$${libdir} -lssl -lcrypto'; \ +- echo 'Libs.private: $(EX_LIBS)'; \ ++ echo 'Libs.private: $(EX_LIBS) $(LIBKRB5)'; \ + echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc + + openssl.pc: Makefile +@@ -397,7 +397,7 @@ openssl.pc: Makefile + echo 'Version: '$(VERSION); \ + echo 'Requires: '; \ + echo 'Libs: -L$${libdir} -lssl -lcrypto'; \ +- echo 'Libs.private: $(EX_LIBS)'; \ ++ echo 'Libs.private: $(EX_LIBS) $(LIBKRB5)'; \ + echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc + + Makefile: Makefile.org Configure config diff --git a/SOURCES/openssl-1.0.1a-algo-doc.patch b/SOURCES/openssl-1.0.1a-algo-doc.patch new file mode 100755 index 00000000..c4aaa897 --- /dev/null +++ b/SOURCES/openssl-1.0.1a-algo-doc.patch @@ -0,0 +1,77 @@ +diff -up openssl-1.0.1a/doc/crypto/EVP_DigestInit.pod.algo-doc openssl-1.0.1a/doc/crypto/EVP_DigestInit.pod +--- openssl-1.0.1a/doc/crypto/EVP_DigestInit.pod.algo-doc 2012-04-11 00:28:22.000000000 +0200 ++++ openssl-1.0.1a/doc/crypto/EVP_DigestInit.pod 2012-04-20 09:14:01.865167011 +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 +@@ -165,7 +165,8 @@ EVP_MD_size(), EVP_MD_block_size(), EVP_ + EVP_MD_CTX_block_size() and EVP_MD_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.1a/doc/crypto/EVP_EncryptInit.pod.algo-doc openssl-1.0.1a/doc/crypto/EVP_EncryptInit.pod +--- openssl-1.0.1a/doc/crypto/EVP_EncryptInit.pod.algo-doc 2005-04-15 18:01:35.000000000 +0200 ++++ openssl-1.0.1a/doc/crypto/EVP_EncryptInit.pod 2012-04-20 09:10:59.114736465 +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.1c-aliasing.patch b/SOURCES/openssl-1.0.1c-aliasing.patch new file mode 100644 index 00000000..582418c9 --- /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-default-paths.patch b/SOURCES/openssl-1.0.1c-default-paths.patch new file mode 100755 index 00000000..364128d7 --- /dev/null +++ b/SOURCES/openssl-1.0.1c-default-paths.patch @@ -0,0 +1,100 @@ +diff -up openssl-1.0.1c/apps/s_client.c.default-paths openssl-1.0.1c/apps/s_client.c +--- openssl-1.0.1c/apps/s_client.c.default-paths 2012-03-18 19:16:05.000000000 +0100 ++++ openssl-1.0.1c/apps/s_client.c 2012-12-06 18:24:06.425933203 +0100 +@@ -1166,12 +1166,19 @@ bad: + if (!set_cert_key_stuff(ctx,cert,key)) + goto end; + +- if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || +- (!SSL_CTX_set_default_verify_paths(ctx))) ++ if (CAfile == NULL && CApath == NULL) + { +- /* BIO_printf(bio_err,"error setting default verify locations\n"); */ +- ERR_print_errors(bio_err); +- /* goto end; */ ++ 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); ++ } + } + + #ifndef OPENSSL_NO_TLSEXT +diff -up openssl-1.0.1c/apps/s_server.c.default-paths openssl-1.0.1c/apps/s_server.c +--- openssl-1.0.1c/apps/s_server.c.default-paths 2012-03-18 19:16:05.000000000 +0100 ++++ openssl-1.0.1c/apps/s_server.c 2012-12-06 18:25:11.199329611 +0100 +@@ -1565,13 +1565,21 @@ bad: + } + #endif + +- if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || +- (!SSL_CTX_set_default_verify_paths(ctx))) ++ if (CAfile == NULL && CApath == NULL) + { +- /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ +- ERR_print_errors(bio_err); +- /* goto end; */ ++ 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); + +@@ -1622,8 +1630,11 @@ bad: + 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); + } +diff -up openssl-1.0.1c/apps/s_time.c.default-paths openssl-1.0.1c/apps/s_time.c +--- openssl-1.0.1c/apps/s_time.c.default-paths 2006-04-17 14:22:13.000000000 +0200 ++++ openssl-1.0.1c/apps/s_time.c 2012-12-06 18:27:41.694574044 +0100 +@@ -373,12 +373,19 @@ 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))) ++ if (CAfile == NULL && CApath == NULL) + { +- /* BIO_printf(bio_err,"error setting default verify locations\n"); */ +- ERR_print_errors(bio_err); +- /* goto end; */ ++ 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.1c-dh-1024.patch b/SOURCES/openssl-1.0.1c-dh-1024.patch new file mode 100755 index 00000000..89f0f04d --- /dev/null +++ b/SOURCES/openssl-1.0.1c-dh-1024.patch @@ -0,0 +1,61 @@ +diff -up openssl-1.0.1c/apps/s_server.c.dh1024 openssl-1.0.1c/apps/s_server.c +--- openssl-1.0.1c/apps/s_server.c.dh1024 2012-11-14 20:27:50.000000000 +0100 ++++ openssl-1.0.1c/apps/s_server.c 2012-11-15 20:56:15.247774465 +0100 +@@ -222,27 +222,31 @@ static void s_server_init(void); + #endif + + #ifndef OPENSSL_NO_DH +-static unsigned char dh512_p[]={ +- 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, +- 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, +- 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, +- 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, +- 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, +- 0x47,0x74,0xE8,0x33, +- }; +-static unsigned char dh512_g[]={ +- 0x02, +- }; +- +-static DH *get_dh512(void) ++static DH *get_dh1024() + { +- DH *dh=NULL; ++ static unsigned char dh1024_p[]={ ++ 0x99,0x58,0xFA,0x90,0x53,0x2F,0xE0,0x61,0x83,0x9D,0x54,0x63, ++ 0xBD,0x35,0x5A,0x31,0xF3,0xC6,0x79,0xE5,0xA0,0x0F,0x66,0x79, ++ 0x3C,0xA0,0x7F,0xE8,0xA2,0x5F,0xDF,0x11,0x08,0xA3,0xF0,0x3C, ++ 0xC3,0x3C,0x5D,0x50,0x2C,0xD5,0xD6,0x58,0x12,0xDB,0xC1,0xEF, ++ 0xB4,0x47,0x4A,0x5A,0x39,0x8A,0x4E,0xEB,0x44,0xE2,0x07,0xFB, ++ 0x3D,0xA3,0xC7,0x6E,0x52,0xF3,0x2B,0x7B,0x10,0xA5,0x98,0xE3, ++ 0x38,0x2A,0xE2,0x7F,0xA4,0x8F,0x26,0x87,0x9B,0x66,0x7A,0xED, ++ 0x2D,0x4C,0xE7,0x33,0x77,0x47,0x94,0x43,0xB6,0xAA,0x97,0x23, ++ 0x8A,0xFC,0xA5,0xA6,0x64,0x09,0xC0,0x27,0xC0,0xEF,0xCB,0x05, ++ 0x90,0x9D,0xD5,0x75,0xBA,0x00,0xE0,0xFB,0xA8,0x81,0x52,0xA4, ++ 0xB2,0x83,0x22,0x5B,0xCB,0xD7,0x16,0x93, ++ }; ++ static unsigned char dh1024_g[]={ ++ 0x02, ++ }; ++ DH *dh; + + if ((dh=DH_new()) == NULL) return(NULL); +- dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); +- dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); ++ dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL); ++ dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL); + if ((dh->p == NULL) || (dh->g == NULL)) +- return(NULL); ++ { DH_free(dh); return(NULL); } + return(dh); + } + #endif +@@ -1657,7 +1661,7 @@ bad: + else + { + BIO_printf(bio_s_out,"Using default temp DH parameters\n"); +- dh=get_dh512(); ++ dh=get_dh1024(); + } + (void)BIO_flush(bio_s_out); + diff --git a/SOURCES/openssl-1.0.1c-ipv6-apps.patch b/SOURCES/openssl-1.0.1c-ipv6-apps.patch new file mode 100755 index 00000000..41e0b361 --- /dev/null +++ b/SOURCES/openssl-1.0.1c-ipv6-apps.patch @@ -0,0 +1,516 @@ +diff -up openssl-1.0.1c/apps/s_apps.h.ipv6-apps openssl-1.0.1c/apps/s_apps.h +--- openssl-1.0.1c/apps/s_apps.h.ipv6-apps 2012-07-11 22:46:02.409221206 +0200 ++++ openssl-1.0.1c/apps/s_apps.h 2012-07-11 22:46:02.451222165 +0200 +@@ -148,7 +148,7 @@ typedef fd_mask fd_set; + #define PORT_STR "4433" + #define PROTOCOL "tcp" + +-int do_server(int port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); ++int do_server(char *port, int type, int *ret, int (*cb) (char *hostname, int s, unsigned char *context), unsigned char *context); + #ifdef HEADER_X509_H + int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx); + #endif +@@ -156,10 +156,9 @@ int MS_CALLBACK verify_callback(int ok, + int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); + int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); + #endif +-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.1c/apps/s_client.c.ipv6-apps openssl-1.0.1c/apps/s_client.c +--- openssl-1.0.1c/apps/s_client.c.ipv6-apps 2012-07-11 22:46:02.433221754 +0200 ++++ openssl-1.0.1c/apps/s_client.c 2012-07-11 22:46:02.452222187 +0200 +@@ -563,7 +563,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; +@@ -664,13 +664,12 @@ 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) +@@ -1253,7 +1252,7 @@ bad: + + 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); +diff -up openssl-1.0.1c/apps/s_server.c.ipv6-apps openssl-1.0.1c/apps/s_server.c +--- openssl-1.0.1c/apps/s_server.c.ipv6-apps 2012-07-11 22:46:02.434221777 +0200 ++++ openssl-1.0.1c/apps/s_server.c 2012-07-11 22:46:02.453222210 +0200 +@@ -929,7 +929,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; + unsigned char *context = NULL; + char *dhfile = NULL; +@@ -1000,8 +1000,7 @@ int MAIN(int argc, char *argv[]) + (strcmp(*argv,"-accept") == 0)) + { + if (--argc < 1) goto bad; +- if (!extract_port(*(++argv),&port)) +- goto bad; ++ port_str= *(++argv); + } + else if (strcmp(*argv,"-verify") == 0) + { +@@ -1878,9 +1877,9 @@ bad: + BIO_printf(bio_s_out,"ACCEPT\n"); + (void)BIO_flush(bio_s_out); + if (www) +- do_server(port,socket_type,&accept_socket,www_body, context); ++ do_server(port_str,socket_type,&accept_socket,www_body, context); + else +- do_server(port,socket_type,&accept_socket,sv_body, context); ++ do_server(port_str,socket_type,&accept_socket,sv_body, context); + print_stats(bio_s_out,ctx); + ret=0; + end: +diff -up openssl-1.0.1c/apps/s_socket.c.ipv6-apps openssl-1.0.1c/apps/s_socket.c +--- openssl-1.0.1c/apps/s_socket.c.ipv6-apps 2011-12-02 15:39:40.000000000 +0100 ++++ openssl-1.0.1c/apps/s_socket.c 2012-07-11 22:49:05.411400450 +0200 +@@ -102,9 +102,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]); + +@@ -234,57 +232,70 @@ 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"); return(0); } ++ 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) { perror("keepalive"); return(0); } ++ 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); + } + +-int do_server(int port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) ++ failed_call = "socket"; ++nextres: ++ if (s != INVALID_SOCKET) ++ close(s); ++ res = res->ai_next; ++ } ++ freeaddrinfo(res0); ++ ++ perror(failed_call); ++ return(0); ++ } ++ ++int do_server(char *port, int type, int *ret, int (*cb)(char *hostname, int s, unsigned char *context), unsigned char *context) + { + int sock; + char *name = NULL; +@@ -322,33 +333,50 @@ 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 ++ memset(&hints, '\0', sizeof(hints)); ++ hints.ai_family = AF_INET6; ++tryipv4: ++ hints.ai_socktype = type; ++ hints.ai_flags = AI_PASSIVE; + +- if (type == SOCK_STREAM) +- s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL); +- else /* type == SOCK_DGRAM */ +- s=socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP); ++ 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; +@@ -356,35 +384,49 @@ static int init_server_long(int *sock, i + (void *) &j, sizeof j); + } + #endif +- if (bind(s,(struct sockaddr *)&server,sizeof(server)) == -1) ++ ++ if (bind(s,(struct sockaddr *)res->ai_addr, res->ai_addrlen) == -1) + { +-#ifndef OPENSSL_SYS_WINDOWS +- perror("bind"); +-#endif +- goto err; ++ failed_call = "bind"; ++ goto nextres; + } +- /* 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)) ++ if (type==SOCK_STREAM && listen(s,128) == -1) + { +- SHUTDOWN(s); ++ failed_call = "listen"; ++ goto nextres; + } +- return(ret); ++ ++ *sock=s; ++ return(1); ++ ++nextres: ++ if (s != INVALID_SOCKET) ++ close(s); ++ res = res->ai_next; + } ++ if (res0) ++ freeaddrinfo(res0); + +-static int init_server(int *sock, int port, int type) ++ if (s == INVALID_SOCKET) + { +- return(init_server_long(sock, port, NULL, type)); ++ if (hints.ai_family == AF_INET6) ++ { ++ hints.ai_family = AF_INET; ++ goto tryipv4; ++ } ++ perror("socket"); ++ return(0); ++ } ++ ++ 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; */ + +@@ -431,135 +473,58 @@ redoit: + */ + + 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) ++ ++ if (getnameinfo((struct sockaddr *)&from, sizeof(from), ++ buffer, sizeof(buffer), ++ NULL, 0, 0)) + { +- BIO_printf(bio_err,"bad gethostbyaddr\n"); ++ 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"); + 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"); +- return(0); +- } +- if (h2->h_addrtype != AF_INET) +- { +- BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n"); +- 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 port defined\n"); ++ BIO_printf(bio_err,"no ending bracket for IPv6 address\n"); + return(0); + } + *(p++)='\0'; +- +- if ((ip != NULL) && !host_ip(str,ip)) +- goto err; +- if (host_ptr != NULL) *host_ptr=h; +- +- if (!extract_port(p,port_ptr)) +- goto err; +- return(1); +-err: +- return(0); ++ x = p; + } +- +-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) ++ p=strchr(x,':'); ++ if (p == NULL) + { +- 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: ++ BIO_printf(bio_err,"no port defined\n"); + return(0); + } ++ *(p++)='\0'; + +-int extract_port(char *str, short *port_ptr) +- { +- int i; +- struct servent *s; ++ if (host_ptr != NULL) *host_ptr=h; ++ if (port_ptr != NULL) *port_ptr=p; + +- 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.1c-perlfind.patch b/SOURCES/openssl-1.0.1c-perlfind.patch new file mode 100644 index 00000000..956afd68 --- /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.1e-3des-strength.patch b/SOURCES/openssl-1.0.1e-3des-strength.patch new file mode 100755 index 00000000..7375b477 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-3des-strength.patch @@ -0,0 +1,171 @@ +Although the real strength is rather 112 bits we use 128 here as +we do not want to sort it behind more obscure ciphers. +AES-128 is preferred anyway. +diff -up openssl-1.0.1e/ssl/s2_lib.c.3des-strength openssl-1.0.1e/ssl/s2_lib.c +--- openssl-1.0.1e/ssl/s2_lib.c.3des-strength 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/s2_lib.c 2014-01-22 16:32:45.791700322 +0100 +@@ -250,7 +250,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip + SSL_SSLV2, + SSL_NOT_EXP|SSL_HIGH, + 0, +- 168, ++ 128, + 168, + }, + +diff -up openssl-1.0.1e/ssl/s3_lib.c.3des-strength openssl-1.0.1e/ssl/s3_lib.c +--- openssl-1.0.1e/ssl/s3_lib.c.3des-strength 2014-01-17 11:41:11.000000000 +0100 ++++ openssl-1.0.1e/ssl/s3_lib.c 2014-01-22 16:31:14.713666777 +0100 +@@ -328,7 +328,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -377,7 +377,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -425,7 +425,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -474,7 +474,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -522,7 +522,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -602,7 +602,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -687,7 +687,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -751,7 +751,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -1685,7 +1685,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2062,7 +2062,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2142,7 +2142,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2222,7 +2222,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2302,7 +2302,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2382,7 +2382,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2432,7 +2432,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2448,7 +2448,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + +@@ -2464,7 +2464,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] + SSL_TLSV1, + SSL_NOT_EXP|SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF, +- 168, ++ 128, + 168, + }, + diff --git a/SOURCES/openssl-1.0.1e-arm-use-elf-auxv-caps.patch b/SOURCES/openssl-1.0.1e-arm-use-elf-auxv-caps.patch new file mode 100755 index 00000000..94a8c426 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-arm-use-elf-auxv-caps.patch @@ -0,0 +1,93 @@ +diff --git a/crypto/armcap.c b/crypto/armcap.c +index 5258d2f..efb4009 100644 +--- a/crypto/armcap.c ++++ b/crypto/armcap.c +@@ -9,11 +9,6 @@ + + unsigned int OPENSSL_armcap_P; + +-static sigset_t all_masked; +- +-static sigjmp_buf ill_jmp; +-static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } +- + /* + * Following subroutines could have been inlined, but it's not all + * ARM compilers support inline assembler... +@@ -29,24 +24,26 @@ unsigned int OPENSSL_rdtsc(void) + return 0; + } + +-#if defined(__GNUC__) && __GNUC__>=2 +-void OPENSSL_cpuid_setup(void) __attribute__((constructor)); +-#endif +-void OPENSSL_cpuid_setup(void) ++#if defined(__GLIBC__) && __GLIBC__>=2 && __GLIBC_MINOR__>=16 ++#include ++ ++void OPENSSL_cpuid_find(void) ++ { ++ unsigned long hwcap = getauxval(AT_HWCAP); ++ char *plat = (char *)getauxval(AT_PLATFORM); ++ ++ OPENSSL_armcap_P |= hwcap & HWCAP_ARM_NEON ? ARMV7_NEON : 0; ++ OPENSSL_armcap_P |= plat ? (plat[1] == '7' ? ARMV7_TICK : 0) : 0; ++ } ++#else ++static sigset_t all_masked; ++static sigjmp_buf ill_jmp; ++static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } ++ ++void OPENSSL_cpuid_find(void) + { +- char *e; + struct sigaction ill_oact,ill_act; + sigset_t oset; +- static int trigger=0; +- +- if (trigger) return; +- trigger=1; +- +- if ((e=getenv("OPENSSL_armcap"))) +- { +- OPENSSL_armcap_P=strtoul(e,NULL,0); +- return; +- } + + sigfillset(&all_masked); + sigdelset(&all_masked,SIGILL); +@@ -55,8 +52,6 @@ void OPENSSL_cpuid_setup(void) + sigdelset(&all_masked,SIGBUS); + sigdelset(&all_masked,SIGSEGV); + +- OPENSSL_armcap_P = 0; +- + memset(&ill_act,0,sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + ill_act.sa_mask = all_masked; +@@ -78,3 +73,25 @@ void OPENSSL_cpuid_setup(void) + sigaction (SIGILL,&ill_oact,NULL); + sigprocmask(SIG_SETMASK,&oset,NULL); + } ++#endif ++ ++#if defined(__GNUC__) && __GNUC__>=2 ++void OPENSSL_cpuid_setup(void) __attribute__((constructor)); ++#endif ++void OPENSSL_cpuid_setup(void) ++ { ++ char *e; ++ static int trigger=0; ++ ++ if (trigger) return; ++ trigger=1; ++ ++ if ((e=getenv("OPENSSL_armcap"))) ++ { ++ OPENSSL_armcap_P=strtoul(e,NULL,0); ++ return; ++ } ++ ++ OPENSSL_armcap_P = 0; ++ OPENSSL_cpuid_find(); ++ } diff --git a/SOURCES/openssl-1.0.1e-backports.patch b/SOURCES/openssl-1.0.1e-backports.patch new file mode 100755 index 00000000..abe3017d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-backports.patch @@ -0,0 +1,345 @@ +diff -up openssl-1.0.1e/crypto/pem/pem_info.c.backports openssl-1.0.1e/crypto/pem/pem_info.c +--- openssl-1.0.1e/crypto/pem/pem_info.c.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/pem/pem_info.c 2013-08-16 15:31:35.726003892 +0200 +@@ -167,6 +167,7 @@ start: + #ifndef OPENSSL_NO_RSA + if (strcmp(name,PEM_STRING_RSA) == 0) + { ++ d2i=(D2I_OF(void))d2i_RSAPrivateKey; + if (xi->x_pkey != NULL) + { + if (!sk_X509_INFO_push(ret,xi)) goto err; +diff -up openssl-1.0.1e/crypto/rsa/rsa_pmeth.c.backports openssl-1.0.1e/crypto/rsa/rsa_pmeth.c +--- openssl-1.0.1e/crypto/rsa/rsa_pmeth.c.backports 2013-08-16 15:31:35.697003256 +0200 ++++ openssl-1.0.1e/crypto/rsa/rsa_pmeth.c 2013-08-16 15:33:37.770673918 +0200 +@@ -582,6 +582,8 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CT + pm = RSA_NO_PADDING; + else if (!strcmp(value, "oeap")) + pm = RSA_PKCS1_OAEP_PADDING; ++ else if (!strcmp(value, "oaep")) ++ pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "x931")) + pm = RSA_X931_PADDING; + else if (!strcmp(value, "pss")) +diff -up openssl-1.0.1e/crypto/x509/x509_vfy.c.backports openssl-1.0.1e/crypto/x509/x509_vfy.c +--- openssl-1.0.1e/crypto/x509/x509_vfy.c.backports 2013-08-16 15:31:35.721003782 +0200 ++++ openssl-1.0.1e/crypto/x509/x509_vfy.c 2013-08-16 15:31:35.726003892 +0200 +@@ -696,6 +696,7 @@ static int check_cert(X509_STORE_CTX *ct + X509_CRL *crl = NULL, *dcrl = NULL; + X509 *x; + int ok, cnum; ++ unsigned int last_reasons; + cnum = ctx->error_depth; + x = sk_X509_value(ctx->chain, cnum); + ctx->current_cert = x; +@@ -704,6 +705,7 @@ static int check_cert(X509_STORE_CTX *ct + ctx->current_reasons = 0; + while (ctx->current_reasons != CRLDP_ALL_REASONS) + { ++ last_reasons = ctx->current_reasons; + /* Try to retrieve relevant CRL */ + if (ctx->get_crl) + ok = ctx->get_crl(ctx, &crl, x); +@@ -747,6 +749,15 @@ static int check_cert(X509_STORE_CTX *ct + X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; ++ /* If reasons not updated we wont get anywhere by ++ * another iteration, so exit loop. ++ */ ++ if (last_reasons == ctx->current_reasons) ++ { ++ ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; ++ ok = ctx->verify_cb(0, ctx); ++ goto err; ++ } + } + err: + X509_CRL_free(crl); +diff -up openssl-1.0.1e/crypto/x509/x_all.c.backports openssl-1.0.1e/crypto/x509/x_all.c +--- openssl-1.0.1e/crypto/x509/x_all.c.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/x509/x_all.c 2013-08-16 15:33:25.247399940 +0200 +@@ -97,6 +97,7 @@ int X509_sign(X509 *x, EVP_PKEY *pkey, c + + int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) + { ++ x->cert_info->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), + x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, ctx); +@@ -123,6 +124,7 @@ int X509_CRL_sign(X509_CRL *x, EVP_PKEY + + int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) + { ++ x->crl->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), + x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx); + } +diff -up openssl-1.0.1e/doc/crypto/X509_STORE_CTX_get_error.pod.backports openssl-1.0.1e/doc/crypto/X509_STORE_CTX_get_error.pod +--- openssl-1.0.1e/doc/crypto/X509_STORE_CTX_get_error.pod.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/crypto/X509_STORE_CTX_get_error.pod 2013-08-16 15:31:35.727003914 +0200 +@@ -278,6 +278,8 @@ happen if extended CRL checking is enabl + an application specific error. This will never be returned unless explicitly + set by an application. + ++=back ++ + =head1 NOTES + + The above functions should be used instead of directly referencing the fields +diff -up openssl-1.0.1e/doc/ssl/SSL_accept.pod.backports openssl-1.0.1e/doc/ssl/SSL_accept.pod +--- openssl-1.0.1e/doc/ssl/SSL_accept.pod.backports 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_accept.pod 2013-08-16 15:31:35.727003914 +0200 +@@ -44,17 +44,17 @@ The following return values can occur: + + =over 4 + +-=item 1 +- +-The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been +-established. +- + =item 0 + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the + return value B to find out the reason. + ++=item 1 ++ ++The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been ++established. ++ + =item E0 + + The TLS/SSL handshake was not successful because a fatal error occurred either +diff -up openssl-1.0.1e/doc/ssl/SSL_connect.pod.backports openssl-1.0.1e/doc/ssl/SSL_connect.pod +--- openssl-1.0.1e/doc/ssl/SSL_connect.pod.backports 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_connect.pod 2013-08-16 15:31:35.727003914 +0200 +@@ -41,17 +41,17 @@ The following return values can occur: + + =over 4 + +-=item 1 +- +-The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been +-established. +- + =item 0 + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the + return value B to find out the reason. + ++=item 1 ++ ++The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been ++established. ++ + =item E0 + + The TLS/SSL handshake was not successful, because a fatal error occurred either +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod.backports openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod.backports 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod 2013-08-16 15:31:35.727003914 +0200 +@@ -66,16 +66,16 @@ values: + + =over 4 + +-=item 1 +- +-The operation succeeded. +- + =item 0 + + A failure while manipulating the STACK_OF(X509_NAME) object occurred or + the X509_NAME could not be extracted from B. Check the error stack + to find out the reason. + ++=item 1 ++ ++The operation succeeded. ++ + =back + + =head1 EXAMPLES +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod.backports openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod 2013-08-16 15:31:35.727003914 +0200 +@@ -81,6 +81,8 @@ SSL_CTX_use_psk_identity_hint() and SSL_ + + Return values from the server callback are interpreted as follows: + ++=over 4 ++ + =item > 0 + + PSK identity was found and the server callback has provided the PSK +@@ -99,4 +101,6 @@ completely. + PSK identity was not found. An "unknown_psk_identity" alert message + will be sent and the connection setup fails. + ++=back ++ + =cut +diff -up openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod.backports openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod +--- openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod.backports 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod 2013-08-16 15:31:35.727003914 +0200 +@@ -45,17 +45,17 @@ The following return values can occur: + + =over 4 + +-=item 1 +- +-The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been +-established. +- + =item 0 + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the + return value B to find out the reason. + ++=item 1 ++ ++The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been ++established. ++ + =item E0 + + The TLS/SSL handshake was not successful because a fatal error occurred either +diff -up openssl-1.0.1e/doc/ssl/SSL_shutdown.pod.backports openssl-1.0.1e/doc/ssl/SSL_shutdown.pod +--- openssl-1.0.1e/doc/ssl/SSL_shutdown.pod.backports 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_shutdown.pod 2013-08-16 15:31:35.728003935 +0200 +@@ -92,11 +92,6 @@ The following return values can occur: + + =over 4 + +-=item 1 +- +-The shutdown was successfully completed. The "close notify" alert was sent +-and the peer's "close notify" alert was received. +- + =item 0 + + The shutdown is not yet finished. Call SSL_shutdown() for a second time, +@@ -104,6 +99,11 @@ if a bidirectional shutdown shall be per + The output of L may be misleading, as an + erroneous SSL_ERROR_SYSCALL may be flagged even though no error occurred. + ++=item 1 ++ ++The shutdown was successfully completed. The "close notify" alert was sent ++and the peer's "close notify" alert was received. ++ + =item -1 + + The shutdown was not successful because a fatal error occurred either +diff -up openssl-1.0.1e/ssl/d1_lib.c.backports openssl-1.0.1e/ssl/d1_lib.c +--- openssl-1.0.1e/ssl/d1_lib.c.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/d1_lib.c 2013-08-16 15:33:33.306576363 +0200 +@@ -196,6 +196,7 @@ void dtls1_free(SSL *s) + pqueue_free(s->d1->buffered_app_data.q); + + OPENSSL_free(s->d1); ++ s->d1 = NULL; + } + + void dtls1_clear(SSL *s) +diff -up openssl-1.0.1e/ssl/d1_pkt.c.backports openssl-1.0.1e/ssl/d1_pkt.c +--- openssl-1.0.1e/ssl/d1_pkt.c.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/d1_pkt.c 2013-08-16 15:31:35.728003935 +0200 +@@ -847,6 +847,12 @@ start: + } + } + ++ if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) ++ { ++ rr->length = 0; ++ goto start; ++ } ++ + /* we now have a packet which can be read and processed */ + + if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, +@@ -1051,6 +1057,7 @@ start: + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) + { ++ s->d1->handshake_read_seq++; + s->new_session = 1; + ssl3_renegotiate(s); + if (ssl3_renegotiate_check(s)) +diff -up openssl-1.0.1e/ssl/d1_srvr.c.backports openssl-1.0.1e/ssl/d1_srvr.c +--- openssl-1.0.1e/ssl/d1_srvr.c.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/d1_srvr.c 2013-08-16 15:31:35.728003935 +0200 +@@ -276,10 +276,11 @@ int dtls1_accept(SSL *s) + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown=0; ++ dtls1_clear_record_buffer(s); + dtls1_start_timer(s); + ret=dtls1_send_hello_request(s); + if (ret <= 0) goto end; +- s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C; ++ s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; + s->state=SSL3_ST_SW_FLUSH; + s->init_num=0; + +diff -up openssl-1.0.1e/ssl/s3_cbc.c.backports openssl-1.0.1e/ssl/s3_cbc.c +--- openssl-1.0.1e/ssl/s3_cbc.c.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/s3_cbc.c 2013-08-16 15:31:35.729003956 +0200 +@@ -148,7 +148,7 @@ int tls1_cbc_remove_padding(const SSL* s + unsigned padding_length, good, to_check, i; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + /* Check if version requires explicit IV */ +- if (s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION) ++ if (s->version >= TLS1_1_VERSION || s->version == DTLS1_BAD_VER) + { + /* These lengths are all public so we can test them in + * non-constant time. +diff -up openssl-1.0.1e/ssl/ssl_lib.c.backports openssl-1.0.1e/ssl/ssl_lib.c +--- openssl-1.0.1e/ssl/ssl_lib.c.backports 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/ssl_lib.c 2013-08-16 15:31:35.729003956 +0200 +@@ -1797,7 +1797,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); + + ret->extra_certs=NULL; +- ret->comp_methods=SSL_COMP_get_compression_methods(); ++ /* No compression for DTLS */ ++ if (meth->version != DTLS1_VERSION) ++ ret->comp_methods=SSL_COMP_get_compression_methods(); + + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + +@@ -2792,9 +2794,7 @@ void ssl_clear_cipher_ctx(SSL *s) + /* Fix this function so that it takes an optional type parameter */ + X509 *SSL_get_certificate(const SSL *s) + { +- if (s->server) +- return(ssl_get_server_send_cert(s)); +- else if (s->cert != NULL) ++ if (s->cert != NULL) + return(s->cert->key->x509); + else + return(NULL); +diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl +index 3b6c469..e8a7518 100644 +--- a/crypto/x86cpuid.pl ++++ b/crypto/x86cpuid.pl +@@ -69,6 +69,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + &inc ("esi"); # number of cores + + &mov ("eax",1); ++ &xor ("ecx","ecx"); + &cpuid (); + &bt ("edx",28); + &jnc (&label("generic")); +@@ -102,6 +103,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + + &set_label("nocacheinfo"); + &mov ("eax",1); ++ &xor ("ecx","ecx"); + &cpuid (); + &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0 + &cmp ("ebp",0); diff --git a/SOURCES/openssl-1.0.1e-bad-mac.patch b/SOURCES/openssl-1.0.1e-bad-mac.patch new file mode 100755 index 00000000..06d284e8 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-bad-mac.patch @@ -0,0 +1,33 @@ +From 9ab3ce124616cb12bd39c6aa1e1bde0f46969b29 Mon Sep 17 00:00:00 2001 +From: Andy Polyakov +Date: Mon, 18 Mar 2013 19:29:41 +0100 +Subject: [PATCH] e_aes_cbc_hmac_sha1.c: fix rare bad record mac on AES-NI + plaforms. + +PR: 3002 +(cherry picked from commit 5c60046553716fcf160718f59160493194f212dc) +--- + crypto/evp/e_aes_cbc_hmac_sha1.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/evp/e_aes_cbc_hmac_sha1.c +index 483e04b..fb2c884 100644 +--- a/crypto/evp/e_aes_cbc_hmac_sha1.c ++++ b/crypto/evp/e_aes_cbc_hmac_sha1.c +@@ -328,10 +328,11 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + + if (res!=SHA_CBLOCK) continue; + +- mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1)); ++ /* j is not incremented yet */ ++ mask = 0-((inp_len+7-j)>>(sizeof(j)*8-1)); + data->u[SHA_LBLOCK-1] |= bitlen&mask; + sha1_block_data_order(&key->md,data,1); +- mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1)); ++ mask &= 0-((j-inp_len-72)>>(sizeof(j)*8-1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; +-- +1.7.9.5 + diff --git a/SOURCES/openssl-1.0.1e-cc-reqs.patch b/SOURCES/openssl-1.0.1e-cc-reqs.patch new file mode 100755 index 00000000..e266bb19 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cc-reqs.patch @@ -0,0 +1,25 @@ +diff -up openssl-1.0.1e/crypto/rsa/rsa_gen.c.cc-reqs openssl-1.0.1e/crypto/rsa/rsa_gen.c +--- openssl-1.0.1e/crypto/rsa/rsa_gen.c.cc-reqs 2015-01-13 12:45:51.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_gen.c 2015-01-15 17:35:04.649697922 +0100 +@@ -438,6 +438,10 @@ static int rsa_builtin_keygen(RSA *rsa, + if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err; + 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; ++ + BN_copy(rsa->e, e_value); + + /* generate p and q */ +@@ -463,7 +467,9 @@ static int rsa_builtin_keygen(RSA *rsa, + { + 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 */ diff --git a/SOURCES/openssl-1.0.1e-compat-symbols.patch b/SOURCES/openssl-1.0.1e-compat-symbols.patch new file mode 100755 index 00000000..25a9d023 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-compat-symbols.patch @@ -0,0 +1,46 @@ +diff -up openssl-1.0.1e/crypto/dsa/dsa_key.c.compat openssl-1.0.1e/crypto/dsa/dsa_key.c +--- openssl-1.0.1e/crypto/dsa/dsa_key.c.compat 2013-11-26 14:36:35.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_key.c 2013-12-11 16:34:58.638549687 +0100 +@@ -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.1e/crypto/engine/eng_all.c.compat openssl-1.0.1e/crypto/engine/eng_all.c +--- openssl-1.0.1e/crypto/engine/eng_all.c.compat 2013-11-26 14:36:35.000000000 +0100 ++++ openssl-1.0.1e/crypto/engine/eng_all.c 2013-12-11 16:32:13.512820424 +0100 +@@ -62,6 +62,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.1e/crypto/fips/fips.c.compat openssl-1.0.1e/crypto/fips/fips.c +--- openssl-1.0.1e/crypto/fips/fips.c.compat 2013-11-26 14:36:35.000000000 +0100 ++++ openssl-1.0.1e/crypto/fips/fips.c 2013-12-11 16:38:52.524831858 +0100 +@@ -111,6 +111,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.1e-copy-algo.patch b/SOURCES/openssl-1.0.1e-copy-algo.patch new file mode 100755 index 00000000..927c584d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-copy-algo.patch @@ -0,0 +1,33 @@ +diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c +index 6a33b9d..76a5f9e 100644 +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -3177,15 +3177,26 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) + + SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx) + { ++ CERT *ocert = ssl->cert; + if (ssl->ctx == ctx) + return ssl->ctx; + #ifndef OPENSSL_NO_TLSEXT + if (ctx == NULL) + ctx = ssl->initial_ctx; + #endif +- if (ssl->cert != NULL) +- ssl_cert_free(ssl->cert); + ssl->cert = ssl_cert_dup(ctx->cert); ++ if (ocert) ++ { ++ int i; ++ /* Copy negotiated digests from original */ ++ for (i = 0; i < SSL_PKEY_NUM; i++) ++ { ++ CERT_PKEY *cpk = ocert->pkeys + i; ++ CERT_PKEY *rpk = ssl->cert->pkeys + i; ++ rpk->digest = cpk->digest; ++ } ++ ssl_cert_free(ocert); ++ } + CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); + if (ssl->ctx != NULL) + SSL_CTX_free(ssl->ctx); /* decrement reference count */ diff --git a/SOURCES/openssl-1.0.1e-cve-2010-5298.patch b/SOURCES/openssl-1.0.1e-cve-2010-5298.patch new file mode 100755 index 00000000..b4f92cd5 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2010-5298.patch @@ -0,0 +1,21 @@ +From: Ben Laurie +Date: Wed, 23 Apr 2014 06:24:03 +0000 (+0100) +Subject: Fix use after free. +X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=94d1f4b + +Fix use after free. +--- + +diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c +index b9e45c7..d601a18 100644 +--- a/ssl/s3_pkt.c ++++ b/ssl/s3_pkt.c +@@ -1334,7 +1334,7 @@ start: + { + s->rstate=SSL_ST_READ_HEADER; + rr->off=0; +- if (s->mode & SSL_MODE_RELEASE_BUFFERS) ++ if (s->mode & SSL_MODE_RELEASE_BUFFERS && s->s3->rbuf.left == 0) + ssl3_release_read_buffer(s); + } + } diff --git a/SOURCES/openssl-1.0.1e-cve-2013-4353.patch b/SOURCES/openssl-1.0.1e-cve-2013-4353.patch new file mode 100755 index 00000000..5f96116c --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2013-4353.patch @@ -0,0 +1,21 @@ +Fix for TLS record tampering bug. A carefully crafted invalid +handshake could crash OpenSSL with a NULL pointer exception. +Thanks to Anton Johansson for reporting this issues. +(CVE-2013-4353) +diff --git a/ssl/s3_both.c b/ssl/s3_both.c +index 1e5dcab..53b9390 100644 +--- a/ssl/s3_both.c ++++ b/ssl/s3_both.c +@@ -210,7 +210,11 @@ static void ssl3_take_mac(SSL *s) + { + const char *sender; + int slen; +- ++ /* If no new cipher setup return immediately: other functions will ++ * set the appropriate error. ++ */ ++ if (s->s3->tmp.new_cipher == NULL) ++ return; + if (s->state & SSL_ST_CONNECT) + { + sender=s->method->ssl3_enc->server_finished_label; diff --git a/SOURCES/openssl-1.0.1e-cve-2013-6449.patch b/SOURCES/openssl-1.0.1e-cve-2013-6449.patch new file mode 100755 index 00000000..d80a1788 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2013-6449.patch @@ -0,0 +1,111 @@ +Use version in SSL_METHOD not SSL structure. + +When deciding whether to use TLS 1.2 PRF and record hash algorithms +use the version number in the corresponding SSL_METHOD structure +instead of the SSL structure. The SSL structure version is sometimes +inaccurate. Note: OpenSSL 1.0.2 and later effectively do this already. +(CVE-2013-6449) + +Also preventively check EVP errors for handshake digests. + +diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c +index bf832bb..c4ef273 100644 +--- a/ssl/s3_lib.c ++++ b/ssl/s3_lib.c +@@ -4286,7 +4286,7 @@ need to go to SSL_ST_ACCEPT. + long ssl_get_algorithm2(SSL *s) + { + long alg2 = s->s3->tmp.new_cipher->algorithm2; +- if (TLS1_get_version(s) >= TLS1_2_VERSION && ++ if (s->method->version == TLS1_2_VERSION && + alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) + return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; + return alg2; +diff --git a/ssl/s3_both.c b/ssl/s3_both.c +index ead01c8..1e5dcab 100644 +--- a/ssl/s3_both.c ++++ b/ssl/s3_both.c +@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) + + i=s->method->ssl3_enc->final_finish_mac(s, + sender,slen,s->s3->tmp.finish_md); ++ if (i == 0) ++ return 0; + s->s3->tmp.finish_md_len = i; + memcpy(p, s->s3->tmp.finish_md, i); + p+=i; +diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c +index 804291e..c4bc4e7 100644 +--- a/ssl/s3_pkt.c ++++ b/ssl/s3_pkt.c +@@ -335,7 +335,7 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); + if (version != s->version) + { + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); +- if ((s->version & 0xFF00) == (version & 0xFF00)) ++ if ((s->version & 0xFF00) == (version & 0xFF00) && !s->enc_write_ctx && !s->write_hash) + /* Send back error using their minor version number :-) */ + s->version = (unsigned short)version; + al=SSL_AD_PROTOCOL_VERSION; +@@ -1459,8 +1459,14 @@ int ssl3_do_change_cipher_spec(SSL *s) + slen=s->method->ssl3_enc->client_finished_label_len; + } + +- s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, ++ i = s->method->ssl3_enc->final_finish_mac(s, + sender,slen,s->s3->tmp.peer_finish_md); ++ if (i == 0) ++ { ++ SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); ++ return 0; ++ } ++ s->s3->tmp.peer_finish_md_len = i; + + return(1); + } +diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c +index e5a8b3f..52efed3 100644 +--- a/ssl/s3_srvr.c ++++ b/ssl/s3_srvr.c +@@ -958,7 +958,8 @@ int ssl3_get_client_hello(SSL *s) + (s->version != DTLS1_VERSION && s->client_version < s->version)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); +- if ((s->client_version>>8) == SSL3_VERSION_MAJOR) ++ if ((s->client_version>>8) == SSL3_VERSION_MAJOR && ++ !s->enc_write_ctx && !s->write_hash) + { + /* similar to ssl3_get_record, send alert using remote version number */ + s->version = s->client_version; +diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c +index 809ad2e..72015f5 100644 +--- a/ssl/t1_enc.c ++++ b/ssl/t1_enc.c +@@ -915,18 +915,19 @@ int tls1_final_finish_mac(SSL *s, + if (mask & ssl_get_algorithm2(s)) + { + int hashsize = EVP_MD_size(md); +- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) ++ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; ++ if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf))) + { + /* internal error: 'buf' is too small for this cipersuite! */ + err = 1; + } + else + { +- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]); +- EVP_DigestFinal_ex(&ctx,q,&i); +- if (i != (unsigned int)hashsize) /* can't really happen */ ++ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || ++ !EVP_DigestFinal_ex(&ctx,q,&i) || ++ (i != (unsigned int)hashsize)) + err = 1; +- q+=i; ++ q+=hashsize; + } + } + } +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2013-6450.patch b/SOURCES/openssl-1.0.1e-cve-2013-6450.patch new file mode 100755 index 00000000..fa096c8b --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2013-6450.patch @@ -0,0 +1,85 @@ +Fix DTLS retransmission from previous session. + +For DTLS we might need to retransmit messages from the previous session +so keep a copy of write context in DTLS retransmission buffers instead +of replacing it after sending CCS. CVE-2013-6450. + +diff --git a/ssl/d1_both.c b/ssl/d1_both.c +index 65ec001..7a5596a 100644 +--- a/ssl/d1_both.c ++++ b/ssl/d1_both.c +@@ -214,6 +214,12 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) + static void + dtls1_hm_fragment_free(hm_fragment *frag) + { ++ ++ if (frag->msg_header.is_ccs) ++ { ++ EVP_CIPHER_CTX_free(frag->msg_header.saved_retransmit_state.enc_write_ctx); ++ EVP_MD_CTX_destroy(frag->msg_header.saved_retransmit_state.write_hash); ++ } + if (frag->fragment) OPENSSL_free(frag->fragment); + if (frag->reassembly) OPENSSL_free(frag->reassembly); + OPENSSL_free(frag); +diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h +index 96ce9a7..e485907 100644 +--- a/ssl/ssl_locl.h ++++ b/ssl/ssl_locl.h +@@ -621,6 +621,8 @@ extern SSL3_ENC_METHOD TLSv1_enc_data; + extern SSL3_ENC_METHOD SSLv3_enc_data; + extern SSL3_ENC_METHOD DTLSv1_enc_data; + ++#define SSL_IS_DTLS(s) (s->method->version == DTLS1_VERSION) ++ + #define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ + s_get_meth) \ + const SSL_METHOD *func_name(void) \ +diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c +index 72015f5..56db834 100644 +--- a/ssl/t1_enc.c ++++ b/ssl/t1_enc.c +@@ -414,15 +414,20 @@ int tls1_change_cipher_state(SSL *s, int which) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; +- if (s->enc_write_ctx != NULL) ++ if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) + reuse_dd = 1; +- else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) ++ else if ((s->enc_write_ctx=EVP_CIPHER_CTX_new()) == NULL) + goto err; +- else +- /* make sure it's intialized in case we exit later with an error */ +- EVP_CIPHER_CTX_init(s->enc_write_ctx); + dd= s->enc_write_ctx; +- mac_ctx = ssl_replace_hash(&s->write_hash,NULL); ++ if (SSL_IS_DTLS(s)) ++ { ++ mac_ctx = EVP_MD_CTX_create(); ++ if (!mac_ctx) ++ goto err; ++ s->write_hash = mac_ctx; ++ } ++ else ++ mac_ctx = ssl_replace_hash(&s->write_hash,NULL); + #ifndef OPENSSL_NO_COMP + if (s->compress != NULL) + { +diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c +index 6fc469f..d14e8e4 100644 +--- a/crypto/evp/digest.c ++++ b/crypto/evp/digest.c +@@ -366,8 +366,11 @@ int EVP_Digest(const void *data, size_t count, + + void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) + { +- EVP_MD_CTX_cleanup(ctx); +- OPENSSL_free(ctx); ++ if (ctx) ++ { ++ EVP_MD_CTX_cleanup(ctx); ++ OPENSSL_free(ctx); ++ } + } + + /* This call frees resources associated with the context */ diff --git a/SOURCES/openssl-1.0.1e-cve-2014-0160.patch b/SOURCES/openssl-1.0.1e-cve-2014-0160.patch new file mode 100755 index 00000000..6d5c5cef --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-0160.patch @@ -0,0 +1,89 @@ +diff -up openssl-1.0.1e/ssl/d1_both.c.heartbeat openssl-1.0.1e/ssl/d1_both.c +--- openssl-1.0.1e/ssl/d1_both.c.heartbeat 2014-04-07 12:52:01.884308971 +0200 ++++ openssl-1.0.1e/ssl/d1_both.c 2014-04-07 13:04:32.860128295 +0200 +@@ -1458,26 +1458,36 @@ dtls1_process_heartbeat(SSL *s) + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + +- /* Read type and payload length first */ +- hbtype = *p++; +- n2s(p, payload); +- pl = p; +- + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + ++ /* Read type and payload length first */ ++ if (1 + 2 + 16 > s->s3->rrec.length) ++ return 0; /* silently discard */ ++ hbtype = *p++; ++ n2s(p, payload); ++ if (1 + 2 + payload + 16 > s->s3->rrec.length) ++ return 0; /* silently discard per RFC 6520 sec. 4 */ ++ pl = p; ++ + if (hbtype == TLS1_HB_REQUEST) + { + unsigned char *buffer, *bp; ++ unsigned int write_length = 1 /* heartbeat type */ + ++ 2 /* heartbeat length */ + ++ payload + padding; + int r; + ++ if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) ++ return 0; ++ + /* Allocate memory for the response, size is 1 byte + * message type, plus 2 bytes payload length, plus + * payload, plus padding + */ +- buffer = OPENSSL_malloc(1 + 2 + payload + padding); ++ buffer = OPENSSL_malloc(write_length); + bp = buffer; + + /* Enter response type, length and copy payload */ +@@ -1488,11 +1498,11 @@ dtls1_process_heartbeat(SSL *s) + /* Random padding */ + RAND_pseudo_bytes(bp, padding); + +- r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding); ++ r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); + + if (r >= 0 && s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, +- buffer, 3 + payload + padding, ++ buffer, write_length, + s, s->msg_callback_arg); + + OPENSSL_free(buffer); +diff -up openssl-1.0.1e/ssl/t1_lib.c.heartbeat openssl-1.0.1e/ssl/t1_lib.c +--- openssl-1.0.1e/ssl/t1_lib.c.heartbeat 2014-04-07 12:52:01.891308997 +0200 ++++ openssl-1.0.1e/ssl/t1_lib.c 2014-04-07 12:57:45.063603587 +0200 +@@ -2463,16 +2463,20 @@ tls1_process_heartbeat(SSL *s) + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + +- /* Read type and payload length first */ +- hbtype = *p++; +- n2s(p, payload); +- pl = p; +- + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + ++ /* Read type and payload length first */ ++ if (1 + 2 + 16 > s->s3->rrec.length) ++ return 0; /* silently discard */ ++ hbtype = *p++; ++ n2s(p, payload); ++ if (1 + 2 + payload + 16 > s->s3->rrec.length) ++ return 0; /* silently discard per RFC 6520 sec. 4 */ ++ pl = p; ++ + if (hbtype == TLS1_HB_REQUEST) + { + unsigned char *buffer, *bp; diff --git a/SOURCES/openssl-1.0.1e-cve-2014-0195.patch b/SOURCES/openssl-1.0.1e-cve-2014-0195.patch new file mode 100755 index 00000000..434eee20 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-0195.patch @@ -0,0 +1,36 @@ +commit 208d54db20d58c9a5e45e856a0650caadd7d9612 +Author: Dr. Stephen Henson +Date: Tue May 13 18:48:31 2014 +0100 + + Fix for CVE-2014-0195 + + A buffer overrun attack can be triggered by sending invalid DTLS fragments + to an OpenSSL DTLS client or server. This is potentially exploitable to + run arbitrary code on a vulnerable client or server. + + Fixed by adding consistency check for DTLS fragments. + + Thanks to Jüri Aedla for reporting this issue. + +diff --git a/ssl/d1_both.c b/ssl/d1_both.c +index 2e8cf68..07f67f8 100644 +--- a/ssl/d1_both.c ++++ b/ssl/d1_both.c +@@ -627,7 +627,16 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) + frag->msg_header.frag_off = 0; + } + else ++ { + frag = (hm_fragment*) item->data; ++ if (frag->msg_header.msg_len != msg_hdr->msg_len) ++ { ++ item = NULL; ++ frag = NULL; ++ goto err; ++ } ++ } ++ + + /* If message is already reassembled, this must be a + * retransmit and can be dropped. + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-0198.patch b/SOURCES/openssl-1.0.1e-cve-2014-0198.patch new file mode 100755 index 00000000..2c94bca5 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-0198.patch @@ -0,0 +1,33 @@ +From: Matt Caswell +Date: Sun, 11 May 2014 23:38:37 +0000 (+0100) +Subject: Fixed NULL pointer dereference. See PR#3321 +X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=b107586 + +Fixed NULL pointer dereference. See PR#3321 +--- + +diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c +index 40eb0dd..d961d12 100644 +--- a/ssl/s3_pkt.c ++++ b/ssl/s3_pkt.c +@@ -657,9 +657,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + SSL3_BUFFER *wb=&(s->s3->wbuf); + SSL_SESSION *sess; + +- if (wb->buf == NULL) +- if (!ssl3_setup_write_buffer(s)) +- return -1; + + /* first check if there is a SSL3_BUFFER still being written + * out. This will happen with non blocking IO */ +@@ -675,6 +672,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + /* if it went, fall through and send more stuff */ + } + ++ if (wb->buf == NULL) ++ if (!ssl3_setup_write_buffer(s)) ++ return -1; ++ + if (len == 0 && !create_empty_fragment) + return 0; + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-0221.patch b/SOURCES/openssl-1.0.1e-cve-2014-0221.patch new file mode 100755 index 00000000..deb3a8b8 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-0221.patch @@ -0,0 +1,34 @@ +commit d30e582446b027868cdabd0994681643682045a4 +Author: Dr. Stephen Henson +Date: Fri May 16 13:00:45 2014 +0100 + + Fix CVE-2014-0221 + + Unnecessary recursion when receiving a DTLS hello request can be used to + crash a DTLS client. Fixed by handling DTLS hello request without recursion. + + Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue. + +diff --git a/ssl/d1_both.c b/ssl/d1_both.c +index 07f67f8..4c2fd03 100644 +--- a/ssl/d1_both.c ++++ b/ssl/d1_both.c +@@ -793,6 +793,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) + int i,al; + struct hm_header_st msg_hdr; + ++ redo: + /* see if we have the required fragment already */ + if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) + { +@@ -851,8 +852,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) + s->msg_callback_arg); + + s->init_num = 0; +- return dtls1_get_message_fragment(s, st1, stn, +- max, ok); ++ goto redo; + } + else /* Incorrectly formated Hello request */ + { + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-0224.patch b/SOURCES/openssl-1.0.1e-cve-2014-0224.patch new file mode 100755 index 00000000..05e7e795 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-0224.patch @@ -0,0 +1,104 @@ +diff -up openssl-1.0.1e/ssl/ssl3.h.keying-mitm openssl-1.0.1e/ssl/ssl3.h +--- openssl-1.0.1e/ssl/ssl3.h.keying-mitm 2014-06-02 19:48:04.518100562 +0200 ++++ openssl-1.0.1e/ssl/ssl3.h 2014-06-02 19:48:04.642103429 +0200 +@@ -388,6 +388,7 @@ typedef struct ssl3_buffer_st + #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 + #define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 + #define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 ++#define SSL3_FLAGS_CCS_OK 0x0080 + + /* SSL3_FLAGS_SGC_RESTART_DONE is set when we + * restart a handshake because of MS SGC and so prevents us +diff -up openssl-1.0.1e/ssl/s3_clnt.c.keying-mitm openssl-1.0.1e/ssl/s3_clnt.c +--- openssl-1.0.1e/ssl/s3_clnt.c.keying-mitm 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/s3_clnt.c 2014-06-02 19:49:57.042701985 +0200 +@@ -510,6 +510,7 @@ int ssl3_connect(SSL *s) + s->method->ssl3_enc->client_finished_label, + s->method->ssl3_enc->client_finished_label_len); + if (ret <= 0) goto end; ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->state=SSL3_ST_CW_FLUSH; + + /* clear flags */ +@@ -559,6 +560,7 @@ int ssl3_connect(SSL *s) + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) goto end; +@@ -901,6 +903,7 @@ int ssl3_get_server_hello(SSL *s) + { + s->session->cipher = pref_cipher ? + pref_cipher : ssl_get_cipher_by_char(s, p+j); ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + } + } + #endif /* OPENSSL_NO_TLSEXT */ +@@ -916,6 +918,7 @@ int ssl3_get_server_hello(SSL *s) + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + goto f_err; + } ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->hit=1; + } + else /* a miss or crap from the other end */ +diff -up openssl-1.0.1e/ssl/s3_pkt.c.keying-mitm openssl-1.0.1e/ssl/s3_pkt.c +--- openssl-1.0.1e/ssl/s3_pkt.c.keying-mitm 2014-06-02 19:48:04.640103383 +0200 ++++ openssl-1.0.1e/ssl/s3_pkt.c 2014-06-02 19:48:04.643103452 +0200 +@@ -1298,6 +1298,15 @@ start: + goto f_err; + } + ++ if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) ++ { ++ al=SSL_AD_UNEXPECTED_MESSAGE; ++ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY); ++ goto f_err; ++ } ++ ++ s->s3->flags &= ~SSL3_FLAGS_CCS_OK; ++ + rr->length=0; + + if (s->msg_callback) +@@ -1432,7 +1441,7 @@ int ssl3_do_change_cipher_spec(SSL *s) + + if (s->s3->tmp.key_block == NULL) + { +- if (s->session == NULL) ++ if (s->session == NULL || s->session->master_key_length == 0) + { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY); +diff -up openssl-1.0.1e/ssl/s3_srvr.c.keying-mitm openssl-1.0.1e/ssl/s3_srvr.c +--- openssl-1.0.1e/ssl/s3_srvr.c.keying-mitm 2014-06-02 19:48:04.630103151 +0200 ++++ openssl-1.0.1e/ssl/s3_srvr.c 2014-06-02 19:48:04.643103452 +0200 +@@ -673,6 +673,7 @@ int ssl3_accept(SSL *s) + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + /* we should decide if we expected this one */ + ret=ssl3_get_cert_verify(s); + if (ret <= 0) goto end; +@@ -700,6 +701,7 @@ int ssl3_accept(SSL *s) + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) goto end; +@@ -770,7 +772,10 @@ int ssl3_accept(SSL *s) + s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; + #else + if (s->s3->next_proto_neg_seen) ++ { ++ s->s3->flags |= SSL3_FLAGS_CCS_OK; + s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A; ++ } + else + s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; + #endif diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3470.patch b/SOURCES/openssl-1.0.1e-cve-2014-3470.patch new file mode 100755 index 00000000..32f44873 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3470.patch @@ -0,0 +1,26 @@ +commit 4ad43d511f6cf064c66eb4bfd0fb0919b5dd8a86 +Author: Dr. Stephen Henson +Date: Thu May 29 15:00:05 2014 +0100 + + Fix CVE-2014-3470 + + Check session_cert is not NULL before dereferencing it. + +diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c +index d35376d..4324f8d 100644 +--- a/ssl/s3_clnt.c ++++ b/ssl/s3_clnt.c +@@ -2511,6 +2511,13 @@ int ssl3_send_client_key_exchange(SSL *s) + int ecdh_clnt_cert = 0; + int field_size = 0; + ++ if (s->session->sess_cert == NULL) ++ { ++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); ++ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); ++ goto err; ++ } ++ + /* Did we send out the client's + * ECDH share for use in premaster + * computation as part of client certificate? diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3505.patch b/SOURCES/openssl-1.0.1e-cve-2014-3505.patch new file mode 100755 index 00000000..8716fae9 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3505.patch @@ -0,0 +1,52 @@ +From 2172d4f63c61922487008f42511cc6bdae9b47a0 Mon Sep 17 00:00:00 2001 +From: Adam Langley +Date: Fri, 6 Jun 2014 14:19:21 -0700 +Subject: [PATCH] Avoid double free when processing DTLS packets. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The |item| variable, in both of these cases, may contain a pointer to a +|pitem| structure within |s->d1->buffered_messages|. It was being freed +in the error case while still being in |buffered_messages|. When the +error later caused the |SSL*| to be destroyed, the item would be double +freed. + +Thanks to Wah-Teh Chang for spotting that the fix in 1632ef74 was +inconsistent with the other error paths (but correct). + +Fixes CVE-2014-3505 + +Reviewed-by: Matt Caswell +Reviewed-by: Emilia Käsper +--- + ssl/d1_both.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/ssl/d1_both.c b/ssl/d1_both.c +index c1eb970..cdb83b6 100644 +--- a/ssl/d1_both.c ++++ b/ssl/d1_both.c +@@ -693,8 +693,7 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) + return DTLS1_HM_FRAGMENT_RETRY; + + err: +- if (frag != NULL) dtls1_hm_fragment_free(frag); +- if (item != NULL) OPENSSL_free(item); ++ if (frag != NULL && item == NULL) dtls1_hm_fragment_free(frag); + *ok = 0; + return i; + } +@@ -778,8 +777,7 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) + return DTLS1_HM_FRAGMENT_RETRY; + + err: +- if ( frag != NULL) dtls1_hm_fragment_free(frag); +- if ( item != NULL) OPENSSL_free(item); ++ if (frag != NULL && item == NULL) dtls1_hm_fragment_free(frag); + *ok = 0; + return i; + } +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3506.patch b/SOURCES/openssl-1.0.1e-cve-2014-3506.patch new file mode 100755 index 00000000..05e364f5 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3506.patch @@ -0,0 +1,87 @@ +From fc7804ec392fcf8051abe6bc9da9108744d2ae35 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Fri, 6 Jun 2014 14:25:52 -0700 +Subject: [PATCH] Fix DTLS handshake message size checks. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In |dtls1_reassemble_fragment|, the value of +|msg_hdr->frag_off+frag_len| was being checked against the maximum +handshake message size, but then |msg_len| bytes were allocated for the +fragment buffer. This means that so long as the fragment was within the +allowed size, the pending handshake message could consume 16MB + 2MB +(for the reassembly bitmap). Approx 10 outstanding handshake messages +are allowed, meaning that an attacker could consume ~180MB per DTLS +connection. + +In the non-fragmented path (in |dtls1_process_out_of_seq_message|), no +check was applied. + +Fixes CVE-2014-3506 + +Wholly based on patch by Adam Langley with one minor amendment. + +Reviewed-by: Emilia Käsper +--- + ssl/d1_both.c | 29 ++++++++++++++++------------- + 1 file changed, 16 insertions(+), 13 deletions(-) + +diff --git a/ssl/d1_both.c b/ssl/d1_both.c +index 6559dfc..b9e15df 100644 +--- a/ssl/d1_both.c ++++ b/ssl/d1_both.c +@@ -587,6 +587,16 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) + return 0; + } + ++/* dtls1_max_handshake_message_len returns the maximum number of bytes ++ * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may ++ * be greater if the maximum certificate list size requires it. */ ++static unsigned long dtls1_max_handshake_message_len(const SSL *s) ++ { ++ unsigned long max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; ++ if (max_len < (unsigned long)s->max_cert_list) ++ return s->max_cert_list; ++ return max_len; ++ } + + static int + dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) +@@ -595,20 +605,10 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) + pitem *item = NULL; + int i = -1, is_complete; + unsigned char seq64be[8]; +- unsigned long frag_len = msg_hdr->frag_len, max_len; +- +- if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) +- goto err; +- +- /* Determine maximum allowed message size. Depends on (user set) +- * maximum certificate length, but 16k is minimum. +- */ +- if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list) +- max_len = s->max_cert_list; +- else +- max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; ++ unsigned long frag_len = msg_hdr->frag_len; + +- if ((msg_hdr->frag_off+frag_len) > max_len) ++ if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len || ++ msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) + goto err; + + /* Try to find item in queue */ +@@ -749,6 +749,9 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) + if (frag_len && frag_len < msg_hdr->msg_len) + return dtls1_reassemble_fragment(s, msg_hdr, ok); + ++ if (frag_len > dtls1_max_handshake_message_len(s)) ++ goto err; ++ + frag = dtls1_hm_fragment_new(frag_len, 0); + if ( frag == NULL) + goto err; +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3507.patch b/SOURCES/openssl-1.0.1e-cve-2014-3507.patch new file mode 100755 index 00000000..05073152 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3507.patch @@ -0,0 +1,53 @@ +diff -up openssl-1.0.1e/ssl/d1_both.c.dtls-memleak openssl-1.0.1e/ssl/d1_both.c +--- openssl-1.0.1e/ssl/d1_both.c.dtls-memleak 2014-08-07 17:51:18.457493922 +0200 ++++ openssl-1.0.1e/ssl/d1_both.c 2014-08-07 17:58:28.478558785 +0200 +@@ -610,6 +610,9 @@ dtls1_reassemble_fragment(SSL *s, struct + msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) + goto err; + ++ if (frag_len == 0) ++ return DTLS1_HM_FRAGMENT_RETRY; ++ + /* Try to find item in queue */ + memset(seq64be,0,sizeof(seq64be)); + seq64be[6] = (unsigned char) (msg_hdr->seq>>8); +@@ -686,7 +689,12 @@ dtls1_reassemble_fragment(SSL *s, struct + i = -1; + } + +- pqueue_insert(s->d1->buffered_messages, item); ++ item = pqueue_insert(s->d1->buffered_messages, item); ++ /* pqueue_insert fails iff a duplicate item is inserted. ++ * However, |item| cannot be a duplicate. If it were, ++ * |pqueue_find|, above, would have returned it and control ++ * would never have reached this branch. */ ++ OPENSSL_assert(item != NULL); + } + + return DTLS1_HM_FRAGMENT_RETRY; +@@ -744,7 +752,7 @@ dtls1_process_out_of_seq_message(SSL *s, + } + else + { +- if (frag_len && frag_len < msg_hdr->msg_len) ++ if (frag_len < msg_hdr->msg_len) + return dtls1_reassemble_fragment(s, msg_hdr, ok); + + if (frag_len > dtls1_max_handshake_message_len(s)) +@@ -773,7 +781,15 @@ dtls1_process_out_of_seq_message(SSL *s, + if ( item == NULL) + goto err; + +- pqueue_insert(s->d1->buffered_messages, item); ++ item = pqueue_insert(s->d1->buffered_messages, item); ++ /* pqueue_insert fails iff a duplicate item is inserted. ++ * However, |item| cannot be a duplicate. If it were, ++ * |pqueue_find|, above, would have returned it. Then, either ++ * |frag_len| != |msg_hdr->msg_len| in which case |item| is set ++ * to NULL and it will have been processed with ++ * |dtls1_reassemble_fragment|, above, or the record will have ++ * been discarded. */ ++ OPENSSL_assert(item != NULL); + } + + return DTLS1_HM_FRAGMENT_RETRY; diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3508.patch b/SOURCES/openssl-1.0.1e-cve-2014-3508.patch new file mode 100755 index 00000000..31dd08db --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3508.patch @@ -0,0 +1,138 @@ +From 03b04ddac162c7b7fa3c57eadccc5a583a00d291 Mon Sep 17 00:00:00 2001 +From: Emilia Kasper +Date: Wed, 2 Jul 2014 19:02:33 +0200 +Subject: [PATCH] Fix OID handling: + +- Upon parsing, reject OIDs with invalid base-128 encoding. +- Always NUL-terminate the destination buffer in OBJ_obj2txt printing function. + +CVE-2014-3508 + +Reviewed-by: Dr. Stephen Henson +Reviewed-by: Kurt Roeckx +Reviewed-by: Tim Hudson +--- + crypto/asn1/a_object.c | 30 +++++++++++++++++++++--------- + crypto/objects/obj_dat.c | 16 +++++++++------- + 2 files changed, 30 insertions(+), 16 deletions(-) + +diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c +index 3978c91..77b2768 100644 +--- a/crypto/asn1/a_object.c ++++ b/crypto/asn1/a_object.c +@@ -283,17 +283,29 @@ err: + ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); + return(NULL); + } ++ + ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long len) + { + ASN1_OBJECT *ret=NULL; + const unsigned char *p; + unsigned char *data; +- int i; +- /* Sanity check OID encoding: can't have leading 0x80 in +- * subidentifiers, see: X.690 8.19.2 ++ int i, length; ++ ++ /* Sanity check OID encoding. ++ * Need at least one content octet. ++ * MSB must be clear in the last octet. ++ * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2 + */ +- for (i = 0, p = *pp; i < len; i++, p++) ++ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || ++ p[len - 1] & 0x80) ++ { ++ ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING); ++ return NULL; ++ } ++ /* Now 0 < len <= INT_MAX, so the cast is safe. */ ++ length = (int)len; ++ for (i = 0; i < length; i++, p++) + { + if (*p == 0x80 && (!i || !(p[-1] & 0x80))) + { +@@ -316,23 +328,23 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + data = (unsigned char *)ret->data; + ret->data = NULL; + /* once detached we can change it */ +- if ((data == NULL) || (ret->length < len)) ++ if ((data == NULL) || (ret->length < length)) + { + ret->length=0; + if (data != NULL) OPENSSL_free(data); +- data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); ++ data=(unsigned char *)OPENSSL_malloc(length); + if (data == NULL) + { i=ERR_R_MALLOC_FAILURE; goto err; } + ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; + } +- memcpy(data,p,(int)len); ++ memcpy(data,p,length); + /* reattach data to object, after which it remains const */ + ret->data =data; +- ret->length=(int)len; ++ ret->length=length; + ret->sn=NULL; + ret->ln=NULL; + /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ +- p+=len; ++ p+=length; + + if (a != NULL) (*a)=ret; + *pp=p; +diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c +index 8a342ba..0b2f442 100644 +--- a/crypto/objects/obj_dat.c ++++ b/crypto/objects/obj_dat.c +@@ -471,11 +471,12 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) + const unsigned char *p; + char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; + +- if ((a == NULL) || (a->data == NULL)) { +- buf[0]='\0'; +- return(0); +- } ++ /* Ensure that, at every state, |buf| is NUL-terminated. */ ++ if (buf && buf_len > 0) ++ buf[0] = '\0'; + ++ if ((a == NULL) || (a->data == NULL)) ++ return(0); + + if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef) + { +@@ -554,9 +555,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) + i=(int)(l/40); + l-=(long)(i*40); + } +- if (buf && (buf_len > 0)) ++ if (buf && (buf_len > 1)) + { + *buf++ = i + '0'; ++ *buf = '\0'; + buf_len--; + } + n++; +@@ -571,9 +573,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) + i = strlen(bndec); + if (buf) + { +- if (buf_len > 0) ++ if (buf_len > 1) + { + *buf++ = '.'; ++ *buf = '\0'; + buf_len--; + } + BUF_strlcpy(buf,bndec,buf_len); +@@ -807,4 +810,3 @@ err: + OPENSSL_free(buf); + return(ok); + } +- +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3509.patch b/SOURCES/openssl-1.0.1e-cve-2014-3509.patch new file mode 100755 index 00000000..cee4aadf --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3509.patch @@ -0,0 +1,45 @@ +From 86788e1ee6908a5b3a4c95fa80caa4b724a8a434 Mon Sep 17 00:00:00 2001 +From: Gabor Tyukasz +Date: Wed, 23 Jul 2014 23:42:06 +0200 +Subject: [PATCH] Fix race condition in ssl_parse_serverhello_tlsext + +CVE-2014-3509 +Reviewed-by: Tim Hudson +Reviewed-by: Dr. Stephen Henson +--- + ssl/t1_lib.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c +index 8167a51..022a4fb 100644 +--- a/ssl/t1_lib.c ++++ b/ssl/t1_lib.c +@@ -1555,15 +1555,18 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in + *al = TLS1_AD_DECODE_ERROR; + return 0; + } +- s->session->tlsext_ecpointformatlist_length = 0; +- if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); +- if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) ++ if (!s->hit) + { +- *al = TLS1_AD_INTERNAL_ERROR; +- return 0; ++ s->session->tlsext_ecpointformatlist_length = 0; ++ if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); ++ if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) ++ { ++ *al = TLS1_AD_INTERNAL_ERROR; ++ return 0; ++ } ++ s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; ++ memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); + } +- s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; +- memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); + #if 0 + fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); + sdata = s->session->tlsext_ecpointformatlist; +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3510.patch b/SOURCES/openssl-1.0.1e-cve-2014-3510.patch new file mode 100755 index 00000000..41965364 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3510.patch @@ -0,0 +1,86 @@ +From 88ae012c8092852f03c50f6461175271104b4c8a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Emilia=20K=C3=A4sper?= +Date: Thu, 24 Jul 2014 22:15:29 +0200 +Subject: [PATCH] Fix DTLS anonymous EC(DH) denial of service + +CVE-2014-3510 + +Reviewed-by: Dr. Stephen Henson +--- + ssl/d1_clnt.c | 23 +++++++++++++++++++++-- + ssl/s3_clnt.c | 7 +++++++ + 2 files changed, 28 insertions(+), 2 deletions(-) + +diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c +index 65dbb4a..fd6562c 100644 +--- a/ssl/d1_clnt.c ++++ b/ssl/d1_clnt.c +@@ -996,6 +996,13 @@ int dtls1_send_client_key_exchange(SSL *s) + RSA *rsa; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + ++ if (s->session->sess_cert == NULL) ++ { ++ /* We should always have a server certificate with SSL_kRSA. */ ++ SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ + if (s->session->sess_cert->peer_rsa_tmp != NULL) + rsa=s->session->sess_cert->peer_rsa_tmp; + else +@@ -1186,6 +1193,13 @@ int dtls1_send_client_key_exchange(SSL *s) + { + DH *dh_srvr,*dh_clnt; + ++ if (s->session->sess_cert == NULL) ++ { ++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); ++ SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); ++ goto err; ++ } ++ + if (s->session->sess_cert->peer_dh_tmp != NULL) + dh_srvr=s->session->sess_cert->peer_dh_tmp; + else +@@ -1245,6 +1259,13 @@ int dtls1_send_client_key_exchange(SSL *s) + int ecdh_clnt_cert = 0; + int field_size = 0; + ++ if (s->session->sess_cert == NULL) ++ { ++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); ++ SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); ++ goto err; ++ } ++ + /* Did we send out the client's + * ECDH share for use in premaster + * computation as part of client certificate? +@@ -1720,5 +1741,3 @@ int dtls1_send_client_certificate(SSL *s) + /* SSL3_ST_CW_CERT_D */ + return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); + } +- +- +diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c +index 2afb892..df05f78 100644 +--- a/ssl/s3_clnt.c ++++ b/ssl/s3_clnt.c +@@ -2253,6 +2253,13 @@ int ssl3_send_client_key_exchange(SSL *s) + RSA *rsa; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + ++ if (s->session->sess_cert == NULL) ++ { ++ /* We should always have a server certificate with SSL_kRSA. */ ++ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); ++ goto err; ++ } ++ + if (s->session->sess_cert->peer_rsa_tmp != NULL) + rsa=s->session->sess_cert->peer_rsa_tmp; + else +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3511.patch b/SOURCES/openssl-1.0.1e-cve-2014-3511.patch new file mode 100755 index 00000000..f9cb4ea3 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3511.patch @@ -0,0 +1,85 @@ +From fc4f4cdb8bf9981904e652abf69b892a45bddacf Mon Sep 17 00:00:00 2001 +From: David Benjamin +Date: Wed, 23 Jul 2014 22:32:21 +0200 +Subject: [PATCH] Fix protocol downgrade bug in case of fragmented packets +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2014-3511 + +Reviewed-by: Emilia Käsper +Reviewed-by: Bodo Möller +--- + ssl/s23_srvr.c | 30 +++++++++++++++++++++++------- + 1 file changed, 23 insertions(+), 7 deletions(-) + +diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c +index 4877849..2901a6b 100644 +--- a/ssl/s23_srvr.c ++++ b/ssl/s23_srvr.c +@@ -348,23 +348,19 @@ int ssl23_get_client_hello(SSL *s) + * Client Hello message, this would be difficult, and we'd have + * to read more records to find out. + * No known SSL 3.0 client fragments ClientHello like this, +- * so we simply assume TLS 1.0 to avoid protocol version downgrade +- * attacks. */ ++ * so we simply reject such connections to avoid ++ * protocol version downgrade attacks. */ + if (p[3] == 0 && p[4] < 6) + { +-#if 0 + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL); + goto err; +-#else +- v[1] = TLS1_VERSION_MINOR; +-#endif + } + /* if major version number > 3 set minor to a value + * which will use the highest version 3 we support. + * If TLS 2.0 ever appears we will need to revise + * this.... + */ +- else if (p[9] > SSL3_VERSION_MAJOR) ++ if (p[9] > SSL3_VERSION_MAJOR) + v[1]=0xff; + else + v[1]=p[10]; /* minor version according to client_version */ +@@ -444,14 +440,34 @@ int ssl23_get_client_hello(SSL *s) + v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ + v[1] = p[4]; + ++ /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 ++ * header is sent directly on the wire, not wrapped as a TLS ++ * record. It's format is: ++ * Byte Content ++ * 0-1 msg_length ++ * 2 msg_type ++ * 3-4 version ++ * 5-6 cipher_spec_length ++ * 7-8 session_id_length ++ * 9-10 challenge_length ++ * ... ... ++ */ + n=((p[0]&0x7f)<<8)|p[1]; + if (n > (1024*4)) + { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE); + goto err; + } ++ if (n < 9) ++ { ++ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH); ++ goto err; ++ } + + j=ssl23_read_bytes(s,n+2); ++ /* We previously read 11 bytes, so if j > 0, we must have ++ * j == n+2 == s->packet_length. We have at least 11 valid ++ * packet bytes. */ + if (j <= 0) return(j); + + ssl3_finish_mac(s, s->packet+2, s->packet_length-2); +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3513.patch b/SOURCES/openssl-1.0.1e-cve-2014-3513.patch new file mode 100755 index 00000000..0d42eec4 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3513.patch @@ -0,0 +1,186 @@ +diff -up openssl-1.0.1e/ssl/d1_srtp.c.srtp-leak openssl-1.0.1e/ssl/d1_srtp.c +--- openssl-1.0.1e/ssl/d1_srtp.c.srtp-leak 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/d1_srtp.c 2014-10-15 13:23:34.253040160 +0200 +@@ -168,25 +168,6 @@ static int find_profile_by_name(char *pr + return 1; + } + +-static int find_profile_by_num(unsigned profile_num, +- SRTP_PROTECTION_PROFILE **pptr) +- { +- SRTP_PROTECTION_PROFILE *p; +- +- p=srtp_known_profiles; +- while(p->name) +- { +- if(p->id == profile_num) +- { +- *pptr=p; +- return 0; +- } +- p++; +- } +- +- return 1; +- } +- + static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out) + { + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; +@@ -209,11 +190,19 @@ static int ssl_ctx_make_profiles(const c + if(!find_profile_by_name(ptr,&p, + col ? col-ptr : (int)strlen(ptr))) + { ++ if (sk_SRTP_PROTECTION_PROFILE_find(profiles,p) >= 0) ++ { ++ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); ++ sk_SRTP_PROTECTION_PROFILE_free(profiles); ++ return 1; ++ } ++ + sk_SRTP_PROTECTION_PROFILE_push(profiles,p); + } + else + { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); ++ sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + +@@ -305,13 +294,12 @@ int ssl_add_clienthello_use_srtp_ext(SSL + + int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al) + { +- SRTP_PROTECTION_PROFILE *cprof,*sprof; +- STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr; ++ SRTP_PROTECTION_PROFILE *sprof; ++ STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; + int ct; + int mki_len; +- int i,j; +- int id; +- int ret; ++ int i, srtp_pref; ++ unsigned int id; + + /* Length value + the MKI length */ + if(len < 3) +@@ -341,22 +329,32 @@ int ssl_parse_clienthello_use_srtp_ext(S + return 1; + } + ++ srvr=SSL_get_srtp_profiles(s); ++ s->srtp_profile = NULL; ++ /* Search all profiles for a match initially */ ++ srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr); + +- clnt=sk_SRTP_PROTECTION_PROFILE_new_null(); +- + while(ct) + { + n2s(d,id); + ct-=2; + len-=2; + +- if(!find_profile_by_num(id,&cprof)) ++ /* ++ * Only look for match in profiles of higher preference than ++ * current match. ++ * If no profiles have been have been configured then this ++ * does nothing. ++ */ ++ for (i = 0; i < srtp_pref; i++) + { +- sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof); +- } +- else +- { +- ; /* Ignore */ ++ sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); ++ if (sprof->id == id) ++ { ++ s->srtp_profile = sprof; ++ srtp_pref = i; ++ break; ++ } + } + } + +@@ -371,36 +369,7 @@ int ssl_parse_clienthello_use_srtp_ext(S + return 1; + } + +- srvr=SSL_get_srtp_profiles(s); +- +- /* Pick our most preferred profile. If no profiles have been +- configured then the outer loop doesn't run +- (sk_SRTP_PROTECTION_PROFILE_num() = -1) +- and so we just return without doing anything */ +- for(i=0;iid==sprof->id) +- { +- s->srtp_profile=sprof; +- *al=0; +- ret=0; +- goto done; +- } +- } +- } +- +- ret=0; +- +-done: +- if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt); +- +- return ret; ++ return 0; + } + + int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen) +diff -up openssl-1.0.1e/ssl/t1_lib.c.srtp-leak openssl-1.0.1e/ssl/t1_lib.c +--- openssl-1.0.1e/ssl/t1_lib.c.srtp-leak 2014-10-15 13:19:59.955202293 +0200 ++++ openssl-1.0.1e/ssl/t1_lib.c 2014-10-15 13:23:34.254040182 +0200 +@@ -696,7 +696,7 @@ unsigned char *ssl_add_clienthello_tlsex + #endif + + #ifndef OPENSSL_NO_SRTP +- if(SSL_get_srtp_profiles(s)) ++ if(SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) + { + int el; + +@@ -829,7 +829,7 @@ unsigned char *ssl_add_serverhello_tlsex + #endif + + #ifndef OPENSSL_NO_SRTP +- if(s->srtp_profile) ++ if(SSL_IS_DTLS(s) && s->srtp_profile) + { + int el; + +@@ -1377,7 +1377,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, + + /* session ticket processed earlier */ + #ifndef OPENSSL_NO_SRTP +- else if (type == TLSEXT_TYPE_use_srtp) ++ else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) ++ && type == TLSEXT_TYPE_use_srtp) + { + if(ssl_parse_clienthello_use_srtp_ext(s, data, size, + al)) +@@ -1631,7 +1632,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, + } + #endif + #ifndef OPENSSL_NO_SRTP +- else if (type == TLSEXT_TYPE_use_srtp) ++ else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) + { + if(ssl_parse_serverhello_use_srtp_ext(s, data, size, + al)) diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3567.patch b/SOURCES/openssl-1.0.1e-cve-2014-3567.patch new file mode 100755 index 00000000..a01ee694 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3567.patch @@ -0,0 +1,14 @@ +diff -up openssl-1.0.1e/ssl/t1_lib.c.ticket-leak openssl-1.0.1e/ssl/t1_lib.c +--- openssl-1.0.1e/ssl/t1_lib.c.ticket-leak 2014-10-15 13:19:26.825454374 +0200 ++++ openssl-1.0.1e/ssl/t1_lib.c 2014-10-15 13:19:59.955202293 +0200 +@@ -2280,7 +2280,10 @@ static int tls_decrypt_ticket(SSL *s, co + HMAC_Final(&hctx, tick_hmac, NULL); + HMAC_CTX_cleanup(&hctx); + if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) ++ { ++ EVP_CIPHER_CTX_cleanup(&ctx); + return 2; ++ } + /* Attempt to decrypt session data */ + /* Move p after IV to start of encrypted ticket, update length */ + p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3570.patch b/SOURCES/openssl-1.0.1e-cve-2014-3570.patch new file mode 100755 index 00000000..aff2f025 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3570.patch @@ -0,0 +1,3155 @@ +From e078642ddea29bbb6ba29788a6a513796387fbbb Mon Sep 17 00:00:00 2001 +From: Andy Polyakov +Date: Mon, 5 Jan 2015 14:52:56 +0100 +Subject: [PATCH] Fix for CVE-2014-3570. + +Reviewed-by: Emilia Kasper +(cherry picked from commit e793809ba50c1e90ab592fb640a856168e50f3de) +(with 1.0.1-specific addendum) +--- + crypto/bn/asm/mips.pl | 611 +++--------- + crypto/bn/asm/mips3.s | 2201 -------------------------------------------- + crypto/bn/asm/x86_64-gcc.c | 34 +- + crypto/bn/bn_asm.c | 16 +- + crypto/bn/bntest.c | 102 +- + 5 files changed, 234 insertions(+), 2730 deletions(-) + delete mode 100644 crypto/bn/asm/mips3.s + +diff --git a/crypto/bn/asm/mips.pl b/crypto/bn/asm/mips.pl +index d2f3ef7..215c9a7 100644 +--- a/crypto/bn/asm/mips.pl ++++ b/crypto/bn/asm/mips.pl +@@ -1872,6 +1872,41 @@ ___ + + ($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3); + ++sub add_c2 () { ++my ($hi,$lo,$c0,$c1,$c2, ++ $warm, # !$warm denotes first call with specific sequence of ++ # $c_[XYZ] when there is no Z-carry to accumulate yet; ++ $an,$bn # these two are arguments for multiplication which ++ # result is used in *next* step [which is why it's ++ # commented as "forward multiplication" below]; ++ )=@_; ++$code.=<<___; ++ mflo $lo ++ mfhi $hi ++ $ADDU $c0,$lo ++ sltu $at,$c0,$lo ++ $MULTU $an,$bn # forward multiplication ++ $ADDU $c0,$lo ++ $ADDU $at,$hi ++ sltu $lo,$c0,$lo ++ $ADDU $c1,$at ++ $ADDU $hi,$lo ++___ ++$code.=<<___ if (!$warm); ++ sltu $c2,$c1,$at ++ $ADDU $c1,$hi ++ sltu $hi,$c1,$hi ++ $ADDU $c2,$hi ++___ ++$code.=<<___ if ($warm); ++ sltu $at,$c1,$at ++ $ADDU $c1,$hi ++ $ADDU $c2,$at ++ sltu $hi,$c1,$hi ++ $ADDU $c2,$hi ++___ ++} ++ + $code.=<<___; + + .align 5 +@@ -1920,21 +1955,10 @@ $code.=<<___; + sltu $at,$c_2,$t_1 + $ADDU $c_3,$t_2,$at + $ST $c_2,$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_2,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at ++___ ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, ++ $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 +@@ -1945,67 +1969,19 @@ $code.=<<___; + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,2*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_3,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_1,$a_2 # mul_add_c2(a[1],b[2],c1,c2,c3); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_3,$at +- $MULTU $a_4,$a_0 # mul_add_c2(a[4],b[0],c2,c3,c1); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at ++___ ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, ++ $a_1,$a_2); # mul_add_c2(a[1],b[2],c1,c2,c3); ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, ++ $a_4,$a_0); # mul_add_c2(a[4],b[0],c2,c3,c1); ++$code.=<<___; + $ST $c_1,3*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_1,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_1,$at +- $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at ++___ ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, ++ $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1); ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, ++ $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 +@@ -2016,97 +1992,23 @@ $code.=<<___; + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,4*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_2,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_1,$a_4 # mul_add_c2(a[1],b[4],c3,c1,c2); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_2,$at +- $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $MULTU $a_6,$a_0 # mul_add_c2(a[6],b[0],c1,c2,c3); +- $ADDU $c_2,$at +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at ++___ ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, ++ $a_1,$a_4); # mul_add_c2(a[1],b[4],c3,c1,c2); ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, ++ $a_2,$a_3); # mul_add_c2(a[2],b[3],c3,c1,c2); ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, ++ $a_6,$a_0); # mul_add_c2(a[6],b[0],c1,c2,c3); ++$code.=<<___; + $ST $c_3,5*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_3,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_5,$a_1 # mul_add_c2(a[5],b[1],c1,c2,c3); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_3,$at +- $MULTU $a_4,$a_2 # mul_add_c2(a[4],b[2],c1,c2,c3); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_3,$at +- $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at ++___ ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, ++ $a_5,$a_1); # mul_add_c2(a[5],b[1],c1,c2,c3); ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, ++ $a_4,$a_2); # mul_add_c2(a[4],b[2],c1,c2,c3); ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, ++ $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 +@@ -2117,112 +2019,25 @@ $code.=<<___; + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,6*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_1,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_1,$a_6 # mul_add_c2(a[1],b[6],c2,c3,c1); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_1,$at +- $MULTU $a_2,$a_5 # mul_add_c2(a[2],b[5],c2,c3,c1); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_1,$at +- $MULTU $a_3,$a_4 # mul_add_c2(a[3],b[4],c2,c3,c1); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_1,$at +- $MULTU $a_7,$a_1 # mul_add_c2(a[7],b[1],c3,c1,c2); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at ++___ ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, ++ $a_1,$a_6); # mul_add_c2(a[1],b[6],c2,c3,c1); ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, ++ $a_2,$a_5); # mul_add_c2(a[2],b[5],c2,c3,c1); ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, ++ $a_3,$a_4); # mul_add_c2(a[3],b[4],c2,c3,c1); ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, ++ $a_7,$a_1); # mul_add_c2(a[7],b[1],c3,c1,c2); ++$code.=<<___; + $ST $c_2,7*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_2,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_6,$a_2 # mul_add_c2(a[6],b[2],c3,c1,c2); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_2,$at +- $MULTU $a_5,$a_3 # mul_add_c2(a[5],b[3],c3,c1,c2); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_2,$at +- $MULTU $a_4,$a_4 # mul_add_c(a[4],b[4],c3,c1,c2); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at ++___ ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, ++ $a_6,$a_2); # mul_add_c2(a[6],b[2],c3,c1,c2); ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, ++ $a_5,$a_3); # mul_add_c2(a[5],b[3],c3,c1,c2); ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, ++ $a_4,$a_4); # mul_add_c(a[4],b[4],c3,c1,c2); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 +@@ -2233,82 +2048,21 @@ $code.=<<___; + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,8*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_3,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_3,$a_6 # mul_add_c2(a[3],b[6],c1,c2,c3); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_3,$at +- $MULTU $a_4,$a_5 # mul_add_c2(a[4],b[5],c1,c2,c3); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_3,$at +- $MULTU $a_7,$a_3 # mul_add_c2(a[7],b[3],c2,c3,c1); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at ++___ ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, ++ $a_3,$a_6); # mul_add_c2(a[3],b[6],c1,c2,c3); ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, ++ $a_4,$a_5); # mul_add_c2(a[4],b[5],c1,c2,c3); ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, ++ $a_7,$a_3); # mul_add_c2(a[7],b[3],c2,c3,c1); ++$code.=<<___; + $ST $c_1,9*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_1,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_6,$a_4 # mul_add_c2(a[6],b[4],c2,c3,c1); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_1,$at +- $MULTU $a_5,$a_5 # mul_add_c(a[5],b[5],c2,c3,c1); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at ++___ ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, ++ $a_6,$a_4); # mul_add_c2(a[6],b[4],c2,c3,c1); ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, ++ $a_5,$a_5); # mul_add_c(a[5],b[5],c2,c3,c1); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 +@@ -2319,52 +2073,17 @@ $code.=<<___; + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,10*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_2,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_5,$a_6 # mul_add_c2(a[5],b[6],c3,c1,c2); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_2,$at +- $MULTU $a_7,$a_5 # mul_add_c2(a[7],b[5],c1,c2,c3); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at ++___ ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, ++ $a_5,$a_6); # mul_add_c2(a[5],b[6],c3,c1,c2); ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, ++ $a_7,$a_5); # mul_add_c2(a[7],b[5],c1,c2,c3); ++$code.=<<___; + $ST $c_3,11*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_3,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_6,$a_6 # mul_add_c(a[6],b[6],c1,c2,c3); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at ++___ ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, ++ $a_6,$a_6); # mul_add_c(a[6],b[6],c1,c2,c3); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 +@@ -2375,21 +2094,10 @@ $code.=<<___; + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,12*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_1,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_7,$a_7 # mul_add_c(a[7],b[7],c3,c1,c2); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at ++___ ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, ++ $a_7,$a_7); # mul_add_c(a[7],b[7],c3,c1,c2); ++$code.=<<___; + $ST $c_2,13*$BNSZ($a0) + + mflo $t_1 +@@ -2457,21 +2165,10 @@ $code.=<<___; + sltu $at,$c_2,$t_1 + $ADDU $c_3,$t_2,$at + $ST $c_2,$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_2,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_1,$a_1 # mul_add_c(a[1],b[1],c3,c1,c2); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at ++___ ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, ++ $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 +@@ -2482,52 +2179,17 @@ $code.=<<___; + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,2*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_3,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_1,$a_2 # mul_add_c(a2[1],b[2],c1,c2,c3); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at +- mflo $t_1 +- mfhi $t_2 +- slt $at,$t_2,$zero +- $ADDU $c_3,$at +- $MULTU $a_3,$a_1 # mul_add_c2(a[3],b[1],c2,c3,c1); +- $SLL $t_2,1 +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_1,$t_1 +- sltu $at,$c_1,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_2,$t_2 +- sltu $at,$c_2,$t_2 +- $ADDU $c_3,$at ++___ ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, ++ $a_1,$a_2); # mul_add_c2(a2[1],b[2],c1,c2,c3); ++ &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, ++ $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1); ++$code.=<<___; + $ST $c_1,3*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_1,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_2,$a_2 # mul_add_c(a[2],b[2],c2,c3,c1); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_2,$t_1 +- sltu $at,$c_2,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_3,$t_2 +- sltu $at,$c_3,$t_2 +- $ADDU $c_1,$at ++___ ++ &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, ++ $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1); ++$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 +@@ -2538,21 +2200,10 @@ $code.=<<___; + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,4*$BNSZ($a0) +- +- mflo $t_1 +- mfhi $t_2 +- slt $c_2,$t_2,$zero +- $SLL $t_2,1 +- $MULTU $a_3,$a_3 # mul_add_c(a[3],b[3],c1,c2,c3); +- slt $a2,$t_1,$zero +- $ADDU $t_2,$a2 +- $SLL $t_1,1 +- $ADDU $c_3,$t_1 +- sltu $at,$c_3,$t_1 +- $ADDU $t_2,$at +- $ADDU $c_1,$t_2 +- sltu $at,$c_1,$t_2 +- $ADDU $c_2,$at ++___ ++ &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, ++ $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3); ++$code.=<<___; + $ST $c_3,5*$BNSZ($a0) + + mflo $t_1 +diff --git a/crypto/bn/asm/mips3.s b/crypto/bn/asm/mips3.s +deleted file mode 100644 +index dca4105..0000000 +--- a/crypto/bn/asm/mips3.s ++++ /dev/null +@@ -1,2201 +0,0 @@ +-.rdata +-.asciiz "mips3.s, Version 1.1" +-.asciiz "MIPS III/IV ISA artwork by Andy Polyakov " +- +-/* +- * ==================================================================== +- * Written by Andy Polyakov for the OpenSSL +- * project. +- * +- * Rights for redistribution and usage in source and binary forms are +- * granted according to the OpenSSL license. Warranty of any kind is +- * disclaimed. +- * ==================================================================== +- */ +- +-/* +- * This is my modest contributon to the OpenSSL project (see +- * http://www.openssl.org/ for more information about it) and is +- * a drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c +- * module. For updates see http://fy.chalmers.se/~appro/hpe/. +- * +- * The module is designed to work with either of the "new" MIPS ABI(5), +- * namely N32 or N64, offered by IRIX 6.x. It's not ment to work under +- * IRIX 5.x not only because it doesn't support new ABIs but also +- * because 5.x kernels put R4x00 CPU into 32-bit mode and all those +- * 64-bit instructions (daddu, dmultu, etc.) found below gonna only +- * cause illegal instruction exception:-( +- * +- * In addition the code depends on preprocessor flags set up by MIPSpro +- * compiler driver (either as or cc) and therefore (probably?) can't be +- * compiled by the GNU assembler. GNU C driver manages fine though... +- * I mean as long as -mmips-as is specified or is the default option, +- * because then it simply invokes /usr/bin/as which in turn takes +- * perfect care of the preprocessor definitions. Another neat feature +- * offered by the MIPSpro assembler is an optimization pass. This gave +- * me the opportunity to have the code looking more regular as all those +- * architecture dependent instruction rescheduling details were left to +- * the assembler. Cool, huh? +- * +- * Performance improvement is astonishing! 'apps/openssl speed rsa dsa' +- * goes way over 3 times faster! +- * +- * +- */ +-#include +-#include +- +-#if _MIPS_ISA>=4 +-#define MOVNZ(cond,dst,src) \ +- movn dst,src,cond +-#else +-#define MOVNZ(cond,dst,src) \ +- .set noreorder; \ +- bnezl cond,.+8; \ +- move dst,src; \ +- .set reorder +-#endif +- +-.text +- +-.set noat +-.set reorder +- +-#define MINUS4 v1 +- +-.align 5 +-LEAF(bn_mul_add_words) +- .set noreorder +- bgtzl a2,.L_bn_mul_add_words_proceed +- ld t0,0(a1) +- jr ra +- move v0,zero +- .set reorder +- +-.L_bn_mul_add_words_proceed: +- li MINUS4,-4 +- and ta0,a2,MINUS4 +- move v0,zero +- beqz ta0,.L_bn_mul_add_words_tail +- +-.L_bn_mul_add_words_loop: +- dmultu t0,a3 +- ld t1,0(a0) +- ld t2,8(a1) +- ld t3,8(a0) +- ld ta0,16(a1) +- ld ta1,16(a0) +- daddu t1,v0 +- sltu v0,t1,v0 /* All manuals say it "compares 32-bit +- * values", but it seems to work fine +- * even on 64-bit registers. */ +- mflo AT +- mfhi t0 +- daddu t1,AT +- daddu v0,t0 +- sltu AT,t1,AT +- sd t1,0(a0) +- daddu v0,AT +- +- dmultu t2,a3 +- ld ta2,24(a1) +- ld ta3,24(a0) +- daddu t3,v0 +- sltu v0,t3,v0 +- mflo AT +- mfhi t2 +- daddu t3,AT +- daddu v0,t2 +- sltu AT,t3,AT +- sd t3,8(a0) +- daddu v0,AT +- +- dmultu ta0,a3 +- subu a2,4 +- PTR_ADD a0,32 +- PTR_ADD a1,32 +- daddu ta1,v0 +- sltu v0,ta1,v0 +- mflo AT +- mfhi ta0 +- daddu ta1,AT +- daddu v0,ta0 +- sltu AT,ta1,AT +- sd ta1,-16(a0) +- daddu v0,AT +- +- +- dmultu ta2,a3 +- and ta0,a2,MINUS4 +- daddu ta3,v0 +- sltu v0,ta3,v0 +- mflo AT +- mfhi ta2 +- daddu ta3,AT +- daddu v0,ta2 +- sltu AT,ta3,AT +- sd ta3,-8(a0) +- daddu v0,AT +- .set noreorder +- bgtzl ta0,.L_bn_mul_add_words_loop +- ld t0,0(a1) +- +- bnezl a2,.L_bn_mul_add_words_tail +- ld t0,0(a1) +- .set reorder +- +-.L_bn_mul_add_words_return: +- jr ra +- +-.L_bn_mul_add_words_tail: +- dmultu t0,a3 +- ld t1,0(a0) +- subu a2,1 +- daddu t1,v0 +- sltu v0,t1,v0 +- mflo AT +- mfhi t0 +- daddu t1,AT +- daddu v0,t0 +- sltu AT,t1,AT +- sd t1,0(a0) +- daddu v0,AT +- beqz a2,.L_bn_mul_add_words_return +- +- ld t0,8(a1) +- dmultu t0,a3 +- ld t1,8(a0) +- subu a2,1 +- daddu t1,v0 +- sltu v0,t1,v0 +- mflo AT +- mfhi t0 +- daddu t1,AT +- daddu v0,t0 +- sltu AT,t1,AT +- sd t1,8(a0) +- daddu v0,AT +- beqz a2,.L_bn_mul_add_words_return +- +- ld t0,16(a1) +- dmultu t0,a3 +- ld t1,16(a0) +- daddu t1,v0 +- sltu v0,t1,v0 +- mflo AT +- mfhi t0 +- daddu t1,AT +- daddu v0,t0 +- sltu AT,t1,AT +- sd t1,16(a0) +- daddu v0,AT +- jr ra +-END(bn_mul_add_words) +- +-.align 5 +-LEAF(bn_mul_words) +- .set noreorder +- bgtzl a2,.L_bn_mul_words_proceed +- ld t0,0(a1) +- jr ra +- move v0,zero +- .set reorder +- +-.L_bn_mul_words_proceed: +- li MINUS4,-4 +- and ta0,a2,MINUS4 +- move v0,zero +- beqz ta0,.L_bn_mul_words_tail +- +-.L_bn_mul_words_loop: +- dmultu t0,a3 +- ld t2,8(a1) +- ld ta0,16(a1) +- ld ta2,24(a1) +- mflo AT +- mfhi t0 +- daddu v0,AT +- sltu t1,v0,AT +- sd v0,0(a0) +- daddu v0,t1,t0 +- +- dmultu t2,a3 +- subu a2,4 +- PTR_ADD a0,32 +- PTR_ADD a1,32 +- mflo AT +- mfhi t2 +- daddu v0,AT +- sltu t3,v0,AT +- sd v0,-24(a0) +- daddu v0,t3,t2 +- +- dmultu ta0,a3 +- mflo AT +- mfhi ta0 +- daddu v0,AT +- sltu ta1,v0,AT +- sd v0,-16(a0) +- daddu v0,ta1,ta0 +- +- +- dmultu ta2,a3 +- and ta0,a2,MINUS4 +- mflo AT +- mfhi ta2 +- daddu v0,AT +- sltu ta3,v0,AT +- sd v0,-8(a0) +- daddu v0,ta3,ta2 +- .set noreorder +- bgtzl ta0,.L_bn_mul_words_loop +- ld t0,0(a1) +- +- bnezl a2,.L_bn_mul_words_tail +- ld t0,0(a1) +- .set reorder +- +-.L_bn_mul_words_return: +- jr ra +- +-.L_bn_mul_words_tail: +- dmultu t0,a3 +- subu a2,1 +- mflo AT +- mfhi t0 +- daddu v0,AT +- sltu t1,v0,AT +- sd v0,0(a0) +- daddu v0,t1,t0 +- beqz a2,.L_bn_mul_words_return +- +- ld t0,8(a1) +- dmultu t0,a3 +- subu a2,1 +- mflo AT +- mfhi t0 +- daddu v0,AT +- sltu t1,v0,AT +- sd v0,8(a0) +- daddu v0,t1,t0 +- beqz a2,.L_bn_mul_words_return +- +- ld t0,16(a1) +- dmultu t0,a3 +- mflo AT +- mfhi t0 +- daddu v0,AT +- sltu t1,v0,AT +- sd v0,16(a0) +- daddu v0,t1,t0 +- jr ra +-END(bn_mul_words) +- +-.align 5 +-LEAF(bn_sqr_words) +- .set noreorder +- bgtzl a2,.L_bn_sqr_words_proceed +- ld t0,0(a1) +- jr ra +- move v0,zero +- .set reorder +- +-.L_bn_sqr_words_proceed: +- li MINUS4,-4 +- and ta0,a2,MINUS4 +- move v0,zero +- beqz ta0,.L_bn_sqr_words_tail +- +-.L_bn_sqr_words_loop: +- dmultu t0,t0 +- ld t2,8(a1) +- ld ta0,16(a1) +- ld ta2,24(a1) +- mflo t1 +- mfhi t0 +- sd t1,0(a0) +- sd t0,8(a0) +- +- dmultu t2,t2 +- subu a2,4 +- PTR_ADD a0,64 +- PTR_ADD a1,32 +- mflo t3 +- mfhi t2 +- sd t3,-48(a0) +- sd t2,-40(a0) +- +- dmultu ta0,ta0 +- mflo ta1 +- mfhi ta0 +- sd ta1,-32(a0) +- sd ta0,-24(a0) +- +- +- dmultu ta2,ta2 +- and ta0,a2,MINUS4 +- mflo ta3 +- mfhi ta2 +- sd ta3,-16(a0) +- sd ta2,-8(a0) +- +- .set noreorder +- bgtzl ta0,.L_bn_sqr_words_loop +- ld t0,0(a1) +- +- bnezl a2,.L_bn_sqr_words_tail +- ld t0,0(a1) +- .set reorder +- +-.L_bn_sqr_words_return: +- move v0,zero +- jr ra +- +-.L_bn_sqr_words_tail: +- dmultu t0,t0 +- subu a2,1 +- mflo t1 +- mfhi t0 +- sd t1,0(a0) +- sd t0,8(a0) +- beqz a2,.L_bn_sqr_words_return +- +- ld t0,8(a1) +- dmultu t0,t0 +- subu a2,1 +- mflo t1 +- mfhi t0 +- sd t1,16(a0) +- sd t0,24(a0) +- beqz a2,.L_bn_sqr_words_return +- +- ld t0,16(a1) +- dmultu t0,t0 +- mflo t1 +- mfhi t0 +- sd t1,32(a0) +- sd t0,40(a0) +- jr ra +-END(bn_sqr_words) +- +-.align 5 +-LEAF(bn_add_words) +- .set noreorder +- bgtzl a3,.L_bn_add_words_proceed +- ld t0,0(a1) +- jr ra +- move v0,zero +- .set reorder +- +-.L_bn_add_words_proceed: +- li MINUS4,-4 +- and AT,a3,MINUS4 +- move v0,zero +- beqz AT,.L_bn_add_words_tail +- +-.L_bn_add_words_loop: +- ld ta0,0(a2) +- subu a3,4 +- ld t1,8(a1) +- and AT,a3,MINUS4 +- ld t2,16(a1) +- PTR_ADD a2,32 +- ld t3,24(a1) +- PTR_ADD a0,32 +- ld ta1,-24(a2) +- PTR_ADD a1,32 +- ld ta2,-16(a2) +- ld ta3,-8(a2) +- daddu ta0,t0 +- sltu t8,ta0,t0 +- daddu t0,ta0,v0 +- sltu v0,t0,ta0 +- sd t0,-32(a0) +- daddu v0,t8 +- +- daddu ta1,t1 +- sltu t9,ta1,t1 +- daddu t1,ta1,v0 +- sltu v0,t1,ta1 +- sd t1,-24(a0) +- daddu v0,t9 +- +- daddu ta2,t2 +- sltu t8,ta2,t2 +- daddu t2,ta2,v0 +- sltu v0,t2,ta2 +- sd t2,-16(a0) +- daddu v0,t8 +- +- daddu ta3,t3 +- sltu t9,ta3,t3 +- daddu t3,ta3,v0 +- sltu v0,t3,ta3 +- sd t3,-8(a0) +- daddu v0,t9 +- +- .set noreorder +- bgtzl AT,.L_bn_add_words_loop +- ld t0,0(a1) +- +- bnezl a3,.L_bn_add_words_tail +- ld t0,0(a1) +- .set reorder +- +-.L_bn_add_words_return: +- jr ra +- +-.L_bn_add_words_tail: +- ld ta0,0(a2) +- daddu ta0,t0 +- subu a3,1 +- sltu t8,ta0,t0 +- daddu t0,ta0,v0 +- sltu v0,t0,ta0 +- sd t0,0(a0) +- daddu v0,t8 +- beqz a3,.L_bn_add_words_return +- +- ld t1,8(a1) +- ld ta1,8(a2) +- daddu ta1,t1 +- subu a3,1 +- sltu t9,ta1,t1 +- daddu t1,ta1,v0 +- sltu v0,t1,ta1 +- sd t1,8(a0) +- daddu v0,t9 +- beqz a3,.L_bn_add_words_return +- +- ld t2,16(a1) +- ld ta2,16(a2) +- daddu ta2,t2 +- sltu t8,ta2,t2 +- daddu t2,ta2,v0 +- sltu v0,t2,ta2 +- sd t2,16(a0) +- daddu v0,t8 +- jr ra +-END(bn_add_words) +- +-.align 5 +-LEAF(bn_sub_words) +- .set noreorder +- bgtzl a3,.L_bn_sub_words_proceed +- ld t0,0(a1) +- jr ra +- move v0,zero +- .set reorder +- +-.L_bn_sub_words_proceed: +- li MINUS4,-4 +- and AT,a3,MINUS4 +- move v0,zero +- beqz AT,.L_bn_sub_words_tail +- +-.L_bn_sub_words_loop: +- ld ta0,0(a2) +- subu a3,4 +- ld t1,8(a1) +- and AT,a3,MINUS4 +- ld t2,16(a1) +- PTR_ADD a2,32 +- ld t3,24(a1) +- PTR_ADD a0,32 +- ld ta1,-24(a2) +- PTR_ADD a1,32 +- ld ta2,-16(a2) +- ld ta3,-8(a2) +- sltu t8,t0,ta0 +- dsubu t0,ta0 +- dsubu ta0,t0,v0 +- sd ta0,-32(a0) +- MOVNZ (t0,v0,t8) +- +- sltu t9,t1,ta1 +- dsubu t1,ta1 +- dsubu ta1,t1,v0 +- sd ta1,-24(a0) +- MOVNZ (t1,v0,t9) +- +- +- sltu t8,t2,ta2 +- dsubu t2,ta2 +- dsubu ta2,t2,v0 +- sd ta2,-16(a0) +- MOVNZ (t2,v0,t8) +- +- sltu t9,t3,ta3 +- dsubu t3,ta3 +- dsubu ta3,t3,v0 +- sd ta3,-8(a0) +- MOVNZ (t3,v0,t9) +- +- .set noreorder +- bgtzl AT,.L_bn_sub_words_loop +- ld t0,0(a1) +- +- bnezl a3,.L_bn_sub_words_tail +- ld t0,0(a1) +- .set reorder +- +-.L_bn_sub_words_return: +- jr ra +- +-.L_bn_sub_words_tail: +- ld ta0,0(a2) +- subu a3,1 +- sltu t8,t0,ta0 +- dsubu t0,ta0 +- dsubu ta0,t0,v0 +- MOVNZ (t0,v0,t8) +- sd ta0,0(a0) +- beqz a3,.L_bn_sub_words_return +- +- ld t1,8(a1) +- subu a3,1 +- ld ta1,8(a2) +- sltu t9,t1,ta1 +- dsubu t1,ta1 +- dsubu ta1,t1,v0 +- MOVNZ (t1,v0,t9) +- sd ta1,8(a0) +- beqz a3,.L_bn_sub_words_return +- +- ld t2,16(a1) +- ld ta2,16(a2) +- sltu t8,t2,ta2 +- dsubu t2,ta2 +- dsubu ta2,t2,v0 +- MOVNZ (t2,v0,t8) +- sd ta2,16(a0) +- jr ra +-END(bn_sub_words) +- +-#undef MINUS4 +- +-.align 5 +-LEAF(bn_div_3_words) +- .set reorder +- move a3,a0 /* we know that bn_div_words doesn't +- * touch a3, ta2, ta3 and preserves a2 +- * so that we can save two arguments +- * and return address in registers +- * instead of stack:-) +- */ +- ld a0,(a3) +- move ta2,a1 +- ld a1,-8(a3) +- bne a0,a2,.L_bn_div_3_words_proceed +- li v0,-1 +- jr ra +-.L_bn_div_3_words_proceed: +- move ta3,ra +- bal bn_div_words +- move ra,ta3 +- dmultu ta2,v0 +- ld t2,-16(a3) +- move ta0,zero +- mfhi t1 +- mflo t0 +- sltu t8,t1,v1 +-.L_bn_div_3_words_inner_loop: +- bnez t8,.L_bn_div_3_words_inner_loop_done +- sgeu AT,t2,t0 +- seq t9,t1,v1 +- and AT,t9 +- sltu t3,t0,ta2 +- daddu v1,a2 +- dsubu t1,t3 +- dsubu t0,ta2 +- sltu t8,t1,v1 +- sltu ta0,v1,a2 +- or t8,ta0 +- .set noreorder +- beqzl AT,.L_bn_div_3_words_inner_loop +- dsubu v0,1 +- .set reorder +-.L_bn_div_3_words_inner_loop_done: +- jr ra +-END(bn_div_3_words) +- +-.align 5 +-LEAF(bn_div_words) +- .set noreorder +- bnezl a2,.L_bn_div_words_proceed +- move v1,zero +- jr ra +- li v0,-1 /* I'd rather signal div-by-zero +- * which can be done with 'break 7' */ +- +-.L_bn_div_words_proceed: +- bltz a2,.L_bn_div_words_body +- move t9,v1 +- dsll a2,1 +- bgtz a2,.-4 +- addu t9,1 +- +- .set reorder +- negu t1,t9 +- li t2,-1 +- dsll t2,t1 +- and t2,a0 +- dsrl AT,a1,t1 +- .set noreorder +- bnezl t2,.+8 +- break 6 /* signal overflow */ +- .set reorder +- dsll a0,t9 +- dsll a1,t9 +- or a0,AT +- +-#define QT ta0 +-#define HH ta1 +-#define DH v1 +-.L_bn_div_words_body: +- dsrl DH,a2,32 +- sgeu AT,a0,a2 +- .set noreorder +- bnezl AT,.+8 +- dsubu a0,a2 +- .set reorder +- +- li QT,-1 +- dsrl HH,a0,32 +- dsrl QT,32 /* q=0xffffffff */ +- beq DH,HH,.L_bn_div_words_skip_div1 +- ddivu zero,a0,DH +- mflo QT +-.L_bn_div_words_skip_div1: +- dmultu a2,QT +- dsll t3,a0,32 +- dsrl AT,a1,32 +- or t3,AT +- mflo t0 +- mfhi t1 +-.L_bn_div_words_inner_loop1: +- sltu t2,t3,t0 +- seq t8,HH,t1 +- sltu AT,HH,t1 +- and t2,t8 +- sltu v0,t0,a2 +- or AT,t2 +- .set noreorder +- beqz AT,.L_bn_div_words_inner_loop1_done +- dsubu t1,v0 +- dsubu t0,a2 +- b .L_bn_div_words_inner_loop1 +- dsubu QT,1 +- .set reorder +-.L_bn_div_words_inner_loop1_done: +- +- dsll a1,32 +- dsubu a0,t3,t0 +- dsll v0,QT,32 +- +- li QT,-1 +- dsrl HH,a0,32 +- dsrl QT,32 /* q=0xffffffff */ +- beq DH,HH,.L_bn_div_words_skip_div2 +- ddivu zero,a0,DH +- mflo QT +-.L_bn_div_words_skip_div2: +-#undef DH +- dmultu a2,QT +- dsll t3,a0,32 +- dsrl AT,a1,32 +- or t3,AT +- mflo t0 +- mfhi t1 +-.L_bn_div_words_inner_loop2: +- sltu t2,t3,t0 +- seq t8,HH,t1 +- sltu AT,HH,t1 +- and t2,t8 +- sltu v1,t0,a2 +- or AT,t2 +- .set noreorder +- beqz AT,.L_bn_div_words_inner_loop2_done +- dsubu t1,v1 +- dsubu t0,a2 +- b .L_bn_div_words_inner_loop2 +- dsubu QT,1 +- .set reorder +-.L_bn_div_words_inner_loop2_done: +-#undef HH +- +- dsubu a0,t3,t0 +- or v0,QT +- dsrl v1,a0,t9 /* v1 contains remainder if anybody wants it */ +- dsrl a2,t9 /* restore a2 */ +- jr ra +-#undef QT +-END(bn_div_words) +- +-#define a_0 t0 +-#define a_1 t1 +-#define a_2 t2 +-#define a_3 t3 +-#define b_0 ta0 +-#define b_1 ta1 +-#define b_2 ta2 +-#define b_3 ta3 +- +-#define a_4 s0 +-#define a_5 s2 +-#define a_6 s4 +-#define a_7 a1 /* once we load a[7] we don't need a anymore */ +-#define b_4 s1 +-#define b_5 s3 +-#define b_6 s5 +-#define b_7 a2 /* once we load b[7] we don't need b anymore */ +- +-#define t_1 t8 +-#define t_2 t9 +- +-#define c_1 v0 +-#define c_2 v1 +-#define c_3 a3 +- +-#define FRAME_SIZE 48 +- +-.align 5 +-LEAF(bn_mul_comba8) +- .set noreorder +- PTR_SUB sp,FRAME_SIZE +- .frame sp,64,ra +- .set reorder +- ld a_0,0(a1) /* If compiled with -mips3 option on +- * R5000 box assembler barks on this +- * line with "shouldn't have mult/div +- * as last instruction in bb (R10K +- * bug)" warning. If anybody out there +- * has a clue about how to circumvent +- * this do send me a note. +- * +- */ +- ld b_0,0(a2) +- ld a_1,8(a1) +- ld a_2,16(a1) +- ld a_3,24(a1) +- ld b_1,8(a2) +- ld b_2,16(a2) +- ld b_3,24(a2) +- dmultu a_0,b_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */ +- sd s0,0(sp) +- sd s1,8(sp) +- sd s2,16(sp) +- sd s3,24(sp) +- sd s4,32(sp) +- sd s5,40(sp) +- mflo c_1 +- mfhi c_2 +- +- dmultu a_0,b_1 /* mul_add_c(a[0],b[1],c2,c3,c1); */ +- ld a_4,32(a1) +- ld a_5,40(a1) +- ld a_6,48(a1) +- ld a_7,56(a1) +- ld b_4,32(a2) +- ld b_5,40(a2) +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu c_3,t_2,AT +- dmultu a_1,b_0 /* mul_add_c(a[1],b[0],c2,c3,c1); */ +- ld b_6,48(a2) +- ld b_7,56(a2) +- sd c_1,0(a0) /* r[0]=c1; */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu c_1,c_3,t_2 +- sd c_2,8(a0) /* r[1]=c2; */ +- +- dmultu a_2,b_0 /* mul_add_c(a[2],b[0],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- dmultu a_1,b_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu c_2,c_1,t_2 +- dmultu a_0,b_2 /* mul_add_c(a[0],b[2],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,16(a0) /* r[2]=c3; */ +- +- dmultu a_0,b_3 /* mul_add_c(a[0],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu c_3,c_2,t_2 +- dmultu a_1,b_2 /* mul_add_c(a[1],b[2],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_2,b_1 /* mul_add_c(a[2],b[1],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_3,b_0 /* mul_add_c(a[3],b[0],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,24(a0) /* r[3]=c1; */ +- +- dmultu a_4,b_0 /* mul_add_c(a[4],b[0],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu c_1,c_3,t_2 +- dmultu a_3,b_1 /* mul_add_c(a[3],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_2,b_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_1,b_3 /* mul_add_c(a[1],b[3],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_0,b_4 /* mul_add_c(a[0],b[4],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,32(a0) /* r[4]=c2; */ +- +- dmultu a_0,b_5 /* mul_add_c(a[0],b[5],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu c_2,c_1,t_2 +- dmultu a_1,b_4 /* mul_add_c(a[1],b[4],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_2,b_3 /* mul_add_c(a[2],b[3],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_3,b_2 /* mul_add_c(a[3],b[2],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_4,b_1 /* mul_add_c(a[4],b[1],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_5,b_0 /* mul_add_c(a[5],b[0],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,40(a0) /* r[5]=c3; */ +- +- dmultu a_6,b_0 /* mul_add_c(a[6],b[0],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu c_3,c_2,t_2 +- dmultu a_5,b_1 /* mul_add_c(a[5],b[1],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_4,b_2 /* mul_add_c(a[4],b[2],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_3,b_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_2,b_4 /* mul_add_c(a[2],b[4],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_1,b_5 /* mul_add_c(a[1],b[5],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_0,b_6 /* mul_add_c(a[0],b[6],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,48(a0) /* r[6]=c1; */ +- +- dmultu a_0,b_7 /* mul_add_c(a[0],b[7],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu c_1,c_3,t_2 +- dmultu a_1,b_6 /* mul_add_c(a[1],b[6],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_2,b_5 /* mul_add_c(a[2],b[5],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_3,b_4 /* mul_add_c(a[3],b[4],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_4,b_3 /* mul_add_c(a[4],b[3],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_5,b_2 /* mul_add_c(a[5],b[2],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_6,b_1 /* mul_add_c(a[6],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_7,b_0 /* mul_add_c(a[7],b[0],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,56(a0) /* r[7]=c2; */ +- +- dmultu a_7,b_1 /* mul_add_c(a[7],b[1],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu c_2,c_1,t_2 +- dmultu a_6,b_2 /* mul_add_c(a[6],b[2],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_5,b_3 /* mul_add_c(a[5],b[3],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_4,b_4 /* mul_add_c(a[4],b[4],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_3,b_5 /* mul_add_c(a[3],b[5],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_2,b_6 /* mul_add_c(a[2],b[6],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_1,b_7 /* mul_add_c(a[1],b[7],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,64(a0) /* r[8]=c3; */ +- +- dmultu a_2,b_7 /* mul_add_c(a[2],b[7],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu c_3,c_2,t_2 +- dmultu a_3,b_6 /* mul_add_c(a[3],b[6],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_4,b_5 /* mul_add_c(a[4],b[5],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_5,b_4 /* mul_add_c(a[5],b[4],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_6,b_3 /* mul_add_c(a[6],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_7,b_2 /* mul_add_c(a[7],b[2],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,72(a0) /* r[9]=c1; */ +- +- dmultu a_7,b_3 /* mul_add_c(a[7],b[3],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu c_1,c_3,t_2 +- dmultu a_6,b_4 /* mul_add_c(a[6],b[4],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_5,b_5 /* mul_add_c(a[5],b[5],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_4,b_6 /* mul_add_c(a[4],b[6],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_3,b_7 /* mul_add_c(a[3],b[7],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,80(a0) /* r[10]=c2; */ +- +- dmultu a_4,b_7 /* mul_add_c(a[4],b[7],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu c_2,c_1,t_2 +- dmultu a_5,b_6 /* mul_add_c(a[5],b[6],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_6,b_5 /* mul_add_c(a[6],b[5],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_7,b_4 /* mul_add_c(a[7],b[4],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,88(a0) /* r[11]=c3; */ +- +- dmultu a_7,b_5 /* mul_add_c(a[7],b[5],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu c_3,c_2,t_2 +- dmultu a_6,b_6 /* mul_add_c(a[6],b[6],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_5,b_7 /* mul_add_c(a[5],b[7],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,96(a0) /* r[12]=c1; */ +- +- dmultu a_6,b_7 /* mul_add_c(a[6],b[7],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu c_1,c_3,t_2 +- dmultu a_7,b_6 /* mul_add_c(a[7],b[6],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,104(a0) /* r[13]=c2; */ +- +- dmultu a_7,b_7 /* mul_add_c(a[7],b[7],c3,c1,c2); */ +- ld s0,0(sp) +- ld s1,8(sp) +- ld s2,16(sp) +- ld s3,24(sp) +- ld s4,32(sp) +- ld s5,40(sp) +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sd c_3,112(a0) /* r[14]=c3; */ +- sd c_1,120(a0) /* r[15]=c1; */ +- +- PTR_ADD sp,FRAME_SIZE +- +- jr ra +-END(bn_mul_comba8) +- +-.align 5 +-LEAF(bn_mul_comba4) +- .set reorder +- ld a_0,0(a1) +- ld b_0,0(a2) +- ld a_1,8(a1) +- ld a_2,16(a1) +- dmultu a_0,b_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */ +- ld a_3,24(a1) +- ld b_1,8(a2) +- ld b_2,16(a2) +- ld b_3,24(a2) +- mflo c_1 +- mfhi c_2 +- sd c_1,0(a0) +- +- dmultu a_0,b_1 /* mul_add_c(a[0],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu c_3,t_2,AT +- dmultu a_1,b_0 /* mul_add_c(a[1],b[0],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu c_1,c_3,t_2 +- sd c_2,8(a0) +- +- dmultu a_2,b_0 /* mul_add_c(a[2],b[0],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- dmultu a_1,b_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu c_2,c_1,t_2 +- dmultu a_0,b_2 /* mul_add_c(a[0],b[2],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,16(a0) +- +- dmultu a_0,b_3 /* mul_add_c(a[0],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu c_3,c_2,t_2 +- dmultu a_1,b_2 /* mul_add_c(a[1],b[2],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_2,b_1 /* mul_add_c(a[2],b[1],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_3,b_0 /* mul_add_c(a[3],b[0],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,24(a0) +- +- dmultu a_3,b_1 /* mul_add_c(a[3],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu c_1,c_3,t_2 +- dmultu a_2,b_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_1,b_3 /* mul_add_c(a[1],b[3],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,32(a0) +- +- dmultu a_2,b_3 /* mul_add_c(a[2],b[3],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu c_2,c_1,t_2 +- dmultu a_3,b_2 /* mul_add_c(a[3],b[2],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,40(a0) +- +- dmultu a_3,b_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sd c_1,48(a0) +- sd c_2,56(a0) +- +- jr ra +-END(bn_mul_comba4) +- +-#undef a_4 +-#undef a_5 +-#undef a_6 +-#undef a_7 +-#define a_4 b_0 +-#define a_5 b_1 +-#define a_6 b_2 +-#define a_7 b_3 +- +-.align 5 +-LEAF(bn_sqr_comba8) +- .set reorder +- ld a_0,0(a1) +- ld a_1,8(a1) +- ld a_2,16(a1) +- ld a_3,24(a1) +- +- dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */ +- ld a_4,32(a1) +- ld a_5,40(a1) +- ld a_6,48(a1) +- ld a_7,56(a1) +- mflo c_1 +- mfhi c_2 +- sd c_1,0(a0) +- +- dmultu a_0,a_1 /* mul_add_c2(a[0],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt c_1,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu c_3,t_2,AT +- sd c_2,8(a0) +- +- dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt c_2,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,16(a0) +- +- dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt c_3,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_1,a_2 /* mul_add_c2(a[1],b[2],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_3,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,24(a0) +- +- dmultu a_4,a_0 /* mul_add_c2(a[4],b[0],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt c_1,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_1,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,32(a0) +- +- dmultu a_0,a_5 /* mul_add_c2(a[0],b[5],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt c_2,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_1,a_4 /* mul_add_c2(a[1],b[4],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_2,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_2,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,40(a0) +- +- dmultu a_6,a_0 /* mul_add_c2(a[6],b[0],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt c_3,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_5,a_1 /* mul_add_c2(a[5],b[1],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_3,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_4,a_2 /* mul_add_c2(a[4],b[2],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_3,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,48(a0) +- +- dmultu a_0,a_7 /* mul_add_c2(a[0],b[7],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt c_1,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_1,a_6 /* mul_add_c2(a[1],b[6],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_1,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_2,a_5 /* mul_add_c2(a[2],b[5],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_1,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_3,a_4 /* mul_add_c2(a[3],b[4],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_1,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,56(a0) +- +- dmultu a_7,a_1 /* mul_add_c2(a[7],b[1],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt c_2,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_6,a_2 /* mul_add_c2(a[6],b[2],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_2,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_5,a_3 /* mul_add_c2(a[5],b[3],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_2,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_4,a_4 /* mul_add_c(a[4],b[4],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,64(a0) +- +- dmultu a_2,a_7 /* mul_add_c2(a[2],b[7],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt c_3,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_3,a_6 /* mul_add_c2(a[3],b[6],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_3,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_4,a_5 /* mul_add_c2(a[4],b[5],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_3,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,72(a0) +- +- dmultu a_7,a_3 /* mul_add_c2(a[7],b[3],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt c_1,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_6,a_4 /* mul_add_c2(a[6],b[4],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_1,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_5,a_5 /* mul_add_c(a[5],b[5],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,80(a0) +- +- dmultu a_4,a_7 /* mul_add_c2(a[4],b[7],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt c_2,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_5,a_6 /* mul_add_c2(a[5],b[6],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_2,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,88(a0) +- +- dmultu a_7,a_5 /* mul_add_c2(a[7],b[5],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt c_3,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_6,a_6 /* mul_add_c(a[6],b[6],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,96(a0) +- +- dmultu a_6,a_7 /* mul_add_c2(a[6],b[7],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt c_1,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,104(a0) +- +- dmultu a_7,a_7 /* mul_add_c(a[7],b[7],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sd c_3,112(a0) +- sd c_1,120(a0) +- +- jr ra +-END(bn_sqr_comba8) +- +-.align 5 +-LEAF(bn_sqr_comba4) +- .set reorder +- ld a_0,0(a1) +- ld a_1,8(a1) +- ld a_2,16(a1) +- ld a_3,24(a1) +- dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */ +- mflo c_1 +- mfhi c_2 +- sd c_1,0(a0) +- +- dmultu a_0,a_1 /* mul_add_c2(a[0],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt c_1,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu c_3,t_2,AT +- sd c_2,8(a0) +- +- dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt c_2,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,16(a0) +- +- dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt c_3,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- dmultu a_1,a_2 /* mul_add_c(a2[1],b[2],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- slt AT,t_2,zero +- daddu c_3,AT +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sltu AT,c_2,t_2 +- daddu c_3,AT +- sd c_1,24(a0) +- +- dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- slt c_1,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */ +- mflo t_1 +- mfhi t_2 +- daddu c_2,t_1 +- sltu AT,c_2,t_1 +- daddu t_2,AT +- daddu c_3,t_2 +- sltu AT,c_3,t_2 +- daddu c_1,AT +- sd c_2,32(a0) +- +- dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */ +- mflo t_1 +- mfhi t_2 +- slt c_2,t_2,zero +- dsll t_2,1 +- slt a2,t_1,zero +- daddu t_2,a2 +- dsll t_1,1 +- daddu c_3,t_1 +- sltu AT,c_3,t_1 +- daddu t_2,AT +- daddu c_1,t_2 +- sltu AT,c_1,t_2 +- daddu c_2,AT +- sd c_3,40(a0) +- +- dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */ +- mflo t_1 +- mfhi t_2 +- daddu c_1,t_1 +- sltu AT,c_1,t_1 +- daddu t_2,AT +- daddu c_2,t_2 +- sd c_1,48(a0) +- sd c_2,56(a0) +- +- jr ra +-END(bn_sqr_comba4) +diff --git a/crypto/bn/asm/x86_64-gcc.c b/crypto/bn/asm/x86_64-gcc.c +index 31476ab..2d39407 100644 +--- a/crypto/bn/asm/x86_64-gcc.c ++++ b/crypto/bn/asm/x86_64-gcc.c +@@ -273,6 +273,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) + /* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ + /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ + ++/* ++ * Keep in mind that carrying into high part of multiplication result ++ * can not overflow, because it cannot be all-ones. ++ */ + #if 0 + /* original macros are kept for reference purposes */ + #define mul_add_c(a,b,c0,c1,c2) { \ +@@ -287,10 +291,10 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) + BN_ULONG ta=(a),tb=(b),t0; \ + t1 = BN_UMULT_HIGH(ta,tb); \ + t0 = ta * tb; \ +- t2 = t1+t1; c2 += (t2neg=rand_neg(); ++ BN_sqr(c,a,ctx); + if (bp != NULL) + { + if (!results) + { +- BN_print(bp,&a); ++ BN_print(bp,a); + BIO_puts(bp," * "); +- BN_print(bp,&a); ++ BN_print(bp,a); + BIO_puts(bp," - "); + } +- BN_print(bp,&c); ++ BN_print(bp,c); + BIO_puts(bp,"\n"); + } +- BN_div(&d,&e,&c,&a,ctx); +- BN_sub(&d,&d,&a); +- if(!BN_is_zero(&d) || !BN_is_zero(&e)) +- { +- fprintf(stderr,"Square test failed!\n"); +- return 0; +- } ++ BN_div(d,e,c,a,ctx); ++ BN_sub(d,d,a); ++ if(!BN_is_zero(d) || !BN_is_zero(e)) ++ { ++ fprintf(stderr,"Square test failed!\n"); ++ goto err; ++ } + } +- BN_free(&a); +- BN_free(&c); +- BN_free(&d); +- BN_free(&e); +- return(1); ++ ++ /* Regression test for a BN_sqr overflow bug. */ ++ BN_hex2bn(&a, ++ "80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000"); ++ BN_sqr(c, a, ctx); ++ if (bp != NULL) ++ { ++ if (!results) ++ { ++ BN_print(bp,a); ++ BIO_puts(bp," * "); ++ BN_print(bp,a); ++ BIO_puts(bp," - "); ++ } ++ BN_print(bp,c); ++ BIO_puts(bp,"\n"); ++ } ++ BN_mul(d, a, a, ctx); ++ if (BN_cmp(c, d)) ++ { ++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce " ++ "different results!\n"); ++ goto err; ++ } ++ ++ /* Regression test for a BN_sqr overflow bug. */ ++ BN_hex2bn(&a, ++ "80000000000000000000000080000001FFFFFFFE000000000000000000000000"); ++ BN_sqr(c, a, ctx); ++ if (bp != NULL) ++ { ++ if (!results) ++ { ++ BN_print(bp,a); ++ BIO_puts(bp," * "); ++ BN_print(bp,a); ++ BIO_puts(bp," - "); ++ } ++ BN_print(bp,c); ++ BIO_puts(bp,"\n"); ++ } ++ BN_mul(d, a, a, ctx); ++ if (BN_cmp(c, d)) ++ { ++ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce " ++ "different results!\n"); ++ goto err; ++ } ++ ret = 1; ++err: ++ if (a != NULL) BN_free(a); ++ if (c != NULL) BN_free(c); ++ if (d != NULL) BN_free(d); ++ if (e != NULL) BN_free(e); ++ return ret; + } + + int test_mont(BIO *bp, BN_CTX *ctx) +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3571.patch b/SOURCES/openssl-1.0.1e-cve-2014-3571.patch new file mode 100755 index 00000000..9c93b7f5 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3571.patch @@ -0,0 +1,34 @@ +diff -up openssl-1.0.1e/ssl/d1_pkt.c.dtls1-reads openssl-1.0.1e/ssl/d1_pkt.c +--- openssl-1.0.1e/ssl/d1_pkt.c.dtls1-reads 2015-01-12 17:31:41.647213706 +0100 ++++ openssl-1.0.1e/ssl/d1_pkt.c 2015-01-12 17:38:21.708261411 +0100 +@@ -641,8 +641,6 @@ again: + /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ + i=rr->length; + n=ssl3_read_n(s,i,i,1); +- if (n <= 0) return(n); /* error or non-blocking io */ +- + /* this packet contained a partial record, dump it */ + if ( n != i) + { +@@ -677,7 +675,8 @@ again: + * would be dropped unnecessarily. + */ + if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && +- *p == SSL3_MT_CLIENT_HELLO) && ++ s->packet_length > DTLS1_RT_HEADER_LENGTH && ++ s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && + !dtls1_record_replay_check(s, bitmap)) + { + rr->length = 0; +diff -up openssl-1.0.1e/ssl/s3_pkt.c.dtls1-reads openssl-1.0.1e/ssl/s3_pkt.c +--- openssl-1.0.1e/ssl/s3_pkt.c.dtls1-reads 2015-01-12 17:31:41.680214453 +0100 ++++ openssl-1.0.1e/ssl/s3_pkt.c 2015-01-12 17:38:06.721922482 +0100 +@@ -182,6 +182,8 @@ int ssl3_read_n(SSL *s, int n, int max, + * at once (as long as it fits into the buffer). */ + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) + { ++ if (left == 0 && extend) ++ return 0; + if (left > 0 && n > left) + n = left; + } diff --git a/SOURCES/openssl-1.0.1e-cve-2014-3572.patch b/SOURCES/openssl-1.0.1e-cve-2014-3572.patch new file mode 100755 index 00000000..013876b9 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-3572.patch @@ -0,0 +1,51 @@ +diff -up openssl-1.0.1e/ssl/s3_clnt.c.ecdh-downgrade openssl-1.0.1e/ssl/s3_clnt.c +--- openssl-1.0.1e/ssl/s3_clnt.c.ecdh-downgrade 2015-01-12 16:37:49.978126895 +0100 ++++ openssl-1.0.1e/ssl/s3_clnt.c 2015-01-12 17:02:01.740959687 +0100 +@@ -1287,6 +1287,8 @@ int ssl3_get_key_exchange(SSL *s) + int encoded_pt_len = 0; + #endif + ++ EVP_MD_CTX_init(&md_ctx); ++ + /* use same message size as in ssl3_get_certificate_request() + * as ServerKeyExchange message may be skipped */ + n=s->method->ssl_get_message(s, +@@ -1297,14 +1299,26 @@ int ssl3_get_key_exchange(SSL *s) + &ok); + if (!ok) return((int)n); + ++ alg_k=s->s3->tmp.new_cipher->algorithm_mkey; ++ + if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) + { ++ /* ++ * Can't skip server key exchange if this is an ephemeral ++ * ciphersuite. ++ */ ++ if (alg_k & (SSL_kEDH|SSL_kEECDH)) ++ { ++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); ++ al = SSL_AD_UNEXPECTED_MESSAGE; ++ goto f_err; ++ } + #ifndef OPENSSL_NO_PSK + /* In plain PSK ciphersuite, ServerKeyExchange can be + omitted if no identity hint is sent. Set + session->sess_cert anyway to avoid problems + later.*/ +- if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) ++ if (alg_k & SSL_kPSK) + { + s->session->sess_cert=ssl_sess_cert_new(); + if (s->ctx->psk_identity_hint) +@@ -1347,9 +1361,8 @@ int ssl3_get_key_exchange(SSL *s) + } + + param_len=0; +- alg_k=s->s3->tmp.new_cipher->algorithm_mkey; ++ + alg_a=s->s3->tmp.new_cipher->algorithm_auth; +- EVP_MD_CTX_init(&md_ctx); + + #ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) diff --git a/SOURCES/openssl-1.0.1e-cve-2014-8176.patch b/SOURCES/openssl-1.0.1e-cve-2014-8176.patch new file mode 100755 index 00000000..052b907a --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-8176.patch @@ -0,0 +1,34 @@ +From bcc311668ede6ffdcd6dc5a65454a548b5404fcc Mon Sep 17 00:00:00 2001 +From: zhu qun-ying +Date: Mon, 2 Jun 2014 14:38:52 +0100 +Subject: [PATCH] Free up s->d1->buffered_app_data.q properly. + +PR#3286 +(cherry picked from commit 71e95000afb2227fe5cac1c79ae884338bcd8d0b) +--- + ssl/d1_lib.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c +index 106939f..6bde16f 100644 +--- a/ssl/d1_lib.c ++++ b/ssl/d1_lib.c +@@ -176,9 +176,12 @@ static void dtls1_clear_queues(SSL *s) + + while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) + { +- frag = (hm_fragment *)item->data; +- OPENSSL_free(frag->fragment); +- OPENSSL_free(frag); ++ rdata = (DTLS1_RECORD_DATA *) item->data; ++ if (rdata->rbuf.buf) ++ { ++ OPENSSL_free(rdata->rbuf.buf); ++ } ++ OPENSSL_free(item->data); + pitem_free(item); + } + } +-- +2.1.0 + diff --git a/SOURCES/openssl-1.0.1e-cve-2014-8275.patch b/SOURCES/openssl-1.0.1e-cve-2014-8275.patch new file mode 100755 index 00000000..91041ac4 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2014-8275.patch @@ -0,0 +1,202 @@ +diff -up openssl-1.0.1e/crypto/asn1/a_bitstr.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/a_bitstr.c +--- openssl-1.0.1e/crypto/asn1/a_bitstr.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/a_bitstr.c 2015-01-13 12:23:36.090478923 +0100 +@@ -136,11 +136,16 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN + + p= *pp; + i= *(p++); ++ if (i > 7) ++ { ++ i=ASN1_R_INVALID_BIT_STRING_BITS_LEFT; ++ goto err; ++ } + /* We do this to preserve the settings. If we modify + * the settings, via the _set_bit function, we will recalculate + * on output */ + ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ +- ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */ ++ ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|i); /* set */ + + if (len-- > 1) /* using one because of the bits left byte */ + { +diff -up openssl-1.0.1e/crypto/asn1/asn1_err.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/asn1_err.c +--- openssl-1.0.1e/crypto/asn1/asn1_err.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/asn1_err.c 2015-01-13 12:23:36.090478923 +0100 +@@ -246,6 +246,7 @@ static ERR_STRING_DATA ASN1_str_reasons[ + {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"}, + {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"}, + {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"}, ++{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),"invalid bit string bits left"}, + {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"}, + {ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"}, + {ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"}, +diff -up openssl-1.0.1e/crypto/asn1/asn1.h.cert-fingerprint openssl-1.0.1e/crypto/asn1/asn1.h +--- openssl-1.0.1e/crypto/asn1/asn1.h.cert-fingerprint 2015-01-13 11:44:11.999013082 +0100 ++++ openssl-1.0.1e/crypto/asn1/asn1.h 2015-01-13 12:23:36.090478923 +0100 +@@ -776,7 +776,7 @@ DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, + int ASN1_TYPE_get(ASN1_TYPE *a); + void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); + int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b); ++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + + ASN1_OBJECT * ASN1_OBJECT_new(void ); + void ASN1_OBJECT_free(ASN1_OBJECT *a); +@@ -1329,6 +1329,7 @@ void ERR_load_ASN1_strings(void); + #define ASN1_R_ILLEGAL_TIME_VALUE 184 + #define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 + #define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 ++#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 + #define ASN1_R_INVALID_BMPSTRING_LENGTH 129 + #define ASN1_R_INVALID_DIGIT 130 + #define ASN1_R_INVALID_MIME_TYPE 205 +diff -up openssl-1.0.1e/crypto/asn1/a_type.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/a_type.c +--- openssl-1.0.1e/crypto/asn1/a_type.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/a_type.c 2015-01-13 12:43:36.779633480 +0100 +@@ -113,7 +113,7 @@ IMPLEMENT_STACK_OF(ASN1_TYPE) + IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) + + /* Returns 0 if they are equal, != 0 otherwise. */ +-int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b) ++int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) + { + int result = -1; + +diff -up openssl-1.0.1e/crypto/asn1/a_verify.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/a_verify.c +--- openssl-1.0.1e/crypto/asn1/a_verify.c.cert-fingerprint 2015-01-13 11:44:12.308020070 +0100 ++++ openssl-1.0.1e/crypto/asn1/a_verify.c 2015-01-13 11:44:12.413022445 +0100 +@@ -93,6 +93,12 @@ int ASN1_verify(i2d_of_void *i2d, X509_A + ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } ++ ++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) ++ { ++ ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); ++ goto err; ++ } + + inl=i2d(data,NULL); + buf_in=OPENSSL_malloc((unsigned int)inl); +@@ -149,6 +155,12 @@ int ASN1_item_verify(const ASN1_ITEM *it + return -1; + } + ++ if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) ++ { ++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); ++ return -1; ++ } ++ + EVP_MD_CTX_init(&ctx); + + /* Convert signature OID into digest and public key OIDs */ +diff -up openssl-1.0.1e/crypto/asn1/x_algor.c.cert-fingerprint openssl-1.0.1e/crypto/asn1/x_algor.c +--- openssl-1.0.1e/crypto/asn1/x_algor.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/x_algor.c 2015-01-13 12:43:36.780633502 +0100 +@@ -142,3 +142,14 @@ void X509_ALGOR_set_md(X509_ALGOR *alg, + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + + } ++ ++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) ++ { ++ int rv; ++ rv = OBJ_cmp(a->algorithm, b->algorithm); ++ if (rv) ++ return rv; ++ if (!a->parameter && !b->parameter) ++ return 0; ++ return ASN1_TYPE_cmp(a->parameter, b->parameter); ++ } +diff -up openssl-1.0.1e/crypto/dsa/dsa_asn1.c.cert-fingerprint openssl-1.0.1e/crypto/dsa/dsa_asn1.c +--- openssl-1.0.1e/crypto/dsa/dsa_asn1.c.cert-fingerprint 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_asn1.c 2015-01-13 11:44:12.414022468 +0100 +@@ -176,13 +176,25 @@ int DSA_verify(int type, const unsigned + const unsigned char *sigbuf, int siglen, DSA *dsa) + { + DSA_SIG *s; ++ const unsigned char *p = sigbuf; ++ unsigned char *der = NULL; ++ int derlen = -1; + int ret=-1; + + s = DSA_SIG_new(); + if (s == NULL) return(ret); +- if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; ++ if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err; ++ /* Ensure signature uses DER and doesn't have trailing garbage */ ++ derlen = i2d_DSA_SIG(s, &der); ++ if (derlen != siglen || memcmp(sigbuf, der, derlen)) ++ goto err; + ret=DSA_do_verify(dgst,dgst_len,s,dsa); + err: ++ if (derlen > 0) ++ { ++ OPENSSL_cleanse(der, derlen); ++ OPENSSL_free(der); ++ } + DSA_SIG_free(s); + return(ret); + } +diff -up openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c.cert-fingerprint openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c +--- openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c.cert-fingerprint 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/crypto/ecdsa/ecs_vrf.c 2015-01-13 11:44:12.414022468 +0100 +@@ -57,6 +57,7 @@ + */ + + #include "ecs_locl.h" ++#include "cryptlib.h" + #ifndef OPENSSL_NO_ENGINE + #include + #endif +@@ -84,13 +85,25 @@ int ECDSA_verify(int type, const unsigne + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) + { + ECDSA_SIG *s; ++ const unsigned char *p = sigbuf; ++ unsigned char *der = NULL; ++ int derlen = -1; + int ret=-1; + + s = ECDSA_SIG_new(); + if (s == NULL) return(ret); +- if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err; ++ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) goto err; ++ /* Ensure signature uses DER and doesn't have trailing garbage */ ++ derlen = i2d_ECDSA_SIG(s, &der); ++ if (derlen != sig_len || memcmp(sigbuf, der, derlen)) ++ goto err; + ret=ECDSA_do_verify(dgst, dgst_len, s, eckey); + err: ++ if (derlen > 0) ++ { ++ OPENSSL_cleanse(der, derlen); ++ OPENSSL_free(der); ++ } + ECDSA_SIG_free(s); + return(ret); + } +diff -up openssl-1.0.1e/crypto/x509/x_all.c.cert-fingerprint openssl-1.0.1e/crypto/x509/x_all.c +--- openssl-1.0.1e/crypto/x509/x_all.c.cert-fingerprint 2015-01-13 11:44:12.330020568 +0100 ++++ openssl-1.0.1e/crypto/x509/x_all.c 2015-01-13 11:44:12.414022468 +0100 +@@ -72,6 +72,8 @@ + + int X509_verify(X509 *a, EVP_PKEY *r) + { ++ if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) ++ return 0; + return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF),a->sig_alg, + a->signature,a->cert_info,r)); + } +diff -up openssl-1.0.1e/crypto/x509/x509.h.cert-fingerprint openssl-1.0.1e/crypto/x509/x509.h +--- openssl-1.0.1e/crypto/x509/x509.h.cert-fingerprint 2015-01-13 11:44:12.126015954 +0100 ++++ openssl-1.0.1e/crypto/x509/x509.h 2015-01-13 12:43:36.780633502 +0100 +@@ -768,6 +768,7 @@ int X509_ALGOR_set0(X509_ALGOR *alg, ASN + void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor); + void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); ++int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + + X509_NAME *X509_NAME_dup(X509_NAME *xn); + X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0204.patch b/SOURCES/openssl-1.0.1e-cve-2015-0204.patch new file mode 100755 index 00000000..527f7c56 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0204.patch @@ -0,0 +1,158 @@ +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_options.pod.rsa-ephemeral openssl-1.0.1e/doc/ssl/SSL_CTX_set_options.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_options.pod.rsa-ephemeral 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_options.pod 2015-01-13 11:15:25.096957795 +0100 +@@ -151,15 +151,7 @@ temporary/ephemeral DH parameters are us + + =item SSL_OP_EPHEMERAL_RSA + +-Always use ephemeral (temporary) RSA key when doing RSA operations +-(see L). +-According to the specifications this is only done, when a RSA key +-can only be used for signature operations (namely under export ciphers +-with restricted RSA keylength). By setting this option, ephemeral +-RSA keys are always used. This option breaks compatibility with the +-SSL/TLS specifications and may lead to interoperability problems with +-clients and should therefore never be used. Ciphers with EDH (ephemeral +-Diffie-Hellman) key exchange should be used instead. ++This option is no longer implemented and is treated as no op. + + =item SSL_OP_CIPHER_SERVER_PREFERENCE + +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod.rsa-ephemeral openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod.rsa-ephemeral 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_rsa_callback.pod 2015-01-13 11:15:25.096957795 +0100 +@@ -74,21 +74,14 @@ exchange and use EDH (Ephemeral Diffie-H + in order to achieve forward secrecy (see + L). + +-On OpenSSL servers ephemeral RSA key exchange is therefore disabled by default +-and must be explicitly enabled using the SSL_OP_EPHEMERAL_RSA option of +-L, violating the TLS/SSL +-standard. When ephemeral RSA key exchange is required for export ciphers, +-it will automatically be used without this option! +- +-An application may either directly specify the key or can supply the key via +-a callback function. The callback approach has the advantage, that the +-callback may generate the key only in case it is actually needed. As the +-generation of a RSA key is however costly, it will lead to a significant +-delay in the handshake procedure. Another advantage of the callback function +-is that it can supply keys of different size (e.g. for SSL_OP_EPHEMERAL_RSA +-usage) while the explicit setting of the key is only useful for key size of +-512 bits to satisfy the export restricted ciphers and does give away key length +-if a longer key would be allowed. ++An application may either directly specify the key or can supply the key via a ++callback function. The callback approach has the advantage, that the callback ++may generate the key only in case it is actually needed. As the generation of a ++RSA key is however costly, it will lead to a significant delay in the handshake ++procedure. Another advantage of the callback function is that it can supply ++keys of different size while the explicit setting of the key is only useful for ++key size of 512 bits to satisfy the export restricted ciphers and does give ++away key length if a longer key would be allowed. + + The B is called with the B needed and + the B information. The B flag is set, when the +diff -up openssl-1.0.1e/CHANGES.rsa-ephemeral openssl-1.0.1e/CHANGES +diff -up openssl-1.0.1e/ssl/d1_srvr.c.rsa-ephemeral openssl-1.0.1e/ssl/d1_srvr.c +--- openssl-1.0.1e/ssl/d1_srvr.c.rsa-ephemeral 2015-01-12 17:49:04.912808002 +0100 ++++ openssl-1.0.1e/ssl/d1_srvr.c 2015-01-13 11:15:25.096957795 +0100 +@@ -450,24 +450,15 @@ int dtls1_accept(SSL *s) + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + +- /* clear this, it may get reset by +- * send_server_key_exchange */ +- if ((s->options & SSL_OP_EPHEMERAL_RSA) +-#ifndef OPENSSL_NO_KRB5 +- && !(alg_k & SSL_kKRB5) +-#endif /* OPENSSL_NO_KRB5 */ +- ) +- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key +- * even when forbidden by protocol specs +- * (handshake may fail as clients are not required to +- * be able to handle this) */ +- s->s3->tmp.use_rsa_tmp=1; +- else +- s->s3->tmp.use_rsa_tmp=0; ++ /* ++ * clear this, it may get reset by ++ * send_server_key_exchange ++ */ ++ s->s3->tmp.use_rsa_tmp=0; + + /* only send if a DH key exchange or + * RSA but we have a sign only certificate */ +- if (s->s3->tmp.use_rsa_tmp ++ if (0 + /* PSK: send ServerKeyExchange if PSK identity + * hint if provided */ + #ifndef OPENSSL_NO_PSK +diff -up openssl-1.0.1e/ssl/ssl.h.rsa-ephemeral openssl-1.0.1e/ssl/ssl.h +--- openssl-1.0.1e/ssl/ssl.h.rsa-ephemeral 2015-01-12 17:49:04.936808545 +0100 ++++ openssl-1.0.1e/ssl/ssl.h 2015-01-13 11:15:25.098957840 +0100 +@@ -587,9 +587,8 @@ struct ssl_session_st + #define SSL_OP_SINGLE_ECDH_USE 0x00080000L + /* If set, always create a new key when using tmp_dh parameters */ + #define SSL_OP_SINGLE_DH_USE 0x00100000L +-/* Set to always use the tmp_rsa key when doing RSA operations, +- * even when this violates protocol specs */ +-#define SSL_OP_EPHEMERAL_RSA 0x00200000L ++/* Does nothing: retained for compatibiity */ ++#define SSL_OP_EPHEMERAL_RSA 0x0 + /* Set on servers to choose the cipher according to the server's + * preferences */ + #define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L +diff -up openssl-1.0.1e/ssl/s3_clnt.c.rsa-ephemeral openssl-1.0.1e/ssl/s3_clnt.c +--- openssl-1.0.1e/ssl/s3_clnt.c.rsa-ephemeral 2015-01-12 17:49:04.946808771 +0100 ++++ openssl-1.0.1e/ssl/s3_clnt.c 2015-01-13 11:15:25.097957817 +0100 +@@ -1492,6 +1492,13 @@ int ssl3_get_key_exchange(SSL *s) + #ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) + { ++ /* Temporary RSA keys only allowed in export ciphersuites */ ++ if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) ++ { ++ al=SSL_AD_UNEXPECTED_MESSAGE; ++ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE); ++ goto f_err; ++ } + if ((rsa=RSA_new()) == NULL) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); +diff -up openssl-1.0.1e/ssl/s3_srvr.c.rsa-ephemeral openssl-1.0.1e/ssl/s3_srvr.c +--- openssl-1.0.1e/ssl/s3_srvr.c.rsa-ephemeral 2015-01-12 17:51:32.044135496 +0100 ++++ openssl-1.0.1e/ssl/s3_srvr.c 2015-01-13 11:15:25.098957840 +0100 +@@ -441,20 +441,11 @@ int ssl3_accept(SSL *s) + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + +- /* clear this, it may get reset by +- * send_server_key_exchange */ +- if ((s->options & SSL_OP_EPHEMERAL_RSA) +-#ifndef OPENSSL_NO_KRB5 +- && !(alg_k & SSL_kKRB5) +-#endif /* OPENSSL_NO_KRB5 */ +- ) +- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key +- * even when forbidden by protocol specs +- * (handshake may fail as clients are not required to +- * be able to handle this) */ +- s->s3->tmp.use_rsa_tmp=1; +- else +- s->s3->tmp.use_rsa_tmp=0; ++ /* ++ * clear this, it may get reset by ++ * send_server_key_exchange ++ */ ++ s->s3->tmp.use_rsa_tmp=0; + + + /* only send if a DH key exchange, fortezza or +@@ -468,7 +459,7 @@ int ssl3_accept(SSL *s) + * server certificate contains the server's + * public key for key exchange. + */ +- if (s->s3->tmp.use_rsa_tmp ++ if (0 + /* PSK: send ServerKeyExchange if PSK identity + * hint if provided */ + #ifndef OPENSSL_NO_PSK diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0205.patch b/SOURCES/openssl-1.0.1e-cve-2015-0205.patch new file mode 100755 index 00000000..ff378ae4 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0205.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1e/ssl/s3_srvr.c.dh-unauthenticated openssl-1.0.1e/ssl/s3_srvr.c +--- openssl-1.0.1e/ssl/s3_srvr.c.dh-unauthenticated 2015-01-12 17:49:04.930808409 +0100 ++++ openssl-1.0.1e/ssl/s3_srvr.c 2015-01-13 11:15:25.098957840 +0100 +@@ -2951,7 +2951,7 @@ int ssl3_get_cert_verify(SSL *s) + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) + { + s->s3->tmp.reuse_message=1; +- if ((peer != NULL) && (type & EVP_PKT_SIGN)) ++ if (peer != NULL) + { + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE); diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0206.patch b/SOURCES/openssl-1.0.1e-cve-2015-0206.patch new file mode 100755 index 00000000..e2d17186 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0206.patch @@ -0,0 +1,116 @@ +diff -up openssl-1.0.1e/ssl/d1_pkt.c.dtls-recleak openssl-1.0.1e/ssl/d1_pkt.c +--- openssl-1.0.1e/ssl/d1_pkt.c.dtls-rec-leak 2015-01-13 11:44:12.410022377 +0100 ++++ openssl-1.0.1e/ssl/d1_pkt.c 2015-01-13 11:50:40.062789458 +0100 +@@ -212,7 +212,7 @@ dtls1_buffer_record(SSL *s, record_pqueu + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; +- ++ + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); + item = pitem_new(priority, rdata); + if (rdata == NULL || item == NULL) +@@ -239,14 +239,6 @@ dtls1_buffer_record(SSL *s, record_pqueu + } + #endif + +- /* insert should not fail, since duplicates are dropped */ +- if (pqueue_insert(queue->q, item) == NULL) +- { +- OPENSSL_free(rdata); +- pitem_free(item); +- return(0); +- } +- + s->packet = NULL; + s->packet_length = 0; + memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); +@@ -255,11 +247,24 @@ dtls1_buffer_record(SSL *s, record_pqueu + if (!ssl3_setup_buffers(s)) + { + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); ++ if (rdata->rbuf.buf != NULL) ++ OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); +- return(0); ++ return(-1); + } +- ++ ++ /* insert should not fail, since duplicates are dropped */ ++ if (pqueue_insert(queue->q, item) == NULL) ++ { ++ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); ++ if (rdata->rbuf.buf != NULL) ++ OPENSSL_free(rdata->rbuf.buf); ++ OPENSSL_free(rdata); ++ pitem_free(item); ++ return(-1); ++ } ++ + return(1); + } + +@@ -313,8 +318,9 @@ dtls1_process_buffered_records(SSL *s) + dtls1_get_unprocessed_record(s); + if ( ! dtls1_process_record(s)) + return(0); +- dtls1_buffer_record(s, &(s->d1->processed_rcds), +- s->s3->rrec.seq_num); ++ if(dtls1_buffer_record(s, &(s->d1->processed_rcds), ++ s->s3->rrec.seq_num)<0) ++ return -1; + } + } + +@@ -529,7 +535,6 @@ printf("\n"); + + /* we have pulled in a full packet so zero things */ + s->packet_length=0; +- dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ + return(1); + + f_err: +@@ -562,7 +567,8 @@ int dtls1_get_record(SSL *s) + + /* The epoch may have changed. If so, process all the + * pending records. This is a non-blocking operation. */ +- dtls1_process_buffered_records(s); ++ if(dtls1_process_buffered_records(s)<0) ++ return -1; + + /* if we're renegotiating, then there may be buffered records */ + if (dtls1_get_processed_record(s)) +@@ -699,7 +705,9 @@ again: + { + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) + { +- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num); ++ if(dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num)<0) ++ return -1; ++ dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */ + } + rr->length = 0; + s->packet_length = 0; +@@ -712,6 +720,7 @@ again: + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } ++ dtls1_record_bitmap_update(s, bitmap);/* Mark receipt of record. */ + + return(1); + +@@ -863,7 +872,11 @@ start: + * buffer the application data for later processing rather + * than dropping the connection. + */ +- dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num); ++ if(dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num)<0) ++ { ++ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); ++ return -1; ++ } + rr->length = 0; + goto start; + } diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0209.patch b/SOURCES/openssl-1.0.1e-cve-2015-0209.patch new file mode 100755 index 00000000..0ebcc56a --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0209.patch @@ -0,0 +1,82 @@ +diff -up openssl-1.0.1e/crypto/asn1/x_x509.c.use-after-free openssl-1.0.1e/crypto/asn1/x_x509.c +--- openssl-1.0.1e/crypto/asn1/x_x509.c.use-after-free 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/x_x509.c 2015-06-11 11:14:52.581856349 +0200 +@@ -170,8 +170,14 @@ X509 *d2i_X509_AUX(X509 **a, const unsig + { + const unsigned char *q; + X509 *ret; ++ int freeret = 0; ++ + /* Save start position */ + q = *pp; ++ ++ if(!a || *a == NULL) { ++ freeret = 1; ++ } + ret = d2i_X509(a, pp, length); + /* If certificate unreadable then forget it */ + if(!ret) return NULL; +@@ -181,7 +187,11 @@ X509 *d2i_X509_AUX(X509 **a, const unsig + if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err; + return ret; + err: +- X509_free(ret); ++ if(freeret) { ++ X509_free(ret); ++ if (a) ++ *a = NULL; ++ } + return NULL; + } + +diff -up openssl-1.0.1e/crypto/ec/ec_asn1.c.use-after-free openssl-1.0.1e/crypto/ec/ec_asn1.c +--- openssl-1.0.1e/crypto/ec/ec_asn1.c.use-after-free 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ec/ec_asn1.c 2015-06-11 11:14:52.581856349 +0200 +@@ -1140,8 +1140,6 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, con + ERR_R_MALLOC_FAILURE); + goto err; + } +- if (a) +- *a = ret; + } + else + ret = *a; +@@ -1206,11 +1204,13 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, con + } + } + ++ if (a) ++ *a = ret; + ok = 1; + err: + if (!ok) + { +- if (ret) ++ if (ret && (a == NULL || *a != ret)) + EC_KEY_free(ret); + ret = NULL; + } +@@ -1358,8 +1358,6 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, con + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + return NULL; + } +- if (a) +- *a = ret; + } + else + ret = *a; +@@ -1367,9 +1365,14 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, con + if (!d2i_ECPKParameters(&ret->group, in, len)) + { + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); ++ if (a == NULL || *a != ret) ++ EC_KEY_free(ret); + return NULL; + } + ++ if (a) ++ *a = ret; ++ + return ret; + } + diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0286.patch b/SOURCES/openssl-1.0.1e-cve-2015-0286.patch new file mode 100755 index 00000000..64ec2b79 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0286.patch @@ -0,0 +1,13 @@ +diff -up openssl-1.0.1e/crypto/asn1/a_type.c.bool-cmp openssl-1.0.1e/crypto/asn1/a_type.c +--- openssl-1.0.1e/crypto/asn1/a_type.c.bool-cmp 2015-03-18 13:02:36.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/a_type.c 2015-03-18 14:38:07.111401390 +0100 +@@ -124,6 +124,9 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, co + case V_ASN1_OBJECT: + result = OBJ_cmp(a->value.object, b->value.object); + break; ++ case V_ASN1_BOOLEAN: ++ result = a->value.boolean - b->value.boolean; ++ break; + case V_ASN1_NULL: + result = 0; /* They do not have content. */ + break; diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0287.patch b/SOURCES/openssl-1.0.1e-cve-2015-0287.patch new file mode 100755 index 00000000..f77b099c --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0287.patch @@ -0,0 +1,46 @@ +diff -up openssl-1.0.1e/crypto/asn1/tasn_dec.c.item-reuse openssl-1.0.1e/crypto/asn1/tasn_dec.c +--- openssl-1.0.1e/crypto/asn1/tasn_dec.c.item-reuse 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/tasn_dec.c 2015-03-19 15:46:51.097022616 +0100 +@@ -310,9 +310,19 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + case ASN1_ITYPE_CHOICE: + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; +- +- /* Allocate structure */ +- if (!*pval && !ASN1_item_ex_new(pval, it)) ++ if (*pval) ++ { ++ /* Free up and zero CHOICE value if initialised */ ++ i = asn1_get_choice_selector(pval, it); ++ if ((i >= 0) && (i < it->tcount)) ++ { ++ tt = it->templates + i; ++ pchptr = asn1_get_field_ptr(pval, tt); ++ ASN1_template_free(pchptr, tt); ++ asn1_set_choice_selector(pval, -1, it); ++ } ++ } ++ else if (!ASN1_item_ex_new(pval, it)) + { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ERR_R_NESTED_ASN1_ERROR); +@@ -407,6 +417,19 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + ++ /* Free up and zero any ADB found */ ++ for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) ++ { ++ if (tt->flags & ASN1_TFLG_ADB_MASK) ++ { ++ const ASN1_TEMPLATE *seqtt; ++ ASN1_VALUE **pseqval; ++ seqtt = asn1_do_adb(pval, tt, 1); ++ pseqval = asn1_get_field_ptr(pval, seqtt); ++ ASN1_template_free(pseqval, seqtt); ++ } ++ } ++ + /* Get each field entry */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) + { diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0288.patch b/SOURCES/openssl-1.0.1e-cve-2015-0288.patch new file mode 100755 index 00000000..c8dc6b98 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0288.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1e/crypto/x509/x509_req.c.req-null-deref openssl-1.0.1e/crypto/x509/x509_req.c +--- openssl-1.0.1e/crypto/x509/x509_req.c.req-null-deref 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/x509/x509_req.c 2015-03-18 18:34:35.732448017 +0100 +@@ -92,6 +92,8 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_ + goto err; + + pktmp = X509_get_pubkey(x); ++ if (pktmp == NULL) ++ goto err; + i=X509_REQ_set_pubkey(ret,pktmp); + EVP_PKEY_free(pktmp); + if (!i) goto err; diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0289.patch b/SOURCES/openssl-1.0.1e-cve-2015-0289.patch new file mode 100755 index 00000000..b52889d7 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0289.patch @@ -0,0 +1,184 @@ +diff -up openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.pkcs7-null-deref openssl-1.0.1e/crypto/pkcs7/pk7_doit.c +--- openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.pkcs7-null-deref 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/pkcs7/pk7_doit.c 2015-03-18 18:54:10.064871658 +0100 +@@ -272,6 +272,27 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) + PKCS7_RECIP_INFO *ri=NULL; + ASN1_OCTET_STRING *os=NULL; + ++ if (p7 == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); ++ return NULL; ++ } ++ /* ++ * The content field in the PKCS7 ContentInfo is optional, but that really ++ * only applies to inner content (precisely, detached signatures). ++ * ++ * When reading content, missing outer content is therefore treated as an ++ * error. ++ * ++ * When creating content, PKCS7_content_new() must be called before ++ * calling this method, so a NULL p7->d is always an error. ++ */ ++ if (p7->d.ptr == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); ++ return NULL; ++ } ++ + i=OBJ_obj2nid(p7->type); + p7->state=PKCS7_S_HEADER; + +@@ -433,6 +454,18 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + unsigned char *ek = NULL, *tkey = NULL; + int eklen = 0, tkeylen = 0; + ++ if (p7 == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); ++ return NULL; ++ } ++ ++ if (p7->d.ptr == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); ++ return NULL; ++ } ++ + i=OBJ_obj2nid(p7->type); + p7->state=PKCS7_S_HEADER; + +@@ -440,6 +473,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + { + case NID_pkcs7_signed: + data_body=PKCS7_get_octet_string(p7->d.sign->contents); ++ if (!PKCS7_is_detached(p7) && data_body == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATADECODE, ++ PKCS7_R_NO_CONTENT); ++ goto err; ++ } + md_sk=p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: +@@ -747,6 +786,18 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) + STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL; + ASN1_OCTET_STRING *os=NULL; + ++ if (p7 == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); ++ return 0; ++ } ++ ++ if (p7->d.ptr == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); ++ return 0; ++ } ++ + EVP_MD_CTX_init(&ctx_tmp); + i=OBJ_obj2nid(p7->type); + p7->state=PKCS7_S_HEADER; +@@ -791,6 +842,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) + /* If detached data then the content is excluded */ + if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { + M_ASN1_OCTET_STRING_free(os); ++ os = NULL; + p7->d.sign->contents->d.data = NULL; + } + break; +@@ -801,6 +853,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) + if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) + { + M_ASN1_OCTET_STRING_free(os); ++ os = NULL; + p7->d.digest->contents->d.data = NULL; + } + break; +@@ -873,23 +926,32 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) + M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); + } + +- if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF)) ++ if (!PKCS7_is_detached(p7)) + { +- char *cont; +- long contlen; +- btmp=BIO_find_type(bio,BIO_TYPE_MEM); +- if (btmp == NULL) +- { +- PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); ++ /* ++ * NOTE(emilia): I think we only reach os == NULL here because detached ++ * digested data support is broken. ++ */ ++ if (os == NULL) + goto err; ++ if (!(os->flags & ASN1_STRING_FLAG_NDEF)) ++ { ++ char *cont; ++ long contlen; ++ btmp=BIO_find_type(bio,BIO_TYPE_MEM); ++ if (btmp == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); ++ goto err; ++ } ++ contlen = BIO_get_mem_data(btmp, &cont); ++ /* Mark the BIO read only then we can use its copy of the data ++ * instead of making an extra copy. ++ */ ++ BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); ++ BIO_set_mem_eof_return(btmp, 0); ++ ASN1_STRING_set0(os, (unsigned char *)cont, contlen); + } +- contlen = BIO_get_mem_data(btmp, &cont); +- /* Mark the BIO read only then we can use its copy of the data +- * instead of making an extra copy. +- */ +- BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); +- BIO_set_mem_eof_return(btmp, 0); +- ASN1_STRING_set0(os, (unsigned char *)cont, contlen); + } + ret=1; + err: +@@ -928,6 +990,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_ + if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0) + goto err; + OPENSSL_free(abuf); ++ abuf = NULL; + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) + goto err; + abuf = OPENSSL_malloc(siglen); +@@ -965,6 +1028,18 @@ int PKCS7_dataVerify(X509_STORE *cert_st + STACK_OF(X509) *cert; + X509 *x509; + ++ if (p7 == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); ++ return 0; ++ } ++ ++ if (p7->d.ptr == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); ++ return 0; ++ } ++ + if (PKCS7_type_is_signed(p7)) + { + cert=p7->d.sign->cert; +diff -up openssl-1.0.1e/crypto/pkcs7/pk7_lib.c.pkcs7-null-deref openssl-1.0.1e/crypto/pkcs7/pk7_lib.c +--- openssl-1.0.1e/crypto/pkcs7/pk7_lib.c.pkcs7-null-deref 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/pkcs7/pk7_lib.c 2015-03-18 18:05:58.398767116 +0100 +@@ -459,6 +459,8 @@ int PKCS7_set_digest(PKCS7 *p7, const EV + + STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) + { ++ if (p7 == NULL || p7->d.ptr == NULL) ++ return NULL; + if (PKCS7_type_is_signed(p7)) + { + return(p7->d.sign->signer_info); diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0292.patch b/SOURCES/openssl-1.0.1e-cve-2015-0292.patch new file mode 100755 index 00000000..dd6a7378 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0292.patch @@ -0,0 +1,11 @@ +diff -up openssl-1.0.1e/crypto/evp/encode.c.b64-underflow openssl-1.0.1e/crypto/evp/encode.c +--- openssl-1.0.1e/crypto/evp/encode.c.b64-underflow 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/encode.c 2015-03-18 18:16:26.452331934 +0100 +@@ -324,6 +324,7 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx + v=EVP_DecodeBlock(out,d,n); + n=0; + if (v < 0) { rv=0; goto end; } ++ if (eof > v) { rv=-1; goto end; } + ret+=(v-eof); + } + else diff --git a/SOURCES/openssl-1.0.1e-cve-2015-0293.patch b/SOURCES/openssl-1.0.1e-cve-2015-0293.patch new file mode 100755 index 00000000..1ca78b3a --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-0293.patch @@ -0,0 +1,102 @@ +diff -up openssl-1.0.1e/ssl/s2_lib.c.ssl2-assert openssl-1.0.1e/ssl/s2_lib.c +--- openssl-1.0.1e/ssl/s2_lib.c.ssl2-assert 2015-03-18 13:02:36.000000000 +0100 ++++ openssl-1.0.1e/ssl/s2_lib.c 2015-03-18 18:22:20.195322489 +0100 +@@ -488,7 +488,7 @@ int ssl2_generate_key_material(SSL *s) + + OPENSSL_assert(s->session->master_key_length >= 0 + && s->session->master_key_length +- < (int)sizeof(s->session->master_key)); ++ <= (int)sizeof(s->session->master_key)); + EVP_DigestUpdate(&ctx,s->session->master_key,s->session->master_key_length); + EVP_DigestUpdate(&ctx,&c,1); + c++; +diff -up openssl-1.0.1e/ssl/s2_srvr.c.ssl2-assert openssl-1.0.1e/ssl/s2_srvr.c +--- openssl-1.0.1e/ssl/s2_srvr.c.ssl2-assert 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/s2_srvr.c 2015-03-18 18:30:11.403974038 +0100 +@@ -446,9 +446,6 @@ static int get_client_master_key(SSL *s) + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_NO_PRIVATEKEY); + return(-1); + } +- i=ssl_rsa_private_decrypt(s->cert,s->s2->tmp.enc, +- &(p[s->s2->tmp.clear]),&(p[s->s2->tmp.clear]), +- (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING); + + is_export=SSL_C_IS_EXPORT(s->session->cipher); + +@@ -467,21 +464,61 @@ static int get_client_master_key(SSL *s) + else + ek=5; + ++ /* ++ * The format of the CLIENT-MASTER-KEY message is ++ * 1 byte message type ++ * 3 bytes cipher ++ * 2-byte clear key length (stored in s->s2->tmp.clear) ++ * 2-byte encrypted key length (stored in s->s2->tmp.enc) ++ * 2-byte key args length (IV etc) ++ * clear key ++ * encrypted key ++ * key args ++ * ++ * If the cipher is an export cipher, then the encrypted key bytes ++ * are a fixed portion of the total key (5 or 8 bytes). The size of ++ * this portion is in |ek|. If the cipher is not an export cipher, ++ * then the entire key material is encrypted (i.e., clear key length ++ * must be zero). ++ */ ++ if ((!is_export && s->s2->tmp.clear != 0) || ++ (is_export && s->s2->tmp.clear + ek != EVP_CIPHER_key_length(c))) ++ { ++ ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); ++ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH); ++ return -1; ++ } ++ /* ++ * The encrypted blob must decrypt to the encrypted portion of the key. ++ * Decryption can't be expanding, so if we don't have enough encrypted ++ * bytes to fit the key in the buffer, stop now. ++ */ ++ if ((is_export && s->s2->tmp.enc < ek) || ++ (!is_export && s->s2->tmp.enc < EVP_CIPHER_key_length(c))) ++ { ++ ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); ++ SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT); ++ return -1; ++ } ++ ++ i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, ++ &(p[s->s2->tmp.clear]), ++ &(p[s->s2->tmp.clear]), ++ (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING : RSA_PKCS1_PADDING); ++ + /* bad decrypt */ + #if 1 + /* If a bad decrypt, continue with protocol but with a + * random master secret (Bleichenbacher attack) */ +- if ((i < 0) || +- ((!is_export && (i != EVP_CIPHER_key_length(c))) +- || (is_export && ((i != ek) || (s->s2->tmp.clear+(unsigned int)i != +- (unsigned int)EVP_CIPHER_key_length(c)))))) ++ if ((i < 0) || ((!is_export && i != EVP_CIPHER_key_length(c)) ++ || (is_export && i != ek))) + { + ERR_clear_error(); + if (is_export) + i=ek; + else + i=EVP_CIPHER_key_length(c); +- if (RAND_pseudo_bytes(p,i) <= 0) ++ if (RAND_pseudo_bytes(&p[s->s2->tmp.clear],i) <= 0) + return 0; + } + #else +@@ -505,7 +542,8 @@ static int get_client_master_key(SSL *s) + } + #endif + +- if (is_export) i+=s->s2->tmp.clear; ++ if (is_export) ++ i = EVP_CIPHER_key_length(c); + + if (i > SSL_MAX_MASTER_KEY_LENGTH) + { diff --git a/SOURCES/openssl-1.0.1e-cve-2015-1789.patch b/SOURCES/openssl-1.0.1e-cve-2015-1789.patch new file mode 100755 index 00000000..8633a768 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-1789.patch @@ -0,0 +1,103 @@ +diff -up openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read openssl-1.0.1e/crypto/x509/x509_vfy.c +--- openssl-1.0.1e/crypto/x509/x509_vfy.c.oob-read 2015-05-25 12:03:41.000000000 +0200 ++++ openssl-1.0.1e/crypto/x509/x509_vfy.c 2015-06-09 15:01:51.688640453 +0200 +@@ -1702,49 +1702,92 @@ int X509_cmp_time(const ASN1_TIME *ctm, + ASN1_TIME atm; + long offset; + char buff1[24],buff2[24],*p; +- int i,j; ++ int i, j, remaining; + + p=buff1; +- i=ctm->length; ++ remaining=ctm->length; + str=(char *)ctm->data; ++ /* ++ * Note that the following (historical) code allows much more slack in the ++ * time format than RFC5280. In RFC5280, the representation is fixed: ++ * UTCTime: YYMMDDHHMMSSZ ++ * GeneralizedTime: YYYYMMDDHHMMSSZ ++ */ + if (ctm->type == V_ASN1_UTCTIME) + { +- if ((i < 11) || (i > 17)) return 0; ++ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */ ++ int min_length = sizeof("YYMMDDHHMMZ") - 1; ++ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1; ++ if (remaining < min_length || remaining > max_length) ++ return 0; + memcpy(p,str,10); + p+=10; + str+=10; ++ remaining -= 10; + } + else + { +- if (i < 13) return 0; ++ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */ ++ int min_length = sizeof("YYYYMMDDHHMMZ") - 1; ++ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1; ++ if (remaining < min_length || remaining > max_length) ++ return 0; + memcpy(p,str,12); + p+=12; + str+=12; ++ remaining -= 12; + } + + if ((*str == 'Z') || (*str == '-') || (*str == '+')) + { *(p++)='0'; *(p++)='0'; } + else + { ++ /* SS (seconds) */ ++ if (remaining < 2) ++ return 0; + *(p++)= *(str++); + *(p++)= *(str++); +- /* Skip any fractional seconds... */ +- if (*str == '.') ++ remaining -= 2; ++ /* ++ * Skip any (up to three) fractional seconds... ++ * TODO(emilia): in RFC5280, fractional seconds are forbidden. ++ * Can we just kill them altogether? ++ */ ++ if (remaining && *str == '.') + { + str++; +- while ((*str >= '0') && (*str <= '9')) str++; ++ remaining--; ++ for (i = 0; i < 3 && remaining; i++, str++, remaining--) ++ { ++ if (*str < '0' || *str > '9') ++ break; ++ } + } + + } + *(p++)='Z'; + *(p++)='\0'; + ++ /* We now need either a terminating 'Z' or an offset. */ ++ if (!remaining) ++ return 0; + if (*str == 'Z') ++ { ++ if (remaining != 1) ++ return 0; + offset=0; ++ } + else + { ++ /* (+-)HHMM */ + if ((*str != '+') && (*str != '-')) + return 0; ++ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */ ++ if (remaining != 5) ++ return 0; ++ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || ++ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9') ++ return 0; + offset=((str[1]-'0')*10+(str[2]-'0'))*60; + offset+=(str[3]-'0')*10+(str[4]-'0'); + if (*str == '-') diff --git a/SOURCES/openssl-1.0.1e-cve-2015-1790.patch b/SOURCES/openssl-1.0.1e-cve-2015-1790.patch new file mode 100755 index 00000000..3b302409 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-1790.patch @@ -0,0 +1,55 @@ +diff -up openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.missing-content openssl-1.0.1e/crypto/pkcs7/pk7_doit.c +--- openssl-1.0.1e/crypto/pkcs7/pk7_doit.c.missing-content 2015-05-25 12:03:41.000000000 +0200 ++++ openssl-1.0.1e/crypto/pkcs7/pk7_doit.c 2015-06-09 15:21:21.377951520 +0200 +@@ -472,6 +472,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + switch (i) + { + case NID_pkcs7_signed: ++ /* ++ * p7->d.sign->contents is a PKCS7 structure consisting of a contentType ++ * field and optional content. ++ * data_body is NULL if that structure has no (=detached) content ++ * or if the contentType is wrong (i.e., not "data"). ++ */ + data_body=PKCS7_get_octet_string(p7->d.sign->contents); + if (!PKCS7_is_detached(p7) && data_body == NULL) + { +@@ -484,6 +490,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + case NID_pkcs7_signedAndEnveloped: + rsk=p7->d.signed_and_enveloped->recipientinfo; + md_sk=p7->d.signed_and_enveloped->md_algs; ++ /* data_body is NULL if the optional EncryptedContent is missing. */ + data_body=p7->d.signed_and_enveloped->enc_data->enc_data; + enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); +@@ -496,6 +503,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + case NID_pkcs7_enveloped: + rsk=p7->d.enveloped->recipientinfo; + enc_alg=p7->d.enveloped->enc_data->algorithm; ++ /* data_body is NULL if the optional EncryptedContent is missing. */ + data_body=p7->d.enveloped->enc_data->enc_data; + evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) +@@ -509,6 +517,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + goto err; + } + ++ /* Detached content must be supplied via in_bio instead. */ ++ if (data_body == NULL && in_bio == NULL) ++ { ++ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); ++ goto err; ++ } ++ + /* We will be checking the signature */ + if (md_sk != NULL) + { +@@ -665,7 +680,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKE + } + + #if 1 +- if (PKCS7_is_detached(p7) || (in_bio != NULL)) ++ if (in_bio != NULL) + { + bio=in_bio; + } diff --git a/SOURCES/openssl-1.0.1e-cve-2015-1791.patch b/SOURCES/openssl-1.0.1e-cve-2015-1791.patch new file mode 100755 index 00000000..2b6f315b --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-1791.patch @@ -0,0 +1,231 @@ +diff -up openssl-1.0.1e/ssl/ssl_err.c.ticket-race openssl-1.0.1e/ssl/ssl_err.c +--- openssl-1.0.1e/ssl/ssl_err.c.ticket-race 2015-06-09 15:40:41.000000000 +0200 ++++ openssl-1.0.1e/ssl/ssl_err.c 2015-06-09 15:45:06.879198463 +0200 +@@ -245,6 +245,7 @@ static ERR_STRING_DATA SSL_str_functs[]= + {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, + {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, + {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, ++{ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"}, + {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, + {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, + {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"}, +diff -up openssl-1.0.1e/ssl/ssl.h.ticket-race openssl-1.0.1e/ssl/ssl.h +--- openssl-1.0.1e/ssl/ssl.h.ticket-race 2015-06-09 15:40:41.000000000 +0200 ++++ openssl-1.0.1e/ssl/ssl.h 2015-06-09 15:44:22.696191291 +0200 +@@ -2176,6 +2176,7 @@ void ERR_load_SSL_strings(void); + #define SSL_F_SSL_READ 223 + #define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 + #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 ++#define SSL_F_SSL_SESSION_DUP 348 + #define SSL_F_SSL_SESSION_NEW 189 + #define SSL_F_SSL_SESSION_PRINT_FP 190 + #define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +diff -up openssl-1.0.1e/ssl/ssl_locl.h.ticket-race openssl-1.0.1e/ssl/ssl_locl.h +--- openssl-1.0.1e/ssl/ssl_locl.h.ticket-race 2015-06-09 15:40:41.000000000 +0200 ++++ openssl-1.0.1e/ssl/ssl_locl.h 2015-06-09 16:02:41.105243796 +0200 +@@ -822,6 +822,7 @@ void ssl_sess_cert_free(SESS_CERT *sc); + int ssl_set_peer_cert_type(SESS_CERT *c, int type); + int ssl_get_new_session(SSL *s, int session); + int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit); ++SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); + int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b); + DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, + ssl_cipher_id); +diff -up openssl-1.0.1e/ssl/ssl_sess.c.ticket-race openssl-1.0.1e/ssl/ssl_sess.c +--- openssl-1.0.1e/ssl/ssl_sess.c.ticket-race 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/ssl_sess.c 2015-06-11 13:48:26.724348868 +0200 +@@ -224,6 +224,146 @@ SSL_SESSION *SSL_SESSION_new(void) + return(ss); + } + ++/* ++ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If ++ * ticket == 0 then no ticket information is duplicated, otherwise it is. ++ */ ++SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) ++{ ++ SSL_SESSION *dest; ++ ++ dest = OPENSSL_malloc(sizeof(*src)); ++ if (dest == NULL) ++ { ++ goto err; ++ } ++ memcpy(dest, src, sizeof(*dest)); ++ ++ /* ++ * Set the various pointers to NULL so that we can call SSL_SESSION_free in ++ * the case of an error whilst halfway through constructing dest ++ */ ++#ifndef OPENSSL_NO_PSK ++ dest->psk_identity_hint = NULL; ++ dest->psk_identity = NULL; ++#endif ++ dest->ciphers = NULL; ++#ifndef OPENSSL_NO_TLSEXT ++ dest->tlsext_hostname = NULL; ++# ifndef OPENSSL_NO_EC ++ dest->tlsext_ecpointformatlist = NULL; ++ dest->tlsext_ellipticcurvelist = NULL; ++# endif ++#endif ++ dest->tlsext_tick = NULL; ++#ifndef OPENSSL_NO_SRP ++ dest->srp_username = NULL; ++#endif ++ memset(&dest->ex_data, 0, sizeof(dest->ex_data)); ++ ++ /* We deliberately don't copy the prev and next pointers */ ++ dest->prev = NULL; ++ dest->next = NULL; ++ ++ dest->references = 1; ++ ++ if (src->sess_cert != NULL) ++ CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); ++ ++ if (src->peer != NULL) ++ CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); ++ ++#ifndef OPENSSL_NO_PSK ++ if (src->psk_identity_hint) ++ { ++ dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); ++ if (dest->psk_identity_hint == NULL) ++ { ++ goto err; ++ } ++ } ++ if (src->psk_identity) ++ { ++ dest->psk_identity = BUF_strdup(src->psk_identity); ++ if (dest->psk_identity == NULL) ++ { ++ goto err; ++ } ++ } ++#endif ++ ++ if(src->ciphers != NULL) ++ { ++ dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); ++ if (dest->ciphers == NULL) ++ goto err; ++ } ++ ++ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ++ &dest->ex_data, &src->ex_data)) ++ { ++ goto err; ++ } ++ ++#ifndef OPENSSL_NO_TLSEXT ++ if (src->tlsext_hostname) ++ { ++ dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); ++ if (dest->tlsext_hostname == NULL) ++ { ++ goto err; ++ } ++ } ++# ifndef OPENSSL_NO_EC ++ if (src->tlsext_ecpointformatlist) ++ { ++ dest->tlsext_ecpointformatlist = ++ BUF_memdup(src->tlsext_ecpointformatlist, ++ src->tlsext_ecpointformatlist_length); ++ if (dest->tlsext_ecpointformatlist == NULL) ++ goto err; ++ } ++ if (src->tlsext_ellipticcurvelist) ++ { ++ dest->tlsext_ellipticcurvelist = ++ BUF_memdup(src->tlsext_ellipticcurvelist, ++ src->tlsext_ellipticcurvelist_length); ++ if (dest->tlsext_ellipticcurvelist == NULL) ++ goto err; ++ } ++# endif ++#endif ++ ++ if (ticket != 0) ++ { ++ dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); ++ if(dest->tlsext_tick == NULL) ++ goto err; ++ } ++ else ++ { ++ dest->tlsext_tick_lifetime_hint = 0; ++ dest->tlsext_ticklen = 0; ++ } ++ ++#ifndef OPENSSL_NO_SRP ++ if (src->srp_username) ++ { ++ dest->srp_username = BUF_strdup(src->srp_username); ++ if (dest->srp_username == NULL) ++ { ++ goto err; ++ } ++ } ++#endif ++ ++ return dest; ++err: ++ SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); ++ SSL_SESSION_free(dest); ++ return NULL; ++} ++ + const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) + { + if(len) +diff -up openssl-1.0.1e/ssl/s3_clnt.c.ticket-race openssl-1.0.1e/ssl/s3_clnt.c +--- openssl-1.0.1e/ssl/s3_clnt.c.ticket-race 2015-06-09 15:40:41.000000000 +0200 ++++ openssl-1.0.1e/ssl/s3_clnt.c 2015-06-09 15:39:56.315119013 +0200 +@@ -2092,6 +2092,44 @@ int ssl3_get_new_session_ticket(SSL *s) + } + + p=d=(unsigned char *)s->init_msg; ++ ++ if (s->session->session_id_length > 0) ++ { ++ int i = s->session_ctx->session_cache_mode; ++ SSL_SESSION *new_sess; ++ /* ++ * We reused an existing session, so we need to replace it with a new ++ * one ++ */ ++ if (i & SSL_SESS_CACHE_CLIENT) ++ { ++ /* ++ * Remove the old session from the cache ++ */ ++ if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) ++ { ++ if (s->session_ctx->remove_session_cb != NULL) ++ s->session_ctx->remove_session_cb(s->session_ctx, ++ s->session); ++ } ++ else ++ { ++ /* We carry on if this fails */ ++ SSL_CTX_remove_session(s->session_ctx, s->session); ++ } ++ } ++ ++ if ((new_sess = ssl_session_dup(s->session, 0)) == 0) ++ { ++ al = SSL_AD_INTERNAL_ERROR; ++ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); ++ goto f_err; ++ } ++ ++ SSL_SESSION_free(s->session); ++ s->session = new_sess; ++ } ++ + n2l(p, s->session->tlsext_tick_lifetime_hint); + n2s(p, ticklen); + /* ticket_lifetime_hint + ticket_length + ticket */ diff --git a/SOURCES/openssl-1.0.1e-cve-2015-1792.patch b/SOURCES/openssl-1.0.1e-cve-2015-1792.patch new file mode 100755 index 00000000..5f2b0cd9 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-1792.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1e/crypto/cms/cms_smime.c.unknown-hash openssl-1.0.1e/crypto/cms/cms_smime.c +--- openssl-1.0.1e/crypto/cms/cms_smime.c.unknown-hash 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/cms/cms_smime.c 2015-06-09 16:07:16.001516190 +0200 +@@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *up + BIO_free(f); + f = tbio; + } +- while (f != upto); ++ while (f && f != upto); + } + else + BIO_free_all(f); diff --git a/SOURCES/openssl-1.0.1e-cve-2015-3194.patch b/SOURCES/openssl-1.0.1e-cve-2015-3194.patch new file mode 100755 index 00000000..58b52f26 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-3194.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1e/crypto/rsa/rsa_ameth.c.pss-check openssl-1.0.1e/crypto/rsa/rsa_ameth.c +--- openssl-1.0.1e/crypto/rsa/rsa_ameth.c.pss-check 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_ameth.c 2015-12-04 09:03:18.300660817 +0100 +@@ -287,7 +287,7 @@ static RSA_PSS_PARAMS *rsa_pss_decode(co + { + ASN1_TYPE *param = pss->maskGenAlgorithm->parameter; + if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1 +- && param->type == V_ASN1_SEQUENCE) ++ && param && param->type == V_ASN1_SEQUENCE) + { + p = param->value.sequence->data; + plen = param->value.sequence->length; diff --git a/SOURCES/openssl-1.0.1e-cve-2015-3195.patch b/SOURCES/openssl-1.0.1e-cve-2015-3195.patch new file mode 100755 index 00000000..80f196fa --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-3195.patch @@ -0,0 +1,31 @@ +diff -up openssl-1.0.1e/crypto/asn1/tasn_dec.c.combine-leak openssl-1.0.1e/crypto/asn1/tasn_dec.c +--- openssl-1.0.1e/crypto/asn1/tasn_dec.c.combine-leak 2015-12-04 09:01:53.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/tasn_dec.c 2015-12-04 09:09:30.629793475 +0100 +@@ -169,6 +169,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + int otag; + int ret = 0; + ASN1_VALUE **pchptr, *ptmpval; ++ int combine = aclass & ASN1_TFLG_COMBINE; ++ aclass &= ~ASN1_TFLG_COMBINE; + if (!pval) + return 0; + if (aux && aux->asn1_cb) +@@ -539,7 +541,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, + auxerr: + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); + err: +- ASN1_item_ex_free(pval, it); ++ if (combine == 0) ++ ASN1_item_ex_free(pval, it); + if (errtt) + ERR_add_error_data(4, "Field=", errtt->field_name, + ", Type=", it->sname); +@@ -767,7 +770,7 @@ static int asn1_template_noexp_d2i(ASN1_ + { + /* Nothing special */ + ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), +- -1, 0, opt, ctx); ++ -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); + if (!ret) + { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, diff --git a/SOURCES/openssl-1.0.1e-cve-2015-3196.patch b/SOURCES/openssl-1.0.1e-cve-2015-3196.patch new file mode 100755 index 00000000..19dc323a --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-3196.patch @@ -0,0 +1,52 @@ +diff -up openssl-1.0.1e/ssl/s3_clnt.c.psk-identity openssl-1.0.1e/ssl/s3_clnt.c +--- openssl-1.0.1e/ssl/s3_clnt.c.psk-identity 2015-12-04 09:01:53.000000000 +0100 ++++ openssl-1.0.1e/ssl/s3_clnt.c 2015-12-04 09:36:24.182010426 +0100 +@@ -1367,8 +1367,6 @@ int ssl3_get_key_exchange(SSL *s) + #ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) + { +- char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1]; +- + al=SSL_AD_HANDSHAKE_FAILURE; + n2s(p,i); + param_len=i+2; +@@ -1389,16 +1387,8 @@ int ssl3_get_key_exchange(SSL *s) + SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); + goto f_err; + } +- /* If received PSK identity hint contains NULL +- * characters, the hint is truncated from the first +- * NULL. p may not be ending with NULL, so create a +- * NULL-terminated string. */ +- memcpy(tmp_id_hint, p, i); +- memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i); +- if (s->ctx->psk_identity_hint != NULL) +- OPENSSL_free(s->ctx->psk_identity_hint); +- s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint); +- if (s->ctx->psk_identity_hint == NULL) ++ s->session->psk_identity_hint = BUF_strndup((char *)p, i); ++ if (s->session->psk_identity_hint == NULL) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; +@@ -2904,7 +2894,7 @@ int ssl3_send_client_key_exchange(SSL *s + goto err; + } + +- psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, ++ psk_len = s->psk_client_callback(s, s->session->psk_identity_hint, + identity, PSK_MAX_IDENTITY_LEN, + psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_len > PSK_MAX_PSK_LEN) +diff -up openssl-1.0.1e/ssl/s3_srvr.c.psk-identity openssl-1.0.1e/ssl/s3_srvr.c +--- openssl-1.0.1e/ssl/s3_srvr.c.psk-identity 2015-12-04 09:01:53.000000000 +0100 ++++ openssl-1.0.1e/ssl/s3_srvr.c 2015-12-04 09:43:45.144086868 +0100 +@@ -2751,7 +2751,7 @@ int ssl3_get_client_key_exchange(SSL *s) + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); +- s->session->psk_identity = BUF_strdup((char *)p); ++ s->session->psk_identity = BUF_strndup((char *)p, i); + if (s->session->psk_identity == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, diff --git a/SOURCES/openssl-1.0.1e-cve-2015-3197.patch b/SOURCES/openssl-1.0.1e-cve-2015-3197.patch new file mode 100755 index 00000000..325ad2d0 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-3197.patch @@ -0,0 +1,42 @@ +diff -up openssl-1.0.1e/ssl/s2_srvr.c.ssl2-ciphers openssl-1.0.1e/ssl/s2_srvr.c +--- openssl-1.0.1e/ssl/s2_srvr.c.ssl2-ciphers 2016-01-14 17:38:50.000000000 +0100 ++++ openssl-1.0.1e/ssl/s2_srvr.c 2016-02-16 16:18:59.790225008 +0100 +@@ -392,7 +392,7 @@ static int get_client_master_key(SSL *s) + } + + cp=ssl2_get_cipher_by_char(p); +- if (cp == NULL) ++ if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) + { + ssl2_return_error(s,SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); +@@ -692,9 +692,13 @@ static int get_client_hello(SSL *s) + prio = cs; + allow = cl; + } ++ ++ /* Generate list of SSLv2 ciphers shared between client and server */ + for (z=0; zalgorithm_ssl & SSL_SSLV2) == 0 || ++ sk_SSL_CIPHER_find(allow,cp) < 0) + { + (void)sk_SSL_CIPHER_delete(prio,z); + z--; +@@ -705,6 +709,14 @@ static int get_client_hello(SSL *s) + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = prio; + } ++ ++ /* Make sure we have at least one cipher in common */ ++ if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) ++ { ++ ssl2_return_error(s, SSL2_PE_NO_CIPHER); ++ SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH); ++ return -1; ++ } + /* s->session->ciphers should now have a list of + * ciphers that are on both the client and server. + * This list is ordered by the order the client sent diff --git a/SOURCES/openssl-1.0.1e-cve-2015-4000.patch b/SOURCES/openssl-1.0.1e-cve-2015-4000.patch new file mode 100755 index 00000000..66dd559d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-4000.patch @@ -0,0 +1,241 @@ +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod.logjam openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod.logjam 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod 2015-05-25 11:37:08.893049771 +0200 +@@ -12,12 +12,10 @@ SSL_CTX_set_tmp_dh_callback, SSL_CTX_set + DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength)); + long SSL_CTX_set_tmp_dh(SSL_CTX *ctx, DH *dh); + +- void SSL_set_tmp_dh_callback(SSL_CTX *ctx, ++ void SSL_set_tmp_dh_callback(SSL *ctx, + DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength)); + long SSL_set_tmp_dh(SSL *ssl, DH *dh) + +- DH *(*tmp_dh_callback)(SSL *ssl, int is_export, int keylength)); +- + =head1 DESCRIPTION + + SSL_CTX_set_tmp_dh_callback() sets the callback function for B to be +@@ -50,24 +48,25 @@ even if he gets hold of the normal (cert + only used for signing. + + In order to perform a DH key exchange the server must use a DH group +-(DH parameters) and generate a DH key. The server will always generate a new +-DH key during the negotiation, when the DH parameters are supplied via +-callback and/or when the SSL_OP_SINGLE_DH_USE option of +-L is set. It will +-immediately create a DH key, when DH parameters are supplied via +-SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. In this case, ++(DH parameters) and generate a DH key. ++The server will always generate a new DH key during the negotiation ++if either the DH parameters are supplied via callback or the ++SSL_OP_SINGLE_DH_USE option of SSL_CTX_set_options(3) is set (or both). ++It will immediately create a DH key if DH parameters are supplied via ++SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. ++In this case, + it may happen that a key is generated on initialization without later + being needed, while on the other hand the computer time during the + negotiation is being saved. + + If "strong" primes were used to generate the DH parameters, it is not strictly + necessary to generate a new key for each handshake but it does improve forward +-secrecy. If it is not assured, that "strong" primes were used (see especially +-the section about DSA parameters below), SSL_OP_SINGLE_DH_USE must be used +-in order to prevent small subgroup attacks. Always using SSL_OP_SINGLE_DH_USE +-has an impact on the computer time needed during negotiation, but it is not +-very large, so application authors/users should consider to always enable +-this option. ++secrecy. If it is not assured that "strong" primes were used, ++SSL_OP_SINGLE_DH_USE must be used in order to prevent small subgroup ++attacks. Always using SSL_OP_SINGLE_DH_USE has an impact on the ++computer time needed during negotiation, but it is not very large, so ++application authors/users should consider always enabling this option. ++The option is required to implement perfect forward secrecy (PFS). + + As generating DH parameters is extremely time consuming, an application + should not generate the parameters on the fly but supply the parameters. +@@ -75,82 +74,62 @@ DH parameters can be reused, as the actu + the negotiation. The risk in reusing DH parameters is that an attacker + may specialize on a very often used DH group. Applications should therefore + generate their own DH parameters during the installation process using the +-openssl L application. In order to reduce the computer +-time needed for this generation, it is possible to use DSA parameters +-instead (see L), but in this case SSL_OP_SINGLE_DH_USE +-is mandatory. ++openssl L application. This application ++guarantees that "strong" primes are used. + +-Application authors may compile in DH parameters. Files dh512.pem, +-dh1024.pem, dh2048.pem, and dh4096 in the 'apps' directory of current ++Files dh2048.pem, and dh4096.pem in the 'apps' directory of the current + version of the OpenSSL distribution contain the 'SKIP' DH parameters, + which use safe primes and were generated verifiably pseudo-randomly. + These files can be converted into C code using the B<-C> option of the +-L application. +-Authors may also generate their own set of parameters using +-L, but a user may not be sure how the parameters were +-generated. The generation of DH parameters during installation is therefore +-recommended. ++L application. Generation of custom DH ++parameters during installation should still be preferred to stop an ++attacker from specializing on a commonly used group. Files dh1024.pem ++and dh512.pem contain old parameters that must not be used by ++applications. + + An application may either directly specify the DH parameters or +-can supply the DH parameters via a callback function. The callback approach +-has the advantage, that the callback may supply DH parameters for different +-key lengths. +- +-The B is called with the B needed and +-the B information. The B flag is set, when the +-ephemeral DH key exchange is performed with an export cipher. ++can supply the DH parameters via a callback function. ++ ++Previous versions of the callback used B and B ++parameters to control parameter generation for export and non-export ++cipher suites. Modern servers that do not support export ciphersuites ++are advised to either use SSL_CTX_set_tmp_dh() in combination with ++SSL_OP_SINGLE_DH_USE, or alternatively, use the callback but ignore ++B and B and simply supply at least 2048-bit ++parameters in the callback. + + =head1 EXAMPLES + +-Handle DH parameters for key lengths of 512 and 1024 bits. (Error handling ++Setup DH parameters with a key length of 2048 bits. (Error handling + partly left out.) + +- ... +- /* Set up ephemeral DH stuff */ +- DH *dh_512 = NULL; +- DH *dh_1024 = NULL; +- FILE *paramfile; ++ Command-line parameter generation: ++ $ openssl dhparam -out dh_param_2048.pem 2048 + ++ Code for setting up parameters during server initialization: ++ ++ ... ++ SSL_CTX ctx = SSL_CTX_new(); + ... +- /* "openssl dhparam -out dh_param_512.pem -2 512" */ +- paramfile = fopen("dh_param_512.pem", "r"); ++ ++ /* Set up ephemeral DH parameters. */ ++ DH *dh_2048 = NULL; ++ FILE *paramfile; ++ paramfile = fopen("dh_param_2048.pem", "r"); + if (paramfile) { +- dh_512 = PEM_read_DHparams(paramfile, NULL, NULL, NULL); ++ dh_2048 = PEM_read_DHparams(paramfile, NULL, NULL, NULL); + fclose(paramfile); ++ } else { ++ /* Error. */ + } +- /* "openssl dhparam -out dh_param_1024.pem -2 1024" */ +- paramfile = fopen("dh_param_1024.pem", "r"); +- if (paramfile) { +- dh_1024 = PEM_read_DHparams(paramfile, NULL, NULL, NULL); +- fclose(paramfile); ++ if (dh_2048 == NULL) { ++ /* Error. */ + } +- ... +- +- /* "openssl dhparam -C -2 512" etc... */ +- DH *get_dh512() { ... } +- DH *get_dh1024() { ... } +- +- DH *tmp_dh_callback(SSL *s, int is_export, int keylength) +- { +- DH *dh_tmp=NULL; +- +- switch (keylength) { +- case 512: +- if (!dh_512) +- dh_512 = get_dh512(); +- dh_tmp = dh_512; +- break; +- case 1024: +- if (!dh_1024) +- dh_1024 = get_dh1024(); +- dh_tmp = dh_1024; +- break; +- default: +- /* Generating a key on the fly is very costly, so use what is there */ +- setup_dh_parameters_like_above(); +- } +- return(dh_tmp); ++ if (SSL_CTX_set_tmp_dh(ctx, dh_2048) != 1) { ++ /* Error. */ + } ++ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); ++ ... + + =head1 RETURN VALUES + +diff -up openssl-1.0.1e/ssl/ssl_err.c.logjam openssl-1.0.1e/ssl/ssl_err.c +--- openssl-1.0.1e/ssl/ssl_err.c.logjam 2015-05-25 11:38:29.834858712 +0200 ++++ openssl-1.0.1e/ssl/ssl_err.c 2015-05-25 11:42:01.041578905 +0200 +@@ -361,6 +361,7 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),"decryption failed or bad record mac"}, ++{ERR_REASON(SSL_R_DH_KEY_TOO_SMALL) ,"dh key too small"}, + {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),"dh public value length is wrong"}, + {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED) ,"digest check failed"}, + {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG) ,"dtls message too big"}, +diff -up openssl-1.0.1e/ssl/ssl.h.logjam openssl-1.0.1e/ssl/ssl.h +--- openssl-1.0.1e/ssl/ssl.h.logjam 2015-05-25 11:38:29.834858712 +0200 ++++ openssl-1.0.1e/ssl/ssl.h 2015-05-25 11:40:42.482823220 +0200 +@@ -2289,6 +2289,7 @@ void ERR_load_SSL_strings(void); + #define SSL_R_DATA_LENGTH_TOO_LONG 146 + #define SSL_R_DECRYPTION_FAILED 147 + #define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 ++#define SSL_R_DH_KEY_TOO_SMALL 372 + #define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 + #define SSL_R_DIGEST_CHECK_FAILED 149 + #define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +diff -up openssl-1.0.1e/ssl/s3_clnt.c.logjam openssl-1.0.1e/ssl/s3_clnt.c +--- openssl-1.0.1e/ssl/s3_clnt.c.logjam 2015-05-25 11:38:29.833858690 +0200 ++++ openssl-1.0.1e/ssl/s3_clnt.c 2015-05-25 11:51:05.845754562 +0200 +@@ -3277,24 +3277,34 @@ int ssl3_check_cert_and_algorithm(SSL *s + } + #endif + #ifndef OPENSSL_NO_DH +- if ((alg_k & SSL_kEDH) && +- !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL))) ++ if ((alg_k & SSL_kEDH) && dh == NULL) + { +- SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY); ++ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,ERR_R_INTERNAL_ERROR); + goto f_err; + } +- else if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA)) ++ if ((alg_k & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA)) + { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT); + goto f_err; + } + #ifndef OPENSSL_NO_DSA +- else if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA)) ++ if ((alg_k & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA)) + { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT); + goto f_err; + } + #endif ++ /* Check DHE only: static DH not implemented. */ ++ if (alg_k & SSL_kEDH) ++ { ++ int dh_size = BN_num_bits(dh->p); ++ if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 768) ++ || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) ++ { ++ SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); ++ goto f_err; ++ } ++ } + #endif + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP)) diff --git a/SOURCES/openssl-1.0.1e-cve-2015-7575.patch b/SOURCES/openssl-1.0.1e-cve-2015-7575.patch new file mode 100755 index 00000000..dc86361d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2015-7575.patch @@ -0,0 +1,38 @@ +diff -up openssl-1.0.1e/ssl/t1_lib.c.no-md5-tls openssl-1.0.1e/ssl/t1_lib.c +--- openssl-1.0.1e/ssl/t1_lib.c.no-md5-tls 2015-12-04 09:51:39.000000000 +0100 ++++ openssl-1.0.1e/ssl/t1_lib.c 2015-12-21 14:09:35.239084727 +0100 +@@ -390,19 +390,11 @@ static unsigned char tls12_sigalgs[] = { + #ifndef OPENSSL_NO_SHA + tlsext_sigalg(TLSEXT_hash_sha1) + #endif +-#ifndef OPENSSL_NO_MD5 +- tlsext_sigalg_rsa(TLSEXT_hash_md5) +-#endif + }; + + int tls12_get_req_sig_algs(SSL *s, unsigned char *p) + { + size_t slen = sizeof(tls12_sigalgs); +-#ifdef OPENSSL_FIPS +- /* If FIPS mode don't include MD5 which is last */ +- if (FIPS_mode()) +- slen -= 2; +-#endif + if (p) + memcpy(p, tls12_sigalgs, slen); + return (int)slen; +@@ -2413,14 +2405,6 @@ const EVP_MD *tls12_get_hash(unsigned ch + { + switch(hash_alg) + { +-#ifndef OPENSSL_NO_MD5 +- case TLSEXT_hash_md5: +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return NULL; +-#endif +- return EVP_md5(); +-#endif + #ifndef OPENSSL_NO_SHA + case TLSEXT_hash_sha1: + return EVP_sha1(); diff --git a/SOURCES/openssl-1.0.1e-cve-2016-0702.patch b/SOURCES/openssl-1.0.1e-cve-2016-0702.patch new file mode 100755 index 00000000..9ce1ca6c --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-0702.patch @@ -0,0 +1,1187 @@ +diff -up openssl-1.0.1e/crypto/bn/asm/x86_64-mont5.pl.rsa-const openssl-1.0.1e/crypto/bn/asm/x86_64-mont5.pl +--- openssl-1.0.1e/crypto/bn/asm/x86_64-mont5.pl.rsa-const 2016-01-14 17:38:50.127212987 +0100 ++++ openssl-1.0.1e/crypto/bn/asm/x86_64-mont5.pl 2016-02-24 12:03:28.180178677 +0100 +@@ -66,60 +66,113 @@ bn_mul_mont_gather5: + .align 16 + .Lmul_enter: + mov ${num}d,${num}d +- mov `($win64?56:8)`(%rsp),%r10d # load 7th argument ++ movd `($win64?56:8)`(%rsp),%xmm5 # load 7th argument ++ lea .Linc(%rip),%r10 + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 +-___ +-$code.=<<___ if ($win64); +- lea -0x28(%rsp),%rsp +- movaps %xmm6,(%rsp) +- movaps %xmm7,0x10(%rsp) ++ + .Lmul_alloca: +-___ +-$code.=<<___; + mov %rsp,%rax + lea 2($num),%r11 + neg %r11 +- lea (%rsp,%r11,8),%rsp # tp=alloca(8*(num+2)) ++ lea -264(%rsp,%r11,8),%rsp # tp=alloca(8*(num+2)+256+8) + and \$-1024,%rsp # minimize TLB usage + + mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp + .Lmul_body: +- mov $bp,%r12 # reassign $bp ++ lea 128($bp),%r12 # reassign $bp (+size optimization) + ___ + $bp="%r12"; + $STRIDE=2**5*8; # 5 is "window size" + $N=$STRIDE/4; # should match cache line size + $code.=<<___; +- mov %r10,%r11 +- shr \$`log($N/8)/log(2)`,%r10 +- and \$`$N/8-1`,%r11 +- not %r10 +- lea .Lmagic_masks(%rip),%rax +- and \$`2**5/($N/8)-1`,%r10 # 5 is "window size" +- lea 96($bp,%r11,8),$bp # pointer within 1st cache line +- movq 0(%rax,%r10,8),%xmm4 # set of masks denoting which +- movq 8(%rax,%r10,8),%xmm5 # cache line contains element +- movq 16(%rax,%r10,8),%xmm6 # denoted by 7th argument +- movq 24(%rax,%r10,8),%xmm7 +- +- movq `0*$STRIDE/4-96`($bp),%xmm0 +- movq `1*$STRIDE/4-96`($bp),%xmm1 +- pand %xmm4,%xmm0 +- movq `2*$STRIDE/4-96`($bp),%xmm2 +- pand %xmm5,%xmm1 +- movq `3*$STRIDE/4-96`($bp),%xmm3 +- pand %xmm6,%xmm2 +- por %xmm1,%xmm0 +- pand %xmm7,%xmm3 ++ movdqa 0(%r10),%xmm0 # 00000001000000010000000000000000 ++ movdqa 16(%r10),%xmm1 # 00000002000000020000000200000002 ++ lea 24-112(%rsp,$num,8),%r10# place the mask after tp[num+3] (+ICache optimization) ++ and \$-16,%r10 ++ ++ pshufd \$0,%xmm5,%xmm5 # broadcast index ++ movdqa %xmm1,%xmm4 ++ movdqa %xmm1,%xmm2 ++___ ++######################################################################## ++# calculate mask by comparing 0..31 to index and save result to stack ++# ++$code.=<<___; ++ paddd %xmm0,%xmm1 ++ pcmpeqd %xmm5,%xmm0 # compare to 1,0 ++ .byte 0x67 ++ movdqa %xmm4,%xmm3 ++___ ++for($k=0;$k<$STRIDE/16-4;$k+=4) { ++$code.=<<___; ++ paddd %xmm1,%xmm2 ++ pcmpeqd %xmm5,%xmm1 # compare to 3,2 ++ movdqa %xmm0,`16*($k+0)+112`(%r10) ++ movdqa %xmm4,%xmm0 ++ ++ paddd %xmm2,%xmm3 ++ pcmpeqd %xmm5,%xmm2 # compare to 5,4 ++ movdqa %xmm1,`16*($k+1)+112`(%r10) ++ movdqa %xmm4,%xmm1 ++ ++ paddd %xmm3,%xmm0 ++ pcmpeqd %xmm5,%xmm3 # compare to 7,6 ++ movdqa %xmm2,`16*($k+2)+112`(%r10) ++ movdqa %xmm4,%xmm2 ++ ++ paddd %xmm0,%xmm1 ++ pcmpeqd %xmm5,%xmm0 ++ movdqa %xmm3,`16*($k+3)+112`(%r10) ++ movdqa %xmm4,%xmm3 ++___ ++} ++$code.=<<___; # last iteration can be optimized ++ paddd %xmm1,%xmm2 ++ pcmpeqd %xmm5,%xmm1 ++ movdqa %xmm0,`16*($k+0)+112`(%r10) ++ ++ paddd %xmm2,%xmm3 ++ .byte 0x67 ++ pcmpeqd %xmm5,%xmm2 ++ movdqa %xmm1,`16*($k+1)+112`(%r10) ++ ++ pcmpeqd %xmm5,%xmm3 ++ movdqa %xmm2,`16*($k+2)+112`(%r10) ++ pand `16*($k+0)-128`($bp),%xmm0 # while it's still in register ++ ++ pand `16*($k+1)-128`($bp),%xmm1 ++ pand `16*($k+2)-128`($bp),%xmm2 ++ movdqa %xmm3,`16*($k+3)+112`(%r10) ++ pand `16*($k+3)-128`($bp),%xmm3 + por %xmm2,%xmm0 ++ por %xmm3,%xmm1 ++___ ++for($k=0;$k<$STRIDE/16-4;$k+=4) { ++$code.=<<___; ++ movdqa `16*($k+0)-128`($bp),%xmm4 ++ movdqa `16*($k+1)-128`($bp),%xmm5 ++ movdqa `16*($k+2)-128`($bp),%xmm2 ++ pand `16*($k+0)+112`(%r10),%xmm4 ++ movdqa `16*($k+3)-128`($bp),%xmm3 ++ pand `16*($k+1)+112`(%r10),%xmm5 ++ por %xmm4,%xmm0 ++ pand `16*($k+2)+112`(%r10),%xmm2 ++ por %xmm5,%xmm1 ++ pand `16*($k+3)+112`(%r10),%xmm3 ++ por %xmm2,%xmm0 ++ por %xmm3,%xmm1 ++___ ++} ++$code.=<<___; ++ por %xmm1,%xmm0 ++ pshufd \$0x4e,%xmm0,%xmm1 ++ por %xmm1,%xmm0 + lea $STRIDE($bp),$bp +- por %xmm3,%xmm0 +- + movq %xmm0,$m0 # m0=bp[0] + + mov ($n0),$n0 # pull n0[0] value +@@ -128,29 +181,14 @@ $code.=<<___; + xor $i,$i # i=0 + xor $j,$j # j=0 + +- movq `0*$STRIDE/4-96`($bp),%xmm0 +- movq `1*$STRIDE/4-96`($bp),%xmm1 +- pand %xmm4,%xmm0 +- movq `2*$STRIDE/4-96`($bp),%xmm2 +- pand %xmm5,%xmm1 +- + mov $n0,$m1 + mulq $m0 # ap[0]*bp[0] + mov %rax,$lo0 + mov ($np),%rax + +- movq `3*$STRIDE/4-96`($bp),%xmm3 +- pand %xmm6,%xmm2 +- por %xmm1,%xmm0 +- pand %xmm7,%xmm3 +- + imulq $lo0,$m1 # "tp[0]"*n0 + mov %rdx,$hi0 + +- por %xmm2,%xmm0 +- lea $STRIDE($bp),$bp +- por %xmm3,%xmm0 +- + mulq $m1 # np[0]*m1 + add %rax,$lo0 # discarded + mov 8($ap),%rax +@@ -183,8 +221,6 @@ $code.=<<___; + cmp $num,$j + jne .L1st + +- movq %xmm0,$m0 # bp[1] +- + add %rax,$hi1 + mov ($ap),%rax # ap[0] + adc \$0,%rdx +@@ -204,33 +240,46 @@ $code.=<<___; + jmp .Louter + .align 16 + .Louter: ++ lea 24+128(%rsp,$num,8),%rdx # where 256-byte mask is (+size optimization) ++ and \$-16,%rdx ++ pxor %xmm4,%xmm4 ++ pxor %xmm5,%xmm5 ++___ ++for($k=0;$k<$STRIDE/16;$k+=4) { ++$code.=<<___; ++ movdqa `16*($k+0)-128`($bp),%xmm0 ++ movdqa `16*($k+1)-128`($bp),%xmm1 ++ movdqa `16*($k+2)-128`($bp),%xmm2 ++ movdqa `16*($k+3)-128`($bp),%xmm3 ++ pand `16*($k+0)-128`(%rdx),%xmm0 ++ pand `16*($k+1)-128`(%rdx),%xmm1 ++ por %xmm0,%xmm4 ++ pand `16*($k+2)-128`(%rdx),%xmm2 ++ por %xmm1,%xmm5 ++ pand `16*($k+3)-128`(%rdx),%xmm3 ++ por %xmm2,%xmm4 ++ por %xmm3,%xmm5 ++___ ++} ++$code.=<<___; ++ por %xmm5,%xmm4 ++ pshufd \$0x4e,%xmm4,%xmm0 ++ por %xmm4,%xmm0 ++ lea $STRIDE($bp),$bp ++ movq %xmm0,$m0 # m0=bp[i] ++ + xor $j,$j # j=0 + mov $n0,$m1 + mov (%rsp),$lo0 + +- movq `0*$STRIDE/4-96`($bp),%xmm0 +- movq `1*$STRIDE/4-96`($bp),%xmm1 +- pand %xmm4,%xmm0 +- movq `2*$STRIDE/4-96`($bp),%xmm2 +- pand %xmm5,%xmm1 +- + mulq $m0 # ap[0]*bp[i] + add %rax,$lo0 # ap[0]*bp[i]+tp[0] + mov ($np),%rax + adc \$0,%rdx + +- movq `3*$STRIDE/4-96`($bp),%xmm3 +- pand %xmm6,%xmm2 +- por %xmm1,%xmm0 +- pand %xmm7,%xmm3 +- + imulq $lo0,$m1 # tp[0]*n0 + mov %rdx,$hi0 + +- por %xmm2,%xmm0 +- lea $STRIDE($bp),$bp +- por %xmm3,%xmm0 +- + mulq $m1 # np[0]*m1 + add %rax,$lo0 # discarded + mov 8($ap),%rax +@@ -266,8 +315,6 @@ $code.=<<___; + cmp $num,$j + jne .Linner + +- movq %xmm0,$m0 # bp[i+1] +- + add %rax,$hi1 + mov ($ap),%rax # ap[0] + adc \$0,%rdx +@@ -321,13 +368,7 @@ $code.=<<___; + + mov 8(%rsp,$num,8),%rsi # restore %rsp + mov \$1,%rax +-___ +-$code.=<<___ if ($win64); +- movaps (%rsi),%xmm6 +- movaps 0x10(%rsi),%xmm7 +- lea 0x28(%rsi),%rsi +-___ +-$code.=<<___; ++ + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 +@@ -348,91 +389,130 @@ $code.=<<___; + bn_mul4x_mont_gather5: + .Lmul4x_enter: + mov ${num}d,${num}d +- mov `($win64?56:8)`(%rsp),%r10d # load 7th argument ++ movd `($win64?56:8)`(%rsp),%xmm5 # load 7th argument ++ lea .Linc(%rip),%r10 + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 +-___ +-$code.=<<___ if ($win64); +- lea -0x28(%rsp),%rsp +- movaps %xmm6,(%rsp) +- movaps %xmm7,0x10(%rsp) ++ + .Lmul4x_alloca: +-___ +-$code.=<<___; + mov %rsp,%rax + lea 4($num),%r11 + neg %r11 +- lea (%rsp,%r11,8),%rsp # tp=alloca(8*(num+4)) ++ lea -256(%rsp,%r11,8),%rsp # tp=alloca(8*(num+4)+256) + and \$-1024,%rsp # minimize TLB usage + + mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp + .Lmul4x_body: + mov $rp,16(%rsp,$num,8) # tp[num+2]=$rp +- mov %rdx,%r12 # reassign $bp ++ lea 128(%rdx),%r12 # reassign $bp (+size optimization) + ___ + $bp="%r12"; + $STRIDE=2**5*8; # 5 is "window size" + $N=$STRIDE/4; # should match cache line size + $code.=<<___; +- mov %r10,%r11 +- shr \$`log($N/8)/log(2)`,%r10 +- and \$`$N/8-1`,%r11 +- not %r10 +- lea .Lmagic_masks(%rip),%rax +- and \$`2**5/($N/8)-1`,%r10 # 5 is "window size" +- lea 96($bp,%r11,8),$bp # pointer within 1st cache line +- movq 0(%rax,%r10,8),%xmm4 # set of masks denoting which +- movq 8(%rax,%r10,8),%xmm5 # cache line contains element +- movq 16(%rax,%r10,8),%xmm6 # denoted by 7th argument +- movq 24(%rax,%r10,8),%xmm7 +- +- movq `0*$STRIDE/4-96`($bp),%xmm0 +- movq `1*$STRIDE/4-96`($bp),%xmm1 +- pand %xmm4,%xmm0 +- movq `2*$STRIDE/4-96`($bp),%xmm2 +- pand %xmm5,%xmm1 +- movq `3*$STRIDE/4-96`($bp),%xmm3 +- pand %xmm6,%xmm2 +- por %xmm1,%xmm0 +- pand %xmm7,%xmm3 ++ movdqa 0(%r10),%xmm0 # 00000001000000010000000000000000 ++ movdqa 16(%r10),%xmm1 # 00000002000000020000000200000002 ++ lea 32-112(%rsp,$num,8),%r10# place the mask after tp[num+4] (+ICache optimization) ++ ++ pshufd \$0,%xmm5,%xmm5 # broadcast index ++ movdqa %xmm1,%xmm4 ++ .byte 0x67,0x67 ++ movdqa %xmm1,%xmm2 ++___ ++######################################################################## ++# calculate mask by comparing 0..31 to index and save result to stack ++# ++$code.=<<___; ++ paddd %xmm0,%xmm1 ++ pcmpeqd %xmm5,%xmm0 # compare to 1,0 ++ .byte 0x67 ++ movdqa %xmm4,%xmm3 ++___ ++for($k=0;$k<$STRIDE/16-4;$k+=4) { ++$code.=<<___; ++ paddd %xmm1,%xmm2 ++ pcmpeqd %xmm5,%xmm1 # compare to 3,2 ++ movdqa %xmm0,`16*($k+0)+112`(%r10) ++ movdqa %xmm4,%xmm0 ++ ++ paddd %xmm2,%xmm3 ++ pcmpeqd %xmm5,%xmm2 # compare to 5,4 ++ movdqa %xmm1,`16*($k+1)+112`(%r10) ++ movdqa %xmm4,%xmm1 ++ ++ paddd %xmm3,%xmm0 ++ pcmpeqd %xmm5,%xmm3 # compare to 7,6 ++ movdqa %xmm2,`16*($k+2)+112`(%r10) ++ movdqa %xmm4,%xmm2 ++ ++ paddd %xmm0,%xmm1 ++ pcmpeqd %xmm5,%xmm0 ++ movdqa %xmm3,`16*($k+3)+112`(%r10) ++ movdqa %xmm4,%xmm3 ++___ ++} ++$code.=<<___; # last iteration can be optimized ++ paddd %xmm1,%xmm2 ++ pcmpeqd %xmm5,%xmm1 ++ movdqa %xmm0,`16*($k+0)+112`(%r10) ++ ++ paddd %xmm2,%xmm3 ++ .byte 0x67 ++ pcmpeqd %xmm5,%xmm2 ++ movdqa %xmm1,`16*($k+1)+112`(%r10) ++ ++ pcmpeqd %xmm5,%xmm3 ++ movdqa %xmm2,`16*($k+2)+112`(%r10) ++ pand `16*($k+0)-128`($bp),%xmm0 # while it's still in register ++ ++ pand `16*($k+1)-128`($bp),%xmm1 ++ pand `16*($k+2)-128`($bp),%xmm2 ++ movdqa %xmm3,`16*($k+3)+112`(%r10) ++ pand `16*($k+3)-128`($bp),%xmm3 ++ por %xmm2,%xmm0 ++ por %xmm3,%xmm1 ++___ ++for($k=0;$k<$STRIDE/16-4;$k+=4) { ++$code.=<<___; ++ movdqa `16*($k+0)-128`($bp),%xmm4 ++ movdqa `16*($k+1)-128`($bp),%xmm5 ++ movdqa `16*($k+2)-128`($bp),%xmm2 ++ pand `16*($k+0)+112`(%r10),%xmm4 ++ movdqa `16*($k+3)-128`($bp),%xmm3 ++ pand `16*($k+1)+112`(%r10),%xmm5 ++ por %xmm4,%xmm0 ++ pand `16*($k+2)+112`(%r10),%xmm2 ++ por %xmm5,%xmm1 ++ pand `16*($k+3)+112`(%r10),%xmm3 + por %xmm2,%xmm0 ++ por %xmm3,%xmm1 ++___ ++} ++$code.=<<___; ++ por %xmm1,%xmm0 ++ pshufd \$0x4e,%xmm0,%xmm1 ++ por %xmm1,%xmm0 + lea $STRIDE($bp),$bp +- por %xmm3,%xmm0 +- + movq %xmm0,$m0 # m0=bp[0] ++ + mov ($n0),$n0 # pull n0[0] value + mov ($ap),%rax + + xor $i,$i # i=0 + xor $j,$j # j=0 + +- movq `0*$STRIDE/4-96`($bp),%xmm0 +- movq `1*$STRIDE/4-96`($bp),%xmm1 +- pand %xmm4,%xmm0 +- movq `2*$STRIDE/4-96`($bp),%xmm2 +- pand %xmm5,%xmm1 +- + mov $n0,$m1 + mulq $m0 # ap[0]*bp[0] + mov %rax,$A[0] + mov ($np),%rax + +- movq `3*$STRIDE/4-96`($bp),%xmm3 +- pand %xmm6,%xmm2 +- por %xmm1,%xmm0 +- pand %xmm7,%xmm3 +- + imulq $A[0],$m1 # "tp[0]"*n0 + mov %rdx,$A[1] + +- por %xmm2,%xmm0 +- lea $STRIDE($bp),$bp +- por %xmm3,%xmm0 +- + mulq $m1 # np[0]*m1 + add %rax,$A[0] # discarded + mov 8($ap),%rax +@@ -550,8 +630,6 @@ $code.=<<___; + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + +- movq %xmm0,$m0 # bp[1] +- + xor $N[1],$N[1] + add $A[0],$N[0] + adc \$0,$N[1] +@@ -561,12 +639,34 @@ $code.=<<___; + lea 1($i),$i # i++ + .align 4 + .Louter4x: ++ lea 32+128(%rsp,$num,8),%rdx # where 256-byte mask is (+size optimization) ++ pxor %xmm4,%xmm4 ++ pxor %xmm5,%xmm5 ++___ ++for($k=0;$k<$STRIDE/16;$k+=4) { ++$code.=<<___; ++ movdqa `16*($k+0)-128`($bp),%xmm0 ++ movdqa `16*($k+1)-128`($bp),%xmm1 ++ movdqa `16*($k+2)-128`($bp),%xmm2 ++ movdqa `16*($k+3)-128`($bp),%xmm3 ++ pand `16*($k+0)-128`(%rdx),%xmm0 ++ pand `16*($k+1)-128`(%rdx),%xmm1 ++ por %xmm0,%xmm4 ++ pand `16*($k+2)-128`(%rdx),%xmm2 ++ por %xmm1,%xmm5 ++ pand `16*($k+3)-128`(%rdx),%xmm3 ++ por %xmm2,%xmm4 ++ por %xmm3,%xmm5 ++___ ++} ++$code.=<<___; ++ por %xmm5,%xmm4 ++ pshufd \$0x4e,%xmm4,%xmm0 ++ por %xmm4,%xmm0 ++ lea $STRIDE($bp),$bp ++ movq %xmm0,$m0 # m0=bp[i] ++ + xor $j,$j # j=0 +- movq `0*$STRIDE/4-96`($bp),%xmm0 +- movq `1*$STRIDE/4-96`($bp),%xmm1 +- pand %xmm4,%xmm0 +- movq `2*$STRIDE/4-96`($bp),%xmm2 +- pand %xmm5,%xmm1 + + mov (%rsp),$A[0] + mov $n0,$m1 +@@ -575,18 +675,9 @@ $code.=<<___; + mov ($np),%rax + adc \$0,%rdx + +- movq `3*$STRIDE/4-96`($bp),%xmm3 +- pand %xmm6,%xmm2 +- por %xmm1,%xmm0 +- pand %xmm7,%xmm3 +- + imulq $A[0],$m1 # tp[0]*n0 + mov %rdx,$A[1] + +- por %xmm2,%xmm0 +- lea $STRIDE($bp),$bp +- por %xmm3,%xmm0 +- + mulq $m1 # np[0]*m1 + add %rax,$A[0] # "$N[0]", discarded + mov 8($ap),%rax +@@ -718,7 +809,6 @@ $code.=<<___; + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + +- movq %xmm0,$m0 # bp[i+1] + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + + xor $N[1],$N[1] +@@ -809,13 +899,7 @@ ___ + $code.=<<___; + mov 8(%rsp,$num,8),%rsi # restore %rsp + mov \$1,%rax +-___ +-$code.=<<___ if ($win64); +- movaps (%rsi),%xmm6 +- movaps 0x10(%rsi),%xmm7 +- lea 0x28(%rsi),%rsi +-___ +-$code.=<<___; ++ + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 +@@ -830,8 +914,8 @@ ___ + }}} + + { +-my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order +- ("%rdi","%rsi","%rdx","%rcx"); # Unix order ++my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%rdx","%r8", "%r9d") : # Win64 order ++ ("%rdi","%rsi","%rdx","%ecx"); # Unix order + my $out=$inp; + my $STRIDE=2**5*8; + my $N=$STRIDE/4; +@@ -859,53 +943,89 @@ bn_scatter5: + .type bn_gather5,\@abi-omnipotent + .align 16 + bn_gather5: +-___ +-$code.=<<___ if ($win64); +-.LSEH_begin_bn_gather5: ++.LSEH_begin_bn_gather5: # Win64 thing, but harmless in other cases + # I can't trust assembler to use specific encoding:-( +- .byte 0x48,0x83,0xec,0x28 #sub \$0x28,%rsp +- .byte 0x0f,0x29,0x34,0x24 #movaps %xmm6,(%rsp) +- .byte 0x0f,0x29,0x7c,0x24,0x10 #movdqa %xmm7,0x10(%rsp) +-___ +-$code.=<<___; +- mov $idx,%r11 +- shr \$`log($N/8)/log(2)`,$idx +- and \$`$N/8-1`,%r11 +- not $idx +- lea .Lmagic_masks(%rip),%rax +- and \$`2**5/($N/8)-1`,$idx # 5 is "window size" +- lea 96($tbl,%r11,8),$tbl # pointer within 1st cache line +- movq 0(%rax,$idx,8),%xmm4 # set of masks denoting which +- movq 8(%rax,$idx,8),%xmm5 # cache line contains element +- movq 16(%rax,$idx,8),%xmm6 # denoted by 7th argument +- movq 24(%rax,$idx,8),%xmm7 ++ .byte 0x4c,0x8d,0x14,0x24 # lea (%rsp),%r10 ++ .byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 # sub $0x108,%rsp ++ lea .Linc(%rip),%rax ++ and \$-16,%rsp # shouldn't be formally required ++ ++ movd $idx,%xmm5 ++ movdqa 0(%rax),%xmm0 # 00000001000000010000000000000000 ++ movdqa 16(%rax),%xmm1 # 00000002000000020000000200000002 ++ lea 128($tbl),%r11 # size optimization ++ lea 128(%rsp),%rax # size optimization ++ ++ pshufd \$0,%xmm5,%xmm5 # broadcast $idx ++ movdqa %xmm1,%xmm4 ++ movdqa %xmm1,%xmm2 ++___ ++######################################################################## ++# calculate mask by comparing 0..31 to $idx and save result to stack ++# ++for($i=0;$i<$STRIDE/16;$i+=4) { ++$code.=<<___; ++ paddd %xmm0,%xmm1 ++ pcmpeqd %xmm5,%xmm0 # compare to 1,0 ++___ ++$code.=<<___ if ($i); ++ movdqa %xmm3,`16*($i-1)-128`(%rax) ++___ ++$code.=<<___; ++ movdqa %xmm4,%xmm3 ++ ++ paddd %xmm1,%xmm2 ++ pcmpeqd %xmm5,%xmm1 # compare to 3,2 ++ movdqa %xmm0,`16*($i+0)-128`(%rax) ++ movdqa %xmm4,%xmm0 ++ ++ paddd %xmm2,%xmm3 ++ pcmpeqd %xmm5,%xmm2 # compare to 5,4 ++ movdqa %xmm1,`16*($i+1)-128`(%rax) ++ movdqa %xmm4,%xmm1 ++ ++ paddd %xmm3,%xmm0 ++ pcmpeqd %xmm5,%xmm3 # compare to 7,6 ++ movdqa %xmm2,`16*($i+2)-128`(%rax) ++ movdqa %xmm4,%xmm2 ++___ ++} ++$code.=<<___; ++ movdqa %xmm3,`16*($i-1)-128`(%rax) + jmp .Lgather +-.align 16 +-.Lgather: +- movq `0*$STRIDE/4-96`($tbl),%xmm0 +- movq `1*$STRIDE/4-96`($tbl),%xmm1 +- pand %xmm4,%xmm0 +- movq `2*$STRIDE/4-96`($tbl),%xmm2 +- pand %xmm5,%xmm1 +- movq `3*$STRIDE/4-96`($tbl),%xmm3 +- pand %xmm6,%xmm2 +- por %xmm1,%xmm0 +- pand %xmm7,%xmm3 +- por %xmm2,%xmm0 +- lea $STRIDE($tbl),$tbl +- por %xmm3,%xmm0 + ++.align 32 ++.Lgather: ++ pxor %xmm4,%xmm4 ++ pxor %xmm5,%xmm5 ++___ ++for($i=0;$i<$STRIDE/16;$i+=4) { ++$code.=<<___; ++ movdqa `16*($i+0)-128`(%r11),%xmm0 ++ movdqa `16*($i+1)-128`(%r11),%xmm1 ++ movdqa `16*($i+2)-128`(%r11),%xmm2 ++ pand `16*($i+0)-128`(%rax),%xmm0 ++ movdqa `16*($i+3)-128`(%r11),%xmm3 ++ pand `16*($i+1)-128`(%rax),%xmm1 ++ por %xmm0,%xmm4 ++ pand `16*($i+2)-128`(%rax),%xmm2 ++ por %xmm1,%xmm5 ++ pand `16*($i+3)-128`(%rax),%xmm3 ++ por %xmm2,%xmm4 ++ por %xmm3,%xmm5 ++___ ++} ++$code.=<<___; ++ por %xmm5,%xmm4 ++ lea $STRIDE(%r11),%r11 ++ pshufd \$0x4e,%xmm4,%xmm0 ++ por %xmm4,%xmm0 + movq %xmm0,($out) # m0=bp[0] + lea 8($out),$out + sub \$1,$num + jnz .Lgather +-___ +-$code.=<<___ if ($win64); +- movaps %xmm6,(%rsp) +- movaps %xmm7,0x10(%rsp) +- lea 0x28(%rsp),%rsp +-___ +-$code.=<<___; ++ ++ lea (%r10),%rsp + ret + .LSEH_end_bn_gather5: + .size bn_gather5,.-bn_gather5 +@@ -913,9 +1033,9 @@ ___ + } + $code.=<<___; + .align 64 +-.Lmagic_masks: +- .long 0,0, 0,0, 0,0, -1,-1 +- .long 0,0, 0,0, 0,0, 0,0 ++.Linc: ++ .long 0,0, 1,1 ++ .long 2,2, 2,2 + .asciz "Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by " + ___ + +@@ -954,7 +1074,7 @@ mul_handler: + cmp %r10,%rbx # context->RipR13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 +- movups %xmm0,512($context) # restore context->Xmm6 +- movups %xmm1,528($context) # restore context->Xmm7 + + .Lcommon_seh_tail: + mov 8(%rax),%rdi +@@ -1057,10 +1173,9 @@ mul_handler: + .rva .Lmul4x_alloca,.Lmul4x_body,.Lmul4x_epilogue # HandlerData[] + .align 8 + .LSEH_info_bn_gather5: +- .byte 0x01,0x0d,0x05,0x00 +- .byte 0x0d,0x78,0x01,0x00 #movaps 0x10(rsp),xmm7 +- .byte 0x08,0x68,0x00,0x00 #movaps (rsp),xmm6 +- .byte 0x04,0x42,0x00,0x00 #sub rsp,0x28 ++ .byte 0x01,0x0b,0x03,0x0a ++ .byte 0x0b,0x01,0x21,0x00 # sub rsp,0x108 ++ .byte 0x04,0xa3,0x00,0x00 # lea r10,(rsp), set_frame r10 + .align 8 + ___ + } +diff -up openssl-1.0.1e/crypto/bn/bn_exp.c.rsa-const openssl-1.0.1e/crypto/bn/bn_exp.c +--- openssl-1.0.1e/crypto/bn/bn_exp.c.rsa-const 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/bn/bn_exp.c 2016-02-24 12:00:20.807856735 +0100 +@@ -111,6 +111,7 @@ + + + #include "cryptlib.h" ++#include "constant_time_locl.h" + #include "bn_lcl.h" + + #include +@@ -534,30 +535,74 @@ err: + * as cache lines are concerned. The following functions are used to transfer a BIGNUM + * from/to that table. */ + +-static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, int idx, int width) ++static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, int idx, int window) + { +- size_t i, j; ++ int i, j; ++ int width = 1 << window; ++ BN_ULONG *table = (BN_ULONG *)buf; + + if (top > b->top) + top = b->top; /* this works because 'buf' is explicitly zeroed */ +- for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width) ++ for (i = 0, j=idx; i < top; i++, j+=width) + { +- buf[j] = ((unsigned char*)b->d)[i]; ++ table[j] = b->d[i]; + } + + return 1; + } + +-static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width) ++static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int window) + { +- size_t i, j; ++ int i, j; ++ int width = 1 << window; ++ volatile BN_ULONG *table = (volatile BN_ULONG *)buf; + + if (bn_wexpand(b, top) == NULL) + return 0; + +- for (i=0, j=idx; i < top * sizeof b->d[0]; i++, j+=width) ++ if (window <= 3) + { +- ((unsigned char*)b->d)[i] = buf[j]; ++ for (i = 0; i < top; i++, table += width) ++ { ++ BN_ULONG acc = 0; ++ ++ for (j = 0; j < width; j++) ++ { ++ acc |= table[j] & ++ ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); ++ } ++ ++ b->d[i] = acc; ++ } ++ } ++ else ++ { ++ int xstride = 1 << (window - 2); ++ BN_ULONG y0, y1, y2, y3; ++ ++ i = idx >> (window - 2); /* equivalent of idx / xstride */ ++ idx &= xstride - 1; /* equivalent of idx % xstride */ ++ ++ y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1); ++ y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1); ++ y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1); ++ y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1); ++ ++ for (i = 0; i < top; i++, table += width) ++ { ++ BN_ULONG acc = 0; ++ ++ for (j = 0; j < xstride; j++) ++ { ++ acc |= ( (table[j + 0 * xstride] & y0) | ++ (table[j + 1 * xstride] & y1) | ++ (table[j + 2 * xstride] & y2) | ++ (table[j + 3 * xstride] & y3) ) ++ & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); ++ } ++ ++ b->d[i] = acc; ++ } + } + + b->top = top; +@@ -592,17 +637,27 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + bn_check_top(p); + bn_check_top(m); + +- top = m->top; +- +- if (!(m->d[0] & 1)) ++ if (!BN_is_odd(m)) + { + BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,BN_R_CALLED_WITH_EVEN_MODULUS); + return(0); + } ++ ++ top = m->top; ++ + bits=BN_num_bits(p); + if (bits == 0) + { +- ret = BN_one(rr); ++ /* x**0 mod 1 is still zero. */ ++ if (BN_is_one(m)) ++ { ++ ret = 1; ++ BN_zero(rr); ++ } ++ else ++ { ++ ret = BN_one(rr); ++ } + return ret; + } + +@@ -680,7 +735,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + + /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as + * 512-bit RSA is hardly relevant, we omit it to spare size... */ +- if (window==5) ++ if (window==5 && top>1) + { + void bn_mul_mont_gather5(BN_ULONG *rp,const BN_ULONG *ap, + const void *table,const BN_ULONG *np, +@@ -767,8 +822,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + else + #endif + { +- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, numPowers)) goto err; +- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, numPowers)) goto err; ++ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window)) goto err; ++ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window)) goto err; + + /* If the window size is greater than 1, then calculate + * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) +@@ -778,20 +833,20 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + if (window > 1) + { + if (!BN_mod_mul_montgomery(&tmp,&am,&am,mont,ctx)) goto err; +- if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, numPowers)) goto err; ++ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, window)) goto err; + for (i=3; i=0; i--,bits--) + wvalue = (wvalue<<1)+BN_is_bit_set(p,bits); +- if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp,top,powerbuf,wvalue,numPowers)) goto err; ++ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp,top,powerbuf,wvalue,window)) goto err; + + /* Scan the exponent one window at a time starting from the most + * significant bits. +@@ -808,7 +863,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr + } + + /* Fetch the appropriate pre-computed value from the pre-buf */ +- if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, numPowers)) goto err; ++ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, window)) goto err; + + /* Multiply the result into the intermediate result */ + if (!BN_mod_mul_montgomery(&tmp,&tmp,&am,mont,ctx)) goto err; +@@ -874,7 +929,16 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ + bits = BN_num_bits(p); + if (bits == 0) + { +- ret = BN_one(rr); ++ /* x**0 mod 1 is still zero. */ ++ if (BN_is_one(m)) ++ { ++ ret = 1; ++ BN_zero(rr); ++ } ++ else ++ { ++ ret = BN_one(rr); ++ } + return ret; + } + if (a == 0) +@@ -997,10 +1061,18 @@ int BN_mod_exp_simple(BIGNUM *r, const B + } + + bits=BN_num_bits(p); +- + if (bits == 0) + { +- ret = BN_one(r); ++ /* x**0 mod 1 is still zero. */ ++ if (BN_is_one(m)) ++ { ++ ret = 1; ++ BN_zero(r); ++ } ++ else ++ { ++ ret = BN_one(r); ++ } + return ret; + } + +diff -up openssl-1.0.1e/crypto/constant_time_locl.h.rsa-const openssl-1.0.1e/crypto/constant_time_locl.h +--- openssl-1.0.1e/crypto/constant_time_locl.h.rsa-const 2016-02-24 11:29:44.635303119 +0100 ++++ openssl-1.0.1e/crypto/constant_time_locl.h 2016-02-24 11:27:44.000000000 +0100 +@@ -0,0 +1,211 @@ ++/* crypto/constant_time_locl.h */ ++/*- ++ * Utilities for constant-time cryptography. ++ * ++ * Author: Emilia Kasper (emilia@openssl.org) ++ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley ++ * (Google). ++ * ==================================================================== ++ * Copyright (c) 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 ++ * 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.] ++ */ ++ ++#ifndef HEADER_CONSTANT_TIME_LOCL_H ++# define HEADER_CONSTANT_TIME_LOCL_H ++ ++# include "e_os.h" /* For 'inline' */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/*- ++ * The boolean methods return a bitmask of all ones (0xff...f) for true ++ * and 0 for false. This is useful for choosing a value based on the result ++ * of a conditional in constant time. For example, ++ * ++ * if (a < b) { ++ * c = a; ++ * } else { ++ * c = b; ++ * } ++ * ++ * can be written as ++ * ++ * unsigned int lt = constant_time_lt(a, b); ++ * c = constant_time_select(lt, a, b); ++ */ ++ ++/* ++ * Returns the given value with the MSB copied to all the other ++ * bits. Uses the fact that arithmetic shift shifts-in the sign bit. ++ * However, this is not ensured by the C standard so you may need to ++ * replace this with something else on odd CPUs. ++ */ ++static inline unsigned int constant_time_msb(unsigned int a); ++ ++/* ++ * Returns 0xff..f if a < b and 0 otherwise. ++ */ ++static inline unsigned int constant_time_lt(unsigned int a, unsigned int b); ++/* Convenience method for getting an 8-bit mask. */ ++static inline unsigned char constant_time_lt_8(unsigned int a, ++ unsigned int b); ++ ++/* ++ * Returns 0xff..f if a >= b and 0 otherwise. ++ */ ++static inline unsigned int constant_time_ge(unsigned int a, unsigned int b); ++/* Convenience method for getting an 8-bit mask. */ ++static inline unsigned char constant_time_ge_8(unsigned int a, ++ unsigned int b); ++ ++/* ++ * Returns 0xff..f if a == 0 and 0 otherwise. ++ */ ++static inline unsigned int constant_time_is_zero(unsigned int a); ++/* Convenience method for getting an 8-bit mask. */ ++static inline unsigned char constant_time_is_zero_8(unsigned int a); ++ ++/* ++ * Returns 0xff..f if a == b and 0 otherwise. ++ */ ++static inline unsigned int constant_time_eq(unsigned int a, unsigned int b); ++/* Convenience method for getting an 8-bit mask. */ ++static inline unsigned char constant_time_eq_8(unsigned int a, ++ unsigned int b); ++/* Signed integers. */ ++static inline unsigned int constant_time_eq_int(int a, int b); ++/* Convenience method for getting an 8-bit mask. */ ++static inline unsigned char constant_time_eq_int_8(int a, int b); ++ ++/*- ++ * Returns (mask & a) | (~mask & b). ++ * ++ * When |mask| is all 1s or all 0s (as returned by the methods above), ++ * the select methods return either |a| (if |mask| is nonzero) or |b| ++ * (if |mask| is zero). ++ */ ++static inline unsigned int constant_time_select(unsigned int mask, ++ unsigned int a, ++ unsigned int b); ++/* Convenience method for unsigned chars. */ ++static inline unsigned char constant_time_select_8(unsigned char mask, ++ unsigned char a, ++ unsigned char b); ++/* Convenience method for signed integers. */ ++static inline int constant_time_select_int(unsigned int mask, int a, int b); ++ ++static inline unsigned int constant_time_msb(unsigned int a) ++{ ++ return 0 - (a >> (sizeof(a) * 8 - 1)); ++} ++ ++static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) ++{ ++ return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); ++} ++ ++static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) ++{ ++ return (unsigned char)(constant_time_lt(a, b)); ++} ++ ++static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) ++{ ++ return ~constant_time_lt(a, b); ++} ++ ++static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) ++{ ++ return (unsigned char)(constant_time_ge(a, b)); ++} ++ ++static inline unsigned int constant_time_is_zero(unsigned int a) ++{ ++ return constant_time_msb(~a & (a - 1)); ++} ++ ++static inline unsigned char constant_time_is_zero_8(unsigned int a) ++{ ++ return (unsigned char)(constant_time_is_zero(a)); ++} ++ ++static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) ++{ ++ return constant_time_is_zero(a ^ b); ++} ++ ++static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) ++{ ++ return (unsigned char)(constant_time_eq(a, b)); ++} ++ ++static inline unsigned int constant_time_eq_int(int a, int b) ++{ ++ return constant_time_eq((unsigned)(a), (unsigned)(b)); ++} ++ ++static inline unsigned char constant_time_eq_int_8(int a, int b) ++{ ++ return constant_time_eq_8((unsigned)(a), (unsigned)(b)); ++} ++ ++static inline unsigned int constant_time_select(unsigned int mask, ++ unsigned int a, ++ unsigned int b) ++{ ++ return (mask & a) | (~mask & b); ++} ++ ++static inline unsigned char constant_time_select_8(unsigned char mask, ++ unsigned char a, ++ unsigned char b) ++{ ++ return (unsigned char)(constant_time_select(mask, a, b)); ++} ++ ++static inline int constant_time_select_int(unsigned int mask, int a, int b) ++{ ++ return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); ++} ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* HEADER_CONSTANT_TIME_LOCL_H */ +diff -up openssl-1.0.1e/crypto/perlasm/x86_64-xlate.pl.rsa-const openssl-1.0.1e/crypto/perlasm/x86_64-xlate.pl +--- openssl-1.0.1e/crypto/perlasm/x86_64-xlate.pl.rsa-const 2016-01-14 17:38:50.121212850 +0100 ++++ openssl-1.0.1e/crypto/perlasm/x86_64-xlate.pl 2016-02-24 11:26:40.316912890 +0100 +@@ -121,7 +121,7 @@ my %globals; + $self->{sz} = ""; + } elsif ($self->{op} =~ /^v/) { # VEX + $self->{sz} = ""; +- } elsif ($self->{op} =~ /movq/ && $line =~ /%xmm/) { ++ } elsif ($self->{op} =~ /mov[dq]/ && $line =~ /%xmm/) { + $self->{sz} = ""; + } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) { + $self->{op} = $1; diff --git a/SOURCES/openssl-1.0.1e-cve-2016-0705.patch b/SOURCES/openssl-1.0.1e-cve-2016-0705.patch new file mode 100755 index 00000000..b82d7a3d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-0705.patch @@ -0,0 +1,45 @@ +diff -up openssl-1.0.1e/crypto/dsa/dsa_ameth.c.dsa-doublefree openssl-1.0.1e/crypto/dsa/dsa_ameth.c +--- openssl-1.0.1e/crypto/dsa/dsa_ameth.c.dsa-doublefree 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_ameth.c 2016-02-24 14:38:46.075165304 +0100 +@@ -201,6 +201,8 @@ static int dsa_priv_decode(EVP_PKEY *pke + STACK_OF(ASN1_TYPE) *ndsa = NULL; + DSA *dsa = NULL; + ++ int ret = 0; ++ + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); +@@ -281,23 +283,21 @@ static int dsa_priv_decode(EVP_PKEY *pke + } + + EVP_PKEY_assign_DSA(pkey, dsa); +- BN_CTX_free (ctx); +- if(ndsa) +- sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); +- else +- ASN1_INTEGER_free(privkey); + +- return 1; ++ ret = 1; ++ goto done; + + decerr: + DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); + dsaerr: +- BN_CTX_free (ctx); +- if (privkey) +- ASN1_INTEGER_free(privkey); +- sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); + DSA_free(dsa); +- return 0; ++ done: ++ BN_CTX_free (ctx); ++ if (ndsa) ++ sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); ++ else ++ ASN1_INTEGER_free(privkey); ++ return ret; + } + + static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) diff --git a/SOURCES/openssl-1.0.1e-cve-2016-0797.patch b/SOURCES/openssl-1.0.1e-cve-2016-0797.patch new file mode 100755 index 00000000..278c3534 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-0797.patch @@ -0,0 +1,74 @@ +diff -up openssl-1.0.1e/crypto/bn/bn.h.bn-hex openssl-1.0.1e/crypto/bn/bn.h +--- openssl-1.0.1e/crypto/bn/bn.h.bn-hex 2016-02-24 14:23:33.020233047 +0100 ++++ openssl-1.0.1e/crypto/bn/bn.h 2016-02-24 14:23:06.078615397 +0100 +@@ -129,6 +129,7 @@ + #ifndef OPENSSL_NO_FP_API + #include /* FILE */ + #endif ++#include + #include + #include + +@@ -640,7 +641,8 @@ const BIGNUM *BN_get0_nist_prime_521(voi + + /* library internal functions */ + +-#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\ ++#define bn_expand(a,bits) (bits > (INT_MAX - BN_BITS2 + 1)?\ ++ NULL:(((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\ + (a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2)) + #define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) + BIGNUM *bn_expand2(BIGNUM *a, int words); +diff -up openssl-1.0.1e/crypto/bn/bn_print.c.bn-hex openssl-1.0.1e/crypto/bn/bn_print.c +--- openssl-1.0.1e/crypto/bn/bn_print.c.bn-hex 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/bn/bn_print.c 2016-02-24 14:15:21.215948376 +0100 +@@ -58,6 +58,7 @@ + + #include + #include ++#include + #include "cryptlib.h" + #include + #include "bn_lcl.h" +@@ -180,8 +181,10 @@ int BN_hex2bn(BIGNUM **bn, const char *a + + if (*a == '-') { neg=1; a++; } + +- for (i=0; isxdigit((unsigned char) a[i]); i++) ++ for (i=0; i <= (INT_MAX/4) && isxdigit((unsigned char) a[i]); i++) + ; ++ if (i > INT_MAX/4) ++ goto err; + + num=i+neg; + if (bn == NULL) return(num); +@@ -197,7 +200,7 @@ int BN_hex2bn(BIGNUM **bn, const char *a + BN_zero(ret); + } + +- /* i is the number of hex digests; */ ++ /* i is the number of hex digits */ + if (bn_expand(ret,i*4) == NULL) goto err; + + j=i; /* least significant 'hex' */ +@@ -246,8 +249,10 @@ int BN_dec2bn(BIGNUM **bn, const char *a + if ((a == NULL) || (*a == '\0')) return(0); + if (*a == '-') { neg=1; a++; } + +- for (i=0; isdigit((unsigned char) a[i]); i++) ++ for (i=0; i <= (INT_MAX/4) && isdigit((unsigned char) a[i]); i++) + ; ++ if (i > INT_MAX/4) ++ goto err; + + num=i+neg; + if (bn == NULL) return(num); +@@ -264,7 +269,7 @@ int BN_dec2bn(BIGNUM **bn, const char *a + BN_zero(ret); + } + +- /* i is the number of digests, a bit of an over expand; */ ++ /* i is the number of digits, a bit of an over expand */ + if (bn_expand(ret,i*4) == NULL) goto err; + + j=BN_DEC_NUM-(i%BN_DEC_NUM); diff --git a/SOURCES/openssl-1.0.1e-cve-2016-0799.patch b/SOURCES/openssl-1.0.1e-cve-2016-0799.patch new file mode 100755 index 00000000..42a3d017 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-0799.patch @@ -0,0 +1,437 @@ +diff -up openssl-1.0.1e/crypto/bio/b_print.c.bio-printf openssl-1.0.1e/crypto/bio/b_print.c +--- openssl-1.0.1e/crypto/bio/b_print.c.bio-printf 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/bio/b_print.c 2016-04-07 14:36:55.538117697 +0200 +@@ -125,14 +125,14 @@ + #define LLONG long + #endif + +-static void fmtstr (char **, char **, size_t *, size_t *, ++static int fmtstr(char **, char **, size_t *, size_t *, + const char *, int, int, int); +-static void fmtint (char **, char **, size_t *, size_t *, ++static int fmtint(char **, char **, size_t *, size_t *, + LLONG, int, int, int, int); +-static void fmtfp (char **, char **, size_t *, size_t *, ++static int fmtfp(char **, char **, size_t *, size_t *, + LDOUBLE, int, int, int); +-static void doapr_outch (char **, char **, size_t *, size_t *, int); +-static void _dopr(char **sbuffer, char **buffer, ++static int doapr_outch(char **, char **, size_t *, size_t *, int); ++static int _dopr(char **sbuffer, char **buffer, + size_t *maxlen, size_t *retlen, int *truncated, + const char *format, va_list args); + +@@ -165,7 +165,7 @@ static void _dopr(char **sbuffer, char * + #define char_to_int(p) (p - '0') + #define OSSL_MAX(p,q) ((p >= q) ? p : q) + +-static void ++static int + _dopr( + char **sbuffer, + char **buffer, +@@ -200,7 +200,8 @@ _dopr( + if (ch == '%') + state = DP_S_FLAGS; + else +- doapr_outch(sbuffer,buffer, &currlen, maxlen, ch); ++ if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) ++ return 0; + ch = *format++; + break; + case DP_S_FLAGS: +@@ -306,8 +307,9 @@ _dopr( + value = va_arg(args, int); + break; + } +- fmtint(sbuffer, buffer, &currlen, maxlen, +- value, 10, min, max, flags); ++ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min, ++ max, flags)) ++ return 0; + break; + case 'X': + flags |= DP_F_UP; +@@ -332,17 +334,19 @@ _dopr( + unsigned int); + break; + } +- fmtint(sbuffer, buffer, &currlen, maxlen, value, ++ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, + ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), +- min, max, flags); ++ min, max, flags)) ++ return 0; + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); +- fmtfp(sbuffer, buffer, &currlen, maxlen, +- fvalue, min, max, flags); ++ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max, ++ flags)) ++ return 0; + break; + case 'E': + flags |= DP_F_UP; +@@ -361,8 +365,9 @@ _dopr( + fvalue = va_arg(args, double); + break; + case 'c': +- doapr_outch(sbuffer, buffer, &currlen, maxlen, +- va_arg(args, int)); ++ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ++ va_arg(args, int))) ++ return 0; + break; + case 's': + strvalue = va_arg(args, char *); +@@ -372,13 +377,15 @@ _dopr( + else + max = *maxlen; + } +- fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, +- flags, min, max); ++ if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, ++ flags, min, max)) ++ return 0; + break; + case 'p': + value = (long)va_arg(args, void *); +- fmtint(sbuffer, buffer, &currlen, maxlen, +- value, 16, min, max, flags|DP_F_NUM); ++ if (!fmtint(sbuffer, buffer, &currlen, maxlen, ++ value, 16, min, max, flags | DP_F_NUM)) ++ return 0; + break; + case 'n': /* XXX */ + if (cflags == DP_C_SHORT) { +@@ -400,7 +407,8 @@ _dopr( + } + break; + case '%': +- doapr_outch(sbuffer, buffer, &currlen, maxlen, ch); ++ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) ++ return 0; + break; + case 'w': + /* not supported yet, treat as next char */ +@@ -424,12 +432,13 @@ _dopr( + *truncated = (currlen > *maxlen - 1); + if (*truncated) + currlen = *maxlen - 1; +- doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'); ++ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) ++ return 0; + *retlen = currlen - 1; +- return; ++ return 1; + } + +-static void ++static int + fmtstr( + char **sbuffer, + char **buffer, +@@ -440,36 +449,44 @@ fmtstr( + int min, + int max) + { +- int padlen, strln; ++ int padlen; ++ size_t strln; + int cnt = 0; + + if (value == 0) + value = ""; +- for (strln = 0; value[strln]; ++strln) +- ; ++ ++ strln = strlen(value); ++ if (strln > INT_MAX) ++ strln = INT_MAX; ++ + padlen = min - strln; +- if (padlen < 0) ++ if (min < 0 || padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; + + while ((padlen > 0) && (cnt < max)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) ++ return 0; + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, *value++); ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++)) ++ return 0; + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) ++ return 0; + ++padlen; + ++cnt; + } ++ return 1; + } + +-static void ++static int + fmtint( + char **sbuffer, + char **buffer, +@@ -533,37 +550,44 @@ fmtint( + + /* spaces */ + while (spadlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) ++ return 0; + --spadlen; + } + + /* sign */ + if (signvalue) +- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) ++ return 0; + + /* prefix */ + while (*prefix) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix); ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix)) ++ return 0; + prefix++; + } + + /* zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) ++ return 0; + --zpadlen; + } + } + /* digits */ +- while (place > 0) +- doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]); ++ while (place > 0) { ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place])) ++ return 0; ++ } + + /* left justified spaces */ + while (spadlen < 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) ++ return 0; + ++spadlen; + } +- return; ++ return 1; + } + + static LDOUBLE +@@ -597,7 +621,7 @@ roundv(LDOUBLE value) + return intpart; + } + +-static void ++static int + fmtfp( + char **sbuffer, + char **buffer, +@@ -616,7 +640,6 @@ fmtfp( + int fplace = 0; + int padlen = 0; + int zpadlen = 0; +- int caps = 0; + long intpart; + long fracpart; + long max10; +@@ -650,9 +673,7 @@ fmtfp( + + /* convert integer part */ + do { +- iconvert[iplace++] = +- (caps ? "0123456789ABCDEF" +- : "0123456789abcdef")[intpart % 10]; ++ iconvert[iplace++] = "0123456789"[intpart % 10]; + intpart = (intpart / 10); + } while (intpart && (iplace < (int)sizeof(iconvert))); + if (iplace == sizeof iconvert) +@@ -661,9 +682,7 @@ fmtfp( + + /* convert fractional part */ + do { +- fconvert[fplace++] = +- (caps ? "0123456789ABCDEF" +- : "0123456789abcdef")[fracpart % 10]; ++ fconvert[fplace++] = "0123456789"[fracpart % 10]; + fracpart = (fracpart / 10); + } while (fplace < max); + if (fplace == sizeof fconvert) +@@ -682,47 +701,61 @@ fmtfp( + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) ++ return 0; + --padlen; + signvalue = 0; + } + while (padlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) ++ return 0; + --padlen; + } + } + while (padlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) ++ return 0; + --padlen; + } +- if (signvalue) +- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); ++ if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) ++ return 0; + +- while (iplace > 0) +- doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]); ++ while (iplace > 0) { ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace])) ++ return 0; ++ } + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0 || (flags & DP_F_NUM)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '.'); ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.')) ++ return 0; + +- while (fplace > 0) +- doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]); ++ while (fplace > 0) { ++ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ++ fconvert[--fplace])) ++ return 0; ++ } + } + while (zpadlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) ++ return 0; + --zpadlen; + } + + while (padlen < 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); ++ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) ++ return 0; + ++padlen; + } ++ return 1; + } + +-static void ++#define BUFFER_INC 1024 ++ ++static int + doapr_outch( + char **sbuffer, + char **buffer, +@@ -733,24 +766,30 @@ doapr_outch( + /* If we haven't at least one buffer, someone has doe a big booboo */ + assert(*sbuffer != NULL || buffer != NULL); + +- if (buffer) { +- while (*currlen >= *maxlen) { +- if (*buffer == NULL) { +- if (*maxlen == 0) +- *maxlen = 1024; ++ /* |currlen| must always be <= |*maxlen| */ ++ assert(*currlen <= *maxlen); ++ ++ if (buffer && *currlen == *maxlen) { ++ if (*maxlen > INT_MAX - BUFFER_INC) ++ return 0; ++ ++ *maxlen += BUFFER_INC; ++ if (*buffer == NULL) { + *buffer = OPENSSL_malloc(*maxlen); ++ if (*buffer == NULL) ++ return 0; + if (*currlen > 0) { + assert(*sbuffer != NULL); + memcpy(*buffer, *sbuffer, *currlen); + } + *sbuffer = NULL; +- } else { +- *maxlen += 1024; +- *buffer = OPENSSL_realloc(*buffer, *maxlen); +- } ++ } else { ++ char *tmpbuf; ++ tmpbuf = OPENSSL_realloc(*buffer, *maxlen); ++ if (tmpbuf == NULL) ++ return 0; ++ *buffer = tmpbuf; + } +- /* What to do if *buffer is NULL? */ +- assert(*sbuffer != NULL || *buffer != NULL); + } + + if (*currlen < *maxlen) { +@@ -760,7 +799,7 @@ doapr_outch( + (*buffer)[(*currlen)++] = (char)c; + } + +- return; ++ return 1; + } + + /***************************************************************************/ +@@ -792,11 +831,15 @@ int BIO_vprintf (BIO *bio, const char *f + + dynbuf = NULL; + CRYPTO_push_info("doapr()"); +- _dopr(&hugebufp, &dynbuf, &hugebufsize, +- &retlen, &ignored, format, args); ++ if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, ++ args)) ++ { ++ OPENSSL_free(dynbuf); ++ return -1; ++ } + if (dynbuf) + { +- ret=BIO_write(bio, dynbuf, (int)retlen); ++ ret = BIO_write(bio, dynbuf, (int)retlen); + OPENSSL_free(dynbuf); + } + else +@@ -829,7 +872,8 @@ int BIO_vsnprintf(char *buf, size_t n, c + size_t retlen; + int truncated; + +- _dopr(&buf, NULL, &n, &retlen, &truncated, format, args); ++ if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args)) ++ return -1; + + if (truncated) + /* In case of truncation, return -1 like traditional snprintf. diff --git a/SOURCES/openssl-1.0.1e-cve-2016-2105.patch b/SOURCES/openssl-1.0.1e-cve-2016-2105.patch new file mode 100755 index 00000000..b6351a0f --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-2105.patch @@ -0,0 +1,40 @@ +diff -up openssl-1.0.1e/crypto/evp/encode.c.b64-overflow openssl-1.0.1e/crypto/evp/encode.c +--- openssl-1.0.1e/crypto/evp/encode.c.b64-overflow 2016-04-07 15:45:20.000000000 +0200 ++++ openssl-1.0.1e/crypto/evp/encode.c 2016-04-29 12:46:34.232656522 +0200 +@@ -132,12 +132,12 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ct + const unsigned char *in, int inl) + { + int i,j; +- unsigned int total=0; ++ size_t total=0; + + *outl=0; + if (inl == 0) return; + OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); +- if ((ctx->num+inl) < ctx->length) ++ if (ctx->length - ctx->num > inl) + { + memcpy(&(ctx->enc_data[ctx->num]),in,inl); + ctx->num+=inl; +@@ -156,7 +156,7 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ct + *out='\0'; + total=j+1; + } +- while (inl >= ctx->length) ++ while (inl >= ctx->length && total <= INT_MAX) + { + j=EVP_EncodeBlock(out,in,ctx->length); + in+=ctx->length; +@@ -166,6 +166,12 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ct + *out='\0'; + total+=j+1; + } ++ if (total > INT_MAX) ++ { ++ /* Too much output data! */ ++ *outl = 0; ++ return; ++ } + if (inl != 0) + memcpy(&(ctx->enc_data[0]),in,inl); + ctx->num=inl; diff --git a/SOURCES/openssl-1.0.1e-cve-2016-2106.patch b/SOURCES/openssl-1.0.1e-cve-2016-2106.patch new file mode 100755 index 00000000..ada5f758 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-2106.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1e/crypto/evp/evp_enc.c.enc-overflow openssl-1.0.1e/crypto/evp/evp_enc.c +--- openssl-1.0.1e/crypto/evp/evp_enc.c.enc-overflow 2016-04-29 12:42:43.000000000 +0200 ++++ openssl-1.0.1e/crypto/evp/evp_enc.c 2016-04-29 12:56:50.253736555 +0200 +@@ -408,7 +408,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ct + OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); + if (i != 0) + { +- if (i+inl < bl) ++ if (bl - i > inl) + { + memcpy(&(ctx->buf[i]),in,inl); + ctx->buf_len+=inl; diff --git a/SOURCES/openssl-1.0.1e-cve-2016-2107.patch b/SOURCES/openssl-1.0.1e-cve-2016-2107.patch new file mode 100755 index 00000000..340267e8 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-2107.patch @@ -0,0 +1,20 @@ +diff -up openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c.padding-check openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c +--- openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c.padding-check 2016-04-29 12:42:43.000000000 +0200 ++++ openssl-1.0.1e/crypto/evp/e_aes_cbc_hmac_sha1.c 2016-04-29 13:10:13.441125487 +0200 +@@ -59,6 +59,7 @@ + #include + #include + #include "evp_locl.h" ++#include "constant_time_locl.h" + + #ifndef EVP_CIPH_FLAG_AEAD_CIPHER + #define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +@@ -278,6 +279,8 @@ static int aesni_cbc_hmac_sha1_cipher(EV + maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8); + maxpad &= 255; + ++ ret &= constant_time_ge(maxpad, pad); ++ + inp_len = len - (SHA_DIGEST_LENGTH+pad+1); + mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1))); + inp_len &= mask; diff --git a/SOURCES/openssl-1.0.1e-cve-2016-2108.patch b/SOURCES/openssl-1.0.1e-cve-2016-2108.patch new file mode 100755 index 00000000..9520ed6d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-2108.patch @@ -0,0 +1,69 @@ +diff -up openssl-1.0.1e/crypto/asn1/a_int.c.asn1-negative openssl-1.0.1e/crypto/asn1/a_int.c +--- openssl-1.0.1e/crypto/asn1/a_int.c.asn1-negative 2016-04-29 13:23:05.221797998 +0200 ++++ openssl-1.0.1e/crypto/asn1/a_int.c 2016-04-29 13:26:51.030957218 +0200 +@@ -124,6 +124,8 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, un + { + ret=a->length; + i=a->data[0]; ++ if (ret == 1 && i == 0) ++ neg = 0; + if (!neg && (i > 127)) { + pad=1; + pb=0; +@@ -157,7 +159,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, un + p += a->length - 1; + i = a->length; + /* Copy zeros to destination as long as source is zero */ +- while(!*n) { ++ while(!*n && i > 1) { + *(p--) = 0; + n--; + i--; +@@ -415,7 +417,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const B + ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR); + goto err; + } +- if (BN_is_negative(bn)) ++ if (BN_is_negative(bn) && !BN_is_zero(bn)) + ret->type = V_ASN1_NEG_INTEGER; + else ret->type=V_ASN1_INTEGER; + j=BN_num_bits(bn); +diff -up openssl-1.0.1e/crypto/asn1/a_type.c.asn1-negative openssl-1.0.1e/crypto/asn1/a_type.c +--- openssl-1.0.1e/crypto/asn1/a_type.c.asn1-negative 2016-04-29 12:42:43.000000000 +0200 ++++ openssl-1.0.1e/crypto/asn1/a_type.c 2016-04-29 13:28:40.202443787 +0200 +@@ -131,9 +131,7 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, co + result = 0; /* They do not have content. */ + break; + case V_ASN1_INTEGER: +- case V_ASN1_NEG_INTEGER: + case V_ASN1_ENUMERATED: +- case V_ASN1_NEG_ENUMERATED: + case V_ASN1_BIT_STRING: + case V_ASN1_OCTET_STRING: + case V_ASN1_SEQUENCE: +diff -up openssl-1.0.1e/crypto/asn1/tasn_dec.c.asn1-negative openssl-1.0.1e/crypto/asn1/tasn_dec.c +--- openssl-1.0.1e/crypto/asn1/tasn_dec.c.asn1-negative 2016-04-29 12:42:43.000000000 +0200 ++++ openssl-1.0.1e/crypto/asn1/tasn_dec.c 2016-04-29 13:30:08.560456293 +0200 +@@ -1011,9 +1011,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const + break; + + case V_ASN1_INTEGER: +- case V_ASN1_NEG_INTEGER: + case V_ASN1_ENUMERATED: +- case V_ASN1_NEG_ENUMERATED: + tint = (ASN1_INTEGER **)pval; + if (!c2i_ASN1_INTEGER(tint, &cont, len)) + goto err; +diff -up openssl-1.0.1e/crypto/asn1/tasn_enc.c.asn1-negative openssl-1.0.1e/crypto/asn1/tasn_enc.c +--- openssl-1.0.1e/crypto/asn1/tasn_enc.c.asn1-negative 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/tasn_enc.c 2016-04-29 13:30:34.688051394 +0200 +@@ -638,9 +638,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsig + break; + + case V_ASN1_INTEGER: +- case V_ASN1_NEG_INTEGER: + case V_ASN1_ENUMERATED: +- case V_ASN1_NEG_ENUMERATED: + /* These are all have the same content format + * as ASN1_INTEGER + */ diff --git a/SOURCES/openssl-1.0.1e-cve-2016-2109.patch b/SOURCES/openssl-1.0.1e-cve-2016-2109.patch new file mode 100755 index 00000000..dd7de61d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-cve-2016-2109.patch @@ -0,0 +1,72 @@ +diff -up openssl-1.0.1e/crypto/asn1/a_d2i_fp.c.asn1-bio-dos openssl-1.0.1e/crypto/asn1/a_d2i_fp.c +--- openssl-1.0.1e/crypto/asn1/a_d2i_fp.c.asn1-bio-dos 2013-02-11 16:02:47.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/a_d2i_fp.c 2016-04-29 13:44:52.205538739 +0200 +@@ -139,6 +139,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM * + #endif + + #define HEADER_SIZE 8 ++#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) + static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) + { + BUF_MEM *b; +@@ -230,6 +231,8 @@ static int asn1_d2i_read_bio(BIO *in, BU + want=c.slen; + if (want > (len-off)) + { ++ size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; ++ + want-=(len-off); + if (want > INT_MAX /* BIO_read takes an int length */ || + len+want < len) +@@ -237,24 +240,38 @@ static int asn1_d2i_read_bio(BIO *in, BU + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); + goto err; + } +- if (!BUF_MEM_grow_clean(b,len+want)) +- { +- ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); +- goto err; +- } + while (want > 0) + { +- i=BIO_read(in,&(b->data[len]),want); +- if (i <= 0) ++ /* ++ * Read content in chunks of increasing size ++ * so we can return an error for EOF without ++ * having to allocate the entire content length ++ * in one go. ++ */ ++ size_t chunk = want > chunk_max ? chunk_max : want; ++ ++ if (!BUF_MEM_grow_clean(b, len + chunk)) + { +- ASN1err(ASN1_F_ASN1_D2I_READ_BIO, +- ASN1_R_NOT_ENOUGH_DATA); ++ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } +- /* This can't overflow because +- * |len+want| didn't overflow. */ +- len+=i; +- want-=i; ++ want -= chunk; ++ while (chunk > 0) ++ { ++ i = BIO_read(in, &(b->data[len]), chunk); ++ if (i <= 0) ++ { ++ ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ++ ASN1_R_NOT_ENOUGH_DATA); ++ goto err; ++ } ++ /* This can't overflow because ++ * |len+want| didn't overflow. */ ++ len += i; ++ chunk -= i; ++ } ++ if (chunk_max < INT_MAX/2) ++ chunk_max *= 2; + } + } + if (off + c.slen < off) diff --git a/SOURCES/openssl-1.0.1e-defaults.patch b/SOURCES/openssl-1.0.1e-defaults.patch new file mode 100755 index 00000000..4323e87a --- /dev/null +++ b/SOURCES/openssl-1.0.1e-defaults.patch @@ -0,0 +1,62 @@ +diff -up openssl-1.0.1e/apps/openssl.cnf.defaults openssl-1.0.1e/apps/openssl.cnf +--- openssl-1.0.1e/apps/openssl.cnf.defaults 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/openssl.cnf 2014-02-06 18:00:00.170929334 +0100 +@@ -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 +@@ -103,7 +103,8 @@ emailAddress = optional + + #################################################################### + [ req ] +-default_bits = 1024 ++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.1e-disable-sslv2.patch b/SOURCES/openssl-1.0.1e-disable-sslv2.patch new file mode 100755 index 00000000..1e6bde0e --- /dev/null +++ b/SOURCES/openssl-1.0.1e-disable-sslv2.patch @@ -0,0 +1,83 @@ +diff -up openssl-1.0.1e/ssl/ssl_lib.c.disable-sslv2 openssl-1.0.1e/ssl/ssl_lib.c +--- openssl-1.0.1e/ssl/ssl_lib.c.disable-sslv2 2016-01-14 17:38:50.018210499 +0100 ++++ openssl-1.0.1e/ssl/ssl_lib.c 2016-02-16 16:00:57.151508715 +0100 +@@ -1903,6 +1903,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *m + */ + ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + ++ /* Disable SSLv2 by default (affects the SSLv23_method() only) */ ++ ret->options |= SSL_OP_NO_SSLv2; ++ + return(ret); + err: + SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); +diff -up openssl-1.0.1e/doc/apps/ciphers.pod.disable-sslv2 openssl-1.0.1e/doc/apps/ciphers.pod +--- openssl-1.0.1e/doc/apps/ciphers.pod.disable-sslv2 2016-01-14 17:38:50.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/ciphers.pod 2016-02-24 11:17:36.297955053 +0100 +@@ -572,11 +572,11 @@ Note: these ciphers can also be used in + =head2 Deprecated SSL v2.0 cipher suites. + + SSL_CK_RC4_128_WITH_MD5 RC4-MD5 +- SSL_CK_RC4_128_EXPORT40_WITH_MD5 EXP-RC4-MD5 +- SSL_CK_RC2_128_CBC_WITH_MD5 RC2-MD5 +- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 EXP-RC2-MD5 ++ SSL_CK_RC4_128_EXPORT40_WITH_MD5 Not implemented. ++ SSL_CK_RC2_128_CBC_WITH_MD5 RC2-CBC-MD5 ++ SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 Not implemented. + SSL_CK_IDEA_128_CBC_WITH_MD5 IDEA-CBC-MD5 +- SSL_CK_DES_64_CBC_WITH_MD5 DES-CBC-MD5 ++ SSL_CK_DES_64_CBC_WITH_MD5 Not implemented. + SSL_CK_DES_192_EDE3_CBC_WITH_MD5 DES-CBC3-MD5 + + =head1 NOTES +diff -up openssl-1.0.1e/ssl/s2_lib.c.disable-sslv2 openssl-1.0.1e/ssl/s2_lib.c +--- openssl-1.0.1e/ssl/s2_lib.c.disable-sslv2 2016-02-24 11:23:24.012237164 +0100 ++++ openssl-1.0.1e/ssl/s2_lib.c 2016-02-24 11:19:34.623773423 +0100 +@@ -156,6 +156,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip + 128, + }, + ++#if 0 + /* RC4_128_EXPORT40_WITH_MD5 */ + { + 1, +@@ -171,6 +172,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip + 40, + 128, + }, ++#endif + + /* RC2_128_CBC_WITH_MD5 */ + { +@@ -188,6 +190,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip + 128, + }, + ++#if 0 + /* RC2_128_CBC_EXPORT40_WITH_MD5 */ + { + 1, +@@ -203,6 +206,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip + 40, + 128, + }, ++#endif + + #ifndef OPENSSL_NO_IDEA + /* IDEA_128_CBC_WITH_MD5 */ +@@ -222,6 +226,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip + }, + #endif + ++#if 0 + /* DES_64_CBC_WITH_MD5 */ + { + 1, +@@ -237,6 +242,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_cip + 56, + 56, + }, ++#endif + + /* DES_192_EDE3_CBC_WITH_MD5 */ + { diff --git a/SOURCES/openssl-1.0.1e-doc-ciphersuites.patch b/SOURCES/openssl-1.0.1e-doc-ciphersuites.patch new file mode 100755 index 00000000..418b9e1a --- /dev/null +++ b/SOURCES/openssl-1.0.1e-doc-ciphersuites.patch @@ -0,0 +1,304 @@ +From 87887a7a658bf305bfe6619eedcbc6c3972cc188 Mon Sep 17 00:00:00 2001 +From: Hubert Kario +Date: Tue, 10 Jun 2014 14:13:33 +0200 +Subject: [PATCH] backport changes to ciphers(1) man page + +Backport of the patch: +add ECC strings to ciphers(1), point out difference between DH and ECDH +and few other changes applicable to the 1.0.1 code base. + + * Make a clear distinction between DH and ECDH key exchange. + * Group all key exchange cipher suite identifiers, first DH then ECDH + * add descriptions for all supported *DH* identifiers + * add ECDSA authentication descriptions + * add example showing how to disable all suites that offer no + authentication or encryption + * backport listing of elliptic curve cipher suites. + * backport listing of TLS 1.2 cipher suites, add note that DH_RSA + and DH_DSS is not implemented in this version + * backport of description of PSK and listing of PSK cipher suites + * backport description of AES128, AES256 and AESGCM options + * backport description of CAMELLIA128, CAMELLIA256 options +--- + doc/apps/ciphers.pod | 195 ++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 173 insertions(+), 22 deletions(-) + +diff --git a/doc/apps/ciphers.pod b/doc/apps/ciphers.pod +index f44aa00..6086d0a 100644 +--- a/doc/apps/ciphers.pod ++++ b/doc/apps/ciphers.pod +@@ -36,7 +36,7 @@ SSL v2 and for SSL v3/TLS v1. + + =item B<-V> + +-Like B<-V>, but include cipher suite codes in output (hex format). ++Like B<-v>, but include cipher suite codes in output (hex format). + + =item B<-ssl3> + +@@ -116,8 +116,8 @@ specified. + =item B + + the ciphers included in B, but not enabled by default. Currently +-this is B. Note that this rule does not cover B, which is +-not included by B (use B if necessary). ++this is B and B. Note that this rule does not cover B, ++which is not included by B (use B if necessary). + + =item B + +@@ -165,21 +165,58 @@ included. + =item B + + the cipher suites offering no authentication. This is currently the anonymous +-DH algorithms. These cipher suites are vulnerable to a "man in the middle" +-attack and so their use is normally discouraged. ++DH algorithms and anonymous ECDH algorithms. These cipher suites are vulnerable ++to a "man in the middle" attack and so their use is normally discouraged. + + =item B, B + + cipher suites using RSA key exchange. + ++=item B, B, B ++ ++cipher suites using DH key agreement and DH certificates signed by CAs with RSA ++and DSS keys or either respectively. Not implemented. ++ + =item B + +-cipher suites using ephemeral DH key agreement. ++cipher suites using ephemeral DH key agreement, including anonymous cipher ++suites. + +-=item B, B ++=item B + +-cipher suites using DH key agreement and DH certificates signed by CAs with RSA +-and DSS keys respectively. Not implemented. ++cipher suites using authenticated ephemeral DH key agreement. ++ ++=item B ++ ++anonymous DH cipher suites, note that this does not include anonymous Elliptic ++Curve DH (ECDH) cipher suites. ++ ++=item B ++ ++cipher suites using DH, including anonymous DH, ephemeral DH and fixed DH. ++ ++=item B, B, B ++ ++cipher suites using fixed ECDH key agreement signed by CAs with RSA and ECDSA ++keys or either respectively. ++ ++=item B ++ ++cipher suites using ephemeral ECDH key agreement, including anonymous ++cipher suites. ++ ++=item B ++ ++cipher suites using authenticated ephemeral ECDH key agreement. ++ ++=item B ++ ++anonymous Elliptic Curve Diffie Hellman cipher suites. ++ ++=item B ++ ++cipher suites using ECDH key exchange, including anonymous, ephemeral and ++fixed ECDH. + + =item B + +@@ -194,30 +231,39 @@ cipher suites using DSS authentication, i.e. the certificates carry DSS keys. + cipher suites effectively using DH authentication, i.e. the certificates carry + DH keys. Not implemented. + ++=item B ++ ++cipher suites effectively using ECDH authentication, i.e. the certificates ++carry ECDH keys. ++ ++=item B, B ++ ++cipher suites using ECDSA authentication, i.e. the certificates carry ECDSA ++keys. ++ + =item B, B, B, B + + ciphers suites using FORTEZZA key exchange, authentication, encryption or all + FORTEZZA algorithms. Not implemented. + +-=item B, B, B +- +-TLS v1.0, SSL v3.0 or SSL v2.0 cipher suites respectively. ++=item B, B, B, B + +-=item B +- +-cipher suites using DH, including anonymous DH. ++TLS v1.2, TLS v1.0, SSL v3.0 or SSL v2.0 cipher suites respectively. Note: ++there are no ciphersuites specific to TLS v1.1. + +-=item B ++=item B, B, B + +-anonymous DH cipher suites. ++cipher suites using 128 bit AES, 256 bit AES or either 128 or 256 bit AES. + +-=item B ++=item B + +-cipher suites using AES. ++AES in Galois Counter Mode (GCM): these ciphersuites are only supported ++in TLS v1.2. + +-=item B ++=item B, B, B + +-cipher suites using Camellia. ++cipher suites using 128 bit CAMELLIA, 256 bit CAMELLIA or either 128 or 256 bit ++CAMELLIA. + + =item B<3DES> + +@@ -251,6 +297,10 @@ cipher suites using MD5. + + cipher suites using SHA1. + ++=item B, B ++ ++ciphersuites using SHA256 or SHA384. ++ + =item B + + cipher suites using GOST R 34.10 (either 2001 or 94) for authenticaction +@@ -277,6 +327,9 @@ cipher suites, using HMAC based on GOST R 34.11-94. + + cipher suites using GOST 28147-89 MAC B HMAC. + ++=item B ++ ++cipher suites using pre-shared keys (PSK). + + =back + +@@ -423,7 +476,100 @@ Note: these ciphers can also be used in SSL v3. + TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA EXP1024-DHE-DSS-RC4-SHA + TLS_DHE_DSS_WITH_RC4_128_SHA DHE-DSS-RC4-SHA + +-=head2 SSL v2.0 cipher suites. ++=head2 Elliptic curve cipher suites. ++ ++ TLS_ECDH_RSA_WITH_NULL_SHA ECDH-RSA-NULL-SHA ++ TLS_ECDH_RSA_WITH_RC4_128_SHA ECDH-RSA-RC4-SHA ++ TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA ECDH-RSA-DES-CBC3-SHA ++ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA ECDH-RSA-AES128-SHA ++ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA ECDH-RSA-AES256-SHA ++ ++ TLS_ECDH_ECDSA_WITH_NULL_SHA ECDH-ECDSA-NULL-SHA ++ TLS_ECDH_ECDSA_WITH_RC4_128_SHA ECDH-ECDSA-RC4-SHA ++ TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA ECDH-ECDSA-DES-CBC3-SHA ++ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA ECDH-ECDSA-AES128-SHA ++ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA ECDH-ECDSA-AES256-SHA ++ ++ TLS_ECDHE_RSA_WITH_NULL_SHA ECDHE-RSA-NULL-SHA ++ TLS_ECDHE_RSA_WITH_RC4_128_SHA ECDHE-RSA-RC4-SHA ++ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA ECDHE-RSA-DES-CBC3-SHA ++ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ECDHE-RSA-AES128-SHA ++ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ECDHE-RSA-AES256-SHA ++ ++ TLS_ECDHE_ECDSA_WITH_NULL_SHA ECDHE-ECDSA-NULL-SHA ++ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA ECDHE-ECDSA-RC4-SHA ++ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA ECDHE-ECDSA-DES-CBC3-SHA ++ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ECDHE-ECDSA-AES128-SHA ++ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ECDHE-ECDSA-AES256-SHA ++ ++ TLS_ECDH_anon_WITH_NULL_SHA AECDH-NULL-SHA ++ TLS_ECDH_anon_WITH_RC4_128_SHA AECDH-RC4-SHA ++ TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA AECDH-DES-CBC3-SHA ++ TLS_ECDH_anon_WITH_AES_128_CBC_SHA AECDH-AES128-SHA ++ TLS_ECDH_anon_WITH_AES_256_CBC_SHA AECDH-AES256-SHA ++ ++=head2 TLS v1.2 cipher suites ++ ++ TLS_RSA_WITH_NULL_SHA256 NULL-SHA256 ++ ++ TLS_RSA_WITH_AES_128_CBC_SHA256 AES128-SHA256 ++ TLS_RSA_WITH_AES_256_CBC_SHA256 AES256-SHA256 ++ TLS_RSA_WITH_AES_128_GCM_SHA256 AES128-GCM-SHA256 ++ TLS_RSA_WITH_AES_256_GCM_SHA384 AES256-GCM-SHA384 ++ ++ TLS_DH_RSA_WITH_AES_128_CBC_SHA256 Not implemented. ++ TLS_DH_RSA_WITH_AES_256_CBC_SHA256 Not implemented. ++ TLS_DH_RSA_WITH_AES_128_GCM_SHA256 Not implemented. ++ TLS_DH_RSA_WITH_AES_256_GCM_SHA384 Not implemented. ++ ++ TLS_DH_DSS_WITH_AES_128_CBC_SHA256 Not implemented. ++ TLS_DH_DSS_WITH_AES_256_CBC_SHA256 Not implemented. ++ TLS_DH_DSS_WITH_AES_128_GCM_SHA256 Not implemented. ++ TLS_DH_DSS_WITH_AES_256_GCM_SHA384 Not implemented. ++ ++ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 DHE-RSA-AES128-SHA256 ++ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 DHE-RSA-AES256-SHA256 ++ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 DHE-RSA-AES128-GCM-SHA256 ++ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 DHE-RSA-AES256-GCM-SHA384 ++ ++ TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 DHE-DSS-AES128-SHA256 ++ TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 DHE-DSS-AES256-SHA256 ++ TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 DHE-DSS-AES128-GCM-SHA256 ++ TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 DHE-DSS-AES256-GCM-SHA384 ++ ++ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 ECDH-RSA-AES128-SHA256 ++ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 ECDH-RSA-AES256-SHA384 ++ TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 ECDH-RSA-AES128-GCM-SHA256 ++ TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 ECDH-RSA-AES256-GCM-SHA384 ++ ++ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 ECDH-ECDSA-AES128-SHA256 ++ TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 ECDH-ECDSA-AES256-SHA384 ++ TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 ECDH-ECDSA-AES128-GCM-SHA256 ++ TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 ECDH-ECDSA-AES256-GCM-SHA384 ++ ++ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ECDHE-RSA-AES128-SHA256 ++ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ECDHE-RSA-AES256-SHA384 ++ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ++ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ECDHE-RSA-AES256-GCM-SHA384 ++ ++ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ECDHE-ECDSA-AES128-SHA256 ++ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 ECDHE-ECDSA-AES256-SHA384 ++ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ECDHE-ECDSA-AES128-GCM-SHA256 ++ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ECDHE-ECDSA-AES256-GCM-SHA384 ++ ++ TLS_DH_anon_WITH_AES_128_CBC_SHA256 ADH-AES128-SHA256 ++ TLS_DH_anon_WITH_AES_256_CBC_SHA256 ADH-AES256-SHA256 ++ TLS_DH_anon_WITH_AES_128_GCM_SHA256 ADH-AES128-GCM-SHA256 ++ TLS_DH_anon_WITH_AES_256_GCM_SHA384 ADH-AES256-GCM-SHA384 ++ ++=head2 Pre shared keying (PSK) cipheruites ++ ++ TLS_PSK_WITH_RC4_128_SHA PSK-RC4-SHA ++ TLS_PSK_WITH_3DES_EDE_CBC_SHA PSK-3DES-EDE-CBC-SHA ++ TLS_PSK_WITH_AES_128_CBC_SHA PSK-AES128-CBC-SHA ++ TLS_PSK_WITH_AES_256_CBC_SHA PSK-AES256-CBC-SHA ++ ++=head2 Deprecated SSL v2.0 cipher suites. + + SSL_CK_RC4_128_WITH_MD5 RC4-MD5 + SSL_CK_RC4_128_EXPORT40_WITH_MD5 EXP-RC4-MD5 +@@ -452,6 +598,11 @@ strength: + + openssl ciphers -v 'ALL:!ADH:@STRENGTH' + ++Include all ciphers except ones with no encryption (eNULL) or no ++authentication (aNULL): ++ ++ openssl ciphers -v 'ALL:!aNULL' ++ + Include only 3DES ciphers and then place RSA ciphers last: + + openssl ciphers -v '3DES:+RSA' +-- +1.7.9.5 + diff --git a/SOURCES/openssl-1.0.1e-dtls-ecc-ext.patch b/SOURCES/openssl-1.0.1e-dtls-ecc-ext.patch new file mode 100755 index 00000000..2a002cc3 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-dtls-ecc-ext.patch @@ -0,0 +1,119 @@ +From 2054eb771ea29378f90d3a77c2f4015b17de702d Mon Sep 17 00:00:00 2001 +From: "Dr. Stephen Henson" +Date: Tue, 15 Jul 2014 12:20:30 +0100 +Subject: [PATCH] Add ECC extensions with DTLS. + +PR#3449 +--- + ssl/d1_clnt.c | 8 +++++++- + ssl/d1_srvr.c | 5 +++++ + ssl/t1_lib.c | 18 ++++++------------ + 3 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c +index 48e5e06..65dbb4a 100644 +--- a/ssl/d1_clnt.c ++++ b/ssl/d1_clnt.c +@@ -876,12 +876,18 @@ int dtls1_client_hello(SSL *s) + *(p++)=0; /* Add the NULL method */ + + #ifndef OPENSSL_NO_TLSEXT ++ /* TLS extensions*/ ++ if (ssl_prepare_clienthello_tlsext(s) <= 0) ++ { ++ SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); ++ goto err; ++ } + if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + { + SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR); + goto err; + } +-#endif ++#endif + + l=(p-d); + d=buf; +diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c +index 1384ab0..ef9c347 100644 +--- a/ssl/d1_srvr.c ++++ b/ssl/d1_srvr.c +@@ -980,6 +980,11 @@ int dtls1_send_server_hello(SSL *s) + #endif + + #ifndef OPENSSL_NO_TLSEXT ++ if (ssl_prepare_serverhello_tlsext(s) <= 0) ++ { ++ SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT); ++ return -1; ++ } + if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL) + { + SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR); +diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c +index f6a480d..8167a51 100644 +--- a/ssl/t1_lib.c ++++ b/ssl/t1_lib.c +@@ -453,8 +453,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c + #endif + + #ifndef OPENSSL_NO_EC +- if (s->tlsext_ecpointformatlist != NULL && +- s->version != DTLS1_VERSION) ++ if (s->tlsext_ecpointformatlist != NULL) + { + /* Add TLS extension ECPointFormats to the ClientHello message */ + long lenmax; +@@ -473,8 +472,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c + memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length); + ret+=s->tlsext_ecpointformatlist_length; + } +- if (s->tlsext_ellipticcurvelist != NULL && +- s->version != DTLS1_VERSION) ++ if (s->tlsext_ellipticcurvelist != NULL) + { + /* Add TLS extension EllipticCurves to the ClientHello message */ + long lenmax; +@@ -750,8 +748,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c + } + + #ifndef OPENSSL_NO_EC +- if (s->tlsext_ecpointformatlist != NULL && +- s->version != DTLS1_VERSION) ++ if (s->tlsext_ecpointformatlist != NULL) + { + /* Add TLS extension ECPointFormats to the ServerHello message */ + long lenmax; +@@ -1154,8 +1151,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in + #endif + + #ifndef OPENSSL_NO_EC +- else if (type == TLSEXT_TYPE_ec_point_formats && +- s->version != DTLS1_VERSION) ++ else if (type == TLSEXT_TYPE_ec_point_formats) + { + unsigned char *sdata = data; + int ecpointformatlist_length = *(sdata++); +@@ -1189,8 +1185,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in + fprintf(stderr,"\n"); + #endif + } +- else if (type == TLSEXT_TYPE_elliptic_curves && +- s->version != DTLS1_VERSION) ++ else if (type == TLSEXT_TYPE_elliptic_curves) + { + unsigned char *sdata = data; + int ellipticcurvelist_length = (*(sdata++) << 8); +@@ -1549,8 +1544,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in + } + + #ifndef OPENSSL_NO_EC +- else if (type == TLSEXT_TYPE_ec_point_formats && +- s->version != DTLS1_VERSION) ++ else if (type == TLSEXT_TYPE_ec_point_formats) + { + unsigned char *sdata = data; + int ecpointformatlist_length = *(sdata++); +-- +1.8.3.1 + diff --git a/SOURCES/openssl-1.0.1e-ecc-suiteb.patch b/SOURCES/openssl-1.0.1e-ecc-suiteb.patch new file mode 100755 index 00000000..dc87b00e --- /dev/null +++ b/SOURCES/openssl-1.0.1e-ecc-suiteb.patch @@ -0,0 +1,124 @@ +diff -up openssl-1.0.1e/apps/speed.c.suiteb openssl-1.0.1e/apps/speed.c +--- openssl-1.0.1e/apps/speed.c.suiteb 2013-11-08 18:02:53.815229706 +0100 ++++ openssl-1.0.1e/apps/speed.c 2013-11-08 18:04:47.016724297 +0100 +@@ -966,49 +966,23 @@ 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) ecdsa_doit[R_EC_P256]=2; ++ 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) ecdh_doit[R_EC_P256]=2; ++ 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 +@@ -1097,15 +1071,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 + +@@ -1184,11 +1154,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; iecdh_tmp_cb = cert->ecdh_tmp_cb; ++ ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; + #endif + + for (i = 0; i < SSL_PKEY_NUM; i++) +diff -up openssl-1.0.1e/ssl/ssl.h.ecdh-auto openssl-1.0.1e/ssl/ssl.h +--- openssl-1.0.1e/ssl/ssl.h.ecdh-auto 2014-09-17 16:20:24.354884336 +0200 ++++ openssl-1.0.1e/ssl/ssl.h 2014-09-17 16:49:29.135273514 +0200 +@@ -1563,6 +1563,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + #define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 + #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 + ++#define SSL_CTRL_SET_ECDH_AUTO 94 + #define SSL_CTRL_GET_SERVER_TMP_KEY 109 + + #define DTLSv1_get_timeout(ssl, arg) \ +@@ -1606,6 +1607,11 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + #define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) + ++#define SSL_CTX_set_ecdh_auto(ctx, onoff) \ ++ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) ++#define SSL_set_ecdh_auto(s, onoff) \ ++ SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) ++ + #define SSL_get_server_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk) + +diff -up openssl-1.0.1e/ssl/ssl_lib.c.ecdh-auto openssl-1.0.1e/ssl/ssl_lib.c +--- openssl-1.0.1e/ssl/ssl_lib.c.ecdh-auto 2014-09-17 15:52:01.616444274 +0200 ++++ openssl-1.0.1e/ssl/ssl_lib.c 2014-09-17 16:20:24.356884383 +0200 +@@ -2045,7 +2045,7 @@ void ssl_set_cert_masks(CERT *c, const S + #endif + + #ifndef OPENSSL_NO_ECDH +- have_ecdh_tmp=(c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL); ++ have_ecdh_tmp=(c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); + #endif + cpk= &(c->pkeys[SSL_PKEY_RSA_ENC]); + rsa_enc= (cpk->x509 != NULL && cpk->privatekey != NULL); +diff -up openssl-1.0.1e/ssl/ssl_locl.h.ecdh-auto openssl-1.0.1e/ssl/ssl_locl.h +--- openssl-1.0.1e/ssl/ssl_locl.h.ecdh-auto 2014-09-17 15:52:01.632444635 +0200 ++++ openssl-1.0.1e/ssl/ssl_locl.h 2014-09-17 17:26:29.764405189 +0200 +@@ -511,6 +511,8 @@ typedef struct cert_st + EC_KEY *ecdh_tmp; + /* Callback for generating ephemeral ECDH keys */ + EC_KEY *(*ecdh_tmp_cb)(SSL *ssl,int is_export,int keysize); ++ /* Select ECDH parameters automatically */ ++ int ecdh_tmp_auto; + #endif + + CERT_PKEY pkeys[SSL_PKEY_NUM]; +@@ -1091,6 +1093,7 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_CO + #ifndef OPENSSL_NO_EC + int tls1_ec_curve_id2nid(int curve_id); + int tls1_ec_nid2curve_id(int nid); ++int tls1_shared_curve(SSL *s, int nmatch); + #endif /* OPENSSL_NO_EC */ + + #ifndef OPENSSL_NO_TLSEXT +diff -up openssl-1.0.1e/ssl/s3_lib.c.ecdh-auto openssl-1.0.1e/ssl/s3_lib.c +--- openssl-1.0.1e/ssl/s3_lib.c.ecdh-auto 2014-09-17 16:20:24.352884288 +0200 ++++ openssl-1.0.1e/ssl/s3_lib.c 2014-09-17 17:37:26.274226185 +0200 +@@ -3350,6 +3350,12 @@ long ssl3_ctrl(SSL *s, int cmd, long lar + #endif + + #endif /* !OPENSSL_NO_TLSEXT */ ++ ++#ifndef OPENSSL_NO_EC ++ case SSL_CTRL_SET_ECDH_AUTO: ++ s->cert->ecdh_tmp_auto = larg; ++ return 1; ++#endif + case SSL_CTRL_GET_SERVER_TMP_KEY: + if (s->server || !s->session || !s->session->sess_cert) + return 0; +@@ -3651,6 +3657,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd + ctx->srp_ctx.strength=larg; + break; + #endif ++ ++#ifndef OPENSSL_NO_EC ++ case SSL_CTRL_SET_ECDH_AUTO: ++ ctx->cert->ecdh_tmp_auto = larg; ++ return 1; ++#endif + #endif /* !OPENSSL_NO_TLSEXT */ + + /* A Thawte special :-) */ +@@ -4003,6 +4015,14 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, S + if ( + /* if we are considering an ECC cipher suite that uses an ephemeral EC key */ + (alg_k & SSL_kEECDH) ++ && (s->cert->ecdh_tmp_auto) ++ ) ++ { ++ ok = ok && tls1_shared_curve(s, 0); ++ } ++ else if ( ++ /* if we are considering an ECC cipher suite that uses an ephemeral EC key */ ++ (alg_k & SSL_kEECDH) + /* and we have an ephemeral EC key */ + && (s->cert->ecdh_tmp != NULL) + /* and the client specified an EllipticCurves extension */ +diff -up openssl-1.0.1e/ssl/s3_srvr.c.ecdh-auto openssl-1.0.1e/ssl/s3_srvr.c +--- openssl-1.0.1e/ssl/s3_srvr.c.ecdh-auto 2014-09-17 15:52:01.644444906 +0200 ++++ openssl-1.0.1e/ssl/s3_srvr.c 2014-09-17 16:20:24.353884312 +0200 +@@ -1693,7 +1693,14 @@ int ssl3_send_server_key_exchange(SSL *s + const EC_GROUP *group; + + ecdhp=cert->ecdh_tmp; +- if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) ++ if (s->cert->ecdh_tmp_auto) ++ { ++ /* Get NID of first shared curve */ ++ int nid = tls1_shared_curve(s, 0); ++ if (nid != NID_undef) ++ ecdhp = EC_KEY_new_by_curve_name(nid); ++ } ++ else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) + { + ecdhp=s->cert->ecdh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), +@@ -1718,7 +1725,9 @@ int ssl3_send_server_key_exchange(SSL *s + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); + goto err; + } +- if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) ++ if (s->cert->ecdh_tmp_auto) ++ ecdh = ecdhp; ++ else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) + { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); + goto err; +diff -up openssl-1.0.1e/ssl/t1_lib.c.ecdh-auto openssl-1.0.1e/ssl/t1_lib.c +--- openssl-1.0.1e/ssl/t1_lib.c.ecdh-auto 2014-09-17 16:20:24.358884427 +0200 ++++ openssl-1.0.1e/ssl/t1_lib.c 2014-09-17 17:32:04.054951942 +0200 +@@ -202,6 +202,13 @@ static int nid_list[] = + NID_secp521r1 /* secp521r1 (25) */ + }; + ++static const unsigned char eccurves_default[] = ++ { ++ 0,23, /* secp256r1 (23) */ ++ 0,24, /* secp384r1 (24) */ ++ 0,25, /* secp521r1 (25) */ ++ }; ++ + static int pref_list[] = + { + NID_secp521r1, /* secp521r1 (25) */ +@@ -277,6 +284,69 @@ int tls1_ec_nid2curve_id(int nid) + return 0; + } + } ++/* Get curves list, if "sess" is set return client curves otherwise ++ * preferred list ++ */ ++static void tls1_get_curvelist(SSL *s, int sess, ++ const unsigned char **pcurves, ++ size_t *pcurveslen) ++ { ++ if (sess) ++ { ++ *pcurves = s->session->tlsext_ellipticcurvelist; ++ *pcurveslen = s->session->tlsext_ellipticcurvelist_length; ++ } ++ else ++ { ++ *pcurves = s->tlsext_ellipticcurvelist; ++ *pcurveslen = s->tlsext_ellipticcurvelist_length; ++ } ++ if (!*pcurves) ++ { ++ *pcurves = eccurves_default; ++ *pcurveslen = sizeof(eccurves_default); ++ } ++ } ++/* Return nth shared curve. If nmatch == -1 return number of ++ * matches. ++ */ ++ ++int tls1_shared_curve(SSL *s, int nmatch) ++ { ++ const unsigned char *pref, *supp; ++ size_t preflen, supplen, i, j; ++ int k; ++ /* Can't do anything on client side */ ++ if (s->server == 0) ++ return -1; ++ tls1_get_curvelist(s, !!(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), ++ &supp, &supplen); ++ tls1_get_curvelist(s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), ++ &pref, &preflen); ++ preflen /= 2; ++ supplen /= 2; ++ k = 0; ++ for (i = 0; i < preflen; i++, pref+=2) ++ { ++ const unsigned char *tsupp = supp; ++ for (j = 0; j < supplen; j++, tsupp+=2) ++ { ++ if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) ++ { ++ if (nmatch == k) ++ { ++ int id = (pref[0] << 8) | pref[1]; ++ return tls1_ec_curve_id2nid(id); ++ } ++ k++; ++ } ++ } ++ } ++ if (nmatch == -1) ++ return k; ++ return 0; ++ } ++ + #endif /* OPENSSL_NO_EC */ + + #ifndef OPENSSL_NO_TLSEXT diff --git a/SOURCES/openssl-1.0.1e-enc-fail.patch b/SOURCES/openssl-1.0.1e-enc-fail.patch new file mode 100755 index 00000000..a5a43f08 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-enc-fail.patch @@ -0,0 +1,39 @@ +diff -up openssl-1.0.1e/crypto/evp/bio_enc.c.enc-fail openssl-1.0.1e/crypto/evp/bio_enc.c +--- openssl-1.0.1e/crypto/evp/bio_enc.c.enc-fail 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/bio_enc.c 2014-03-04 15:21:12.185821738 +0100 +@@ -198,10 +198,15 @@ static int enc_read(BIO *b, char *out, i + } + else + { +- EVP_CipherUpdate(&(ctx->cipher), ++ if (!EVP_CipherUpdate(&(ctx->cipher), + (unsigned char *)ctx->buf,&ctx->buf_len, +- (unsigned char *)&(ctx->buf[BUF_OFFSET]),i); +- ctx->cont=1; ++ (unsigned char *)&(ctx->buf[BUF_OFFSET]),i)) ++ { ++ ctx->ok = 0; ++ ctx->cont = 0; ++ } ++ else ++ ctx->cont=1; + /* Note: it is possible for EVP_CipherUpdate to + * decrypt zero bytes because this is or looks like + * the final block: if this happens we should retry +@@ -257,9 +262,14 @@ static int enc_write(BIO *b, const char + while (inl > 0) + { + n=(inl > ENC_BLOCK_SIZE)?ENC_BLOCK_SIZE:inl; +- EVP_CipherUpdate(&(ctx->cipher), ++ if (!EVP_CipherUpdate(&(ctx->cipher), + (unsigned char *)ctx->buf,&ctx->buf_len, +- (unsigned char *)in,n); ++ (unsigned char *)in,n)) ++ { ++ BIO_copy_next_retry(b); ++ ctx->ok = 0; ++ return ret - inl; ++ } + inl-=n; + in+=n; + diff --git a/SOURCES/openssl-1.0.1e-env-zlib.patch b/SOURCES/openssl-1.0.1e-env-zlib.patch new file mode 100755 index 00000000..b702acb2 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-env-zlib.patch @@ -0,0 +1,38 @@ +diff -up openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod.env-zlib openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod +--- openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod.env-zlib 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod 2013-02-19 16:32:51.000000000 +0100 +@@ -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.1e/ssl/ssl_ciph.c.env-zlib openssl-1.0.1e/ssl/ssl_ciph.c +--- openssl-1.0.1e/ssl/ssl_ciph.c.env-zlib 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/ssl_ciph.c 2013-02-19 16:37:36.163545085 +0100 +@@ -140,6 +140,8 @@ + * OTHERWISE. + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #ifndef OPENSSL_NO_COMP +@@ -455,7 +457,7 @@ 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) diff --git a/SOURCES/openssl-1.0.1e-ephemeral-key-size.patch b/SOURCES/openssl-1.0.1e-ephemeral-key-size.patch new file mode 100755 index 00000000..14f7940f --- /dev/null +++ b/SOURCES/openssl-1.0.1e-ephemeral-key-size.patch @@ -0,0 +1,135 @@ +diff -up openssl-1.0.1e/apps/s_apps.h.ephemeral openssl-1.0.1e/apps/s_apps.h +--- openssl-1.0.1e/apps/s_apps.h.ephemeral 2014-02-12 14:49:14.333513753 +0100 ++++ openssl-1.0.1e/apps/s_apps.h 2014-02-12 14:49:14.417515629 +0100 +@@ -156,6 +156,7 @@ int MS_CALLBACK verify_callback(int ok, + int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file); + int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); + #endif ++int ssl_print_tmp_key(BIO *out, SSL *s); + int init_client(int *sock, char *server, char *port, int type); + int should_retry(int i); + int extract_host_port(char *str,char **host_ptr,char **port_ptr); +diff -up openssl-1.0.1e/apps/s_cb.c.ephemeral openssl-1.0.1e/apps/s_cb.c +--- openssl-1.0.1e/apps/s_cb.c.ephemeral 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/s_cb.c 2014-02-12 14:56:25.584142499 +0100 +@@ -338,6 +338,38 @@ void MS_CALLBACK apps_ssl_info_callback( + } + } + ++int ssl_print_tmp_key(BIO *out, SSL *s) ++ { ++ EVP_PKEY *key; ++ if (!SSL_get_server_tmp_key(s, &key)) ++ return 1; ++ BIO_puts(out, "Server Temp Key: "); ++ switch (EVP_PKEY_id(key)) ++ { ++ case EVP_PKEY_RSA: ++ BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_bits(key)); ++ break; ++ ++ case EVP_PKEY_DH: ++ BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(key)); ++ break; ++ ++ case EVP_PKEY_EC: ++ { ++ EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); ++ int nid; ++ const char *cname; ++ nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); ++ EC_KEY_free(ec); ++ cname = OBJ_nid2sn(nid); ++ BIO_printf(out, "ECDH, %s, %d bits\n", ++ cname, EVP_PKEY_bits(key)); ++ } ++ } ++ EVP_PKEY_free(key); ++ return 1; ++ } ++ + + void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) + { +diff -up openssl-1.0.1e/apps/s_client.c.ephemeral openssl-1.0.1e/apps/s_client.c +--- openssl-1.0.1e/apps/s_client.c.ephemeral 2014-02-12 14:49:14.407515406 +0100 ++++ openssl-1.0.1e/apps/s_client.c 2014-02-12 14:49:14.418515652 +0100 +@@ -2032,6 +2032,8 @@ static void print_stuff(BIO *bio, SSL *s + BIO_write(bio,"\n",1); + } + ++ ssl_print_tmp_key(bio, s); ++ + BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n", + BIO_number_read(SSL_get_rbio(s)), + BIO_number_written(SSL_get_wbio(s))); +diff -up openssl-1.0.1e/ssl/ssl.h.ephemeral openssl-1.0.1e/ssl/ssl.h +--- openssl-1.0.1e/ssl/ssl.h.ephemeral 2014-02-12 14:49:14.391515049 +0100 ++++ openssl-1.0.1e/ssl/ssl.h 2014-02-12 14:49:14.418515652 +0100 +@@ -1563,6 +1563,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + #define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 + #define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 + ++#define SSL_CTRL_GET_SERVER_TMP_KEY 109 ++ + #define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) + #define DTLSv1_handle_timeout(ssl) \ +@@ -1604,6 +1606,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + #define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) + ++#define SSL_get_server_tmp_key(s, pk) \ ++ SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk) ++ + #ifndef OPENSSL_NO_BIO + BIO_METHOD *BIO_f_ssl(void); + BIO *BIO_new_ssl(SSL_CTX *ctx,int client); +diff -up openssl-1.0.1e/ssl/s3_lib.c.ephemeral openssl-1.0.1e/ssl/s3_lib.c +--- openssl-1.0.1e/ssl/s3_lib.c.ephemeral 2014-02-12 14:49:14.412515518 +0100 ++++ openssl-1.0.1e/ssl/s3_lib.c 2014-02-12 14:49:14.418515652 +0100 +@@ -3350,6 +3350,44 @@ long ssl3_ctrl(SSL *s, int cmd, long lar + #endif + + #endif /* !OPENSSL_NO_TLSEXT */ ++ case SSL_CTRL_GET_SERVER_TMP_KEY: ++ if (s->server || !s->session || !s->session->sess_cert) ++ return 0; ++ else ++ { ++ SESS_CERT *sc; ++ EVP_PKEY *ptmp; ++ int rv = 0; ++ sc = s->session->sess_cert; ++#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) ++ if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp ++ && !sc->peer_ecdh_tmp) ++ return 0; ++#endif ++ ptmp = EVP_PKEY_new(); ++ if (!ptmp) ++ return 0; ++ if (0); ++#ifndef OPENSSL_NO_RSA ++ else if (sc->peer_rsa_tmp) ++ rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp); ++#endif ++#ifndef OPENSSL_NO_DH ++ else if (sc->peer_dh_tmp) ++ rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp); ++#endif ++#ifndef OPENSSL_NO_ECDH ++ else if (sc->peer_ecdh_tmp) ++ rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp); ++#endif ++ if (rv) ++ { ++ *(EVP_PKEY **)parg = ptmp; ++ return 1; ++ } ++ EVP_PKEY_free(ptmp); ++ return 0; ++ } + default: + break; + } diff --git a/SOURCES/openssl-1.0.1e-evp-wrap.patch b/SOURCES/openssl-1.0.1e-evp-wrap.patch new file mode 100755 index 00000000..ecb43a43 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-evp-wrap.patch @@ -0,0 +1,1239 @@ +diff -up openssl-1.0.1e/crypto/aes/aes_wrap.c.wrap openssl-1.0.1e/crypto/aes/aes_wrap.c +--- openssl-1.0.1e/crypto/aes/aes_wrap.c.wrap 2013-02-11 16:02:47.000000000 +0100 ++++ openssl-1.0.1e/crypto/aes/aes_wrap.c 2014-09-09 16:12:25.852801573 +0200 +@@ -53,207 +53,18 @@ + + #include "cryptlib.h" + #include +-#include +- +-static const unsigned char default_iv[] = { +- 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, +-}; ++#include + + int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen) + { +- unsigned char *A, B[16], *R; +- unsigned int i, j, t; +- if ((inlen & 0x7) || (inlen < 8)) +- return -1; +- A = B; +- t = 1; +- memcpy(out + 8, in, inlen); +- if (!iv) +- iv = default_iv; +- +- memcpy(A, iv, 8); +- +- for (j = 0; j < 6; j++) +- { +- R = out + 8; +- for (i = 0; i < inlen; i += 8, t++, R += 8) +- { +- memcpy(B + 8, R, 8); +- AES_encrypt(B, B, key); +- A[7] ^= (unsigned char)(t & 0xff); +- if (t > 0xff) +- { +- A[6] ^= (unsigned char)((t >> 8) & 0xff); +- A[5] ^= (unsigned char)((t >> 16) & 0xff); +- A[4] ^= (unsigned char)((t >> 24) & 0xff); +- } +- memcpy(R, B + 8, 8); +- } +- } +- memcpy(out, A, 8); +- return inlen + 8; ++ return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f)AES_encrypt); + } + + int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen) + { +- unsigned char *A, B[16], *R; +- unsigned int i, j, t; +- inlen -= 8; +- if (inlen & 0x7) +- return -1; +- if (inlen < 8) +- return -1; +- A = B; +- t = 6 * (inlen >> 3); +- memcpy(A, in, 8); +- memcpy(out, in + 8, inlen); +- for (j = 0; j < 6; j++) +- { +- R = out + inlen - 8; +- for (i = 0; i < inlen; i += 8, t--, R -= 8) +- { +- A[7] ^= (unsigned char)(t & 0xff); +- if (t > 0xff) +- { +- A[6] ^= (unsigned char)((t >> 8) & 0xff); +- A[5] ^= (unsigned char)((t >> 16) & 0xff); +- A[4] ^= (unsigned char)((t >> 24) & 0xff); +- } +- memcpy(B + 8, R, 8); +- AES_decrypt(B, B, key); +- memcpy(R, B + 8, 8); +- } +- } +- if (!iv) +- iv = default_iv; +- if (memcmp(A, iv, 8)) +- { +- OPENSSL_cleanse(out, inlen); +- return 0; +- } +- return inlen; +- } +- +-#ifdef AES_WRAP_TEST +- +-int AES_wrap_unwrap_test(const unsigned char *kek, int keybits, +- const unsigned char *iv, +- const unsigned char *eout, +- const unsigned char *key, int keylen) +- { +- unsigned char *otmp = NULL, *ptmp = NULL; +- int r, ret = 0; +- AES_KEY wctx; +- otmp = OPENSSL_malloc(keylen + 8); +- ptmp = OPENSSL_malloc(keylen); +- if (!otmp || !ptmp) +- return 0; +- if (AES_set_encrypt_key(kek, keybits, &wctx)) +- goto err; +- r = AES_wrap_key(&wctx, iv, otmp, key, keylen); +- if (r <= 0) +- goto err; +- +- if (eout && memcmp(eout, otmp, keylen)) +- goto err; +- +- if (AES_set_decrypt_key(kek, keybits, &wctx)) +- goto err; +- r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r); +- +- if (memcmp(key, ptmp, keylen)) +- goto err; +- +- ret = 1; +- +- err: +- if (otmp) +- OPENSSL_free(otmp); +- if (ptmp) +- OPENSSL_free(ptmp); +- +- return ret; +- ++ return CRYPTO_128_unwrap(key, iv, out, in, inlen, (block128_f)AES_decrypt); + } +- +- +- +-int main(int argc, char **argv) +-{ +- +-static const unsigned char kek[] = { +- 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 +-}; +- +-static const unsigned char key[] = { +- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, +- 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, +- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +-}; +- +-static const unsigned char e1[] = { +- 0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47, +- 0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82, +- 0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5 +-}; +- +-static const unsigned char e2[] = { +- 0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35, +- 0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2, +- 0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d +-}; +- +-static const unsigned char e3[] = { +- 0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2, +- 0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a, +- 0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7 +-}; +- +-static const unsigned char e4[] = { +- 0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32, +- 0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc, +- 0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93, +- 0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2 +-}; +- +-static const unsigned char e5[] = { +- 0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f, +- 0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4, +- 0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95, +- 0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1 +-}; +- +-static const unsigned char e6[] = { +- 0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4, +- 0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26, +- 0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26, +- 0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b, +- 0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21 +-}; +- +- AES_KEY wctx, xctx; +- int ret; +- ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16); +- fprintf(stderr, "Key test result %d\n", ret); +- ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16); +- fprintf(stderr, "Key test result %d\n", ret); +- ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16); +- fprintf(stderr, "Key test result %d\n", ret); +- ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24); +- fprintf(stderr, "Key test result %d\n", ret); +- ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24); +- fprintf(stderr, "Key test result %d\n", ret); +- ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32); +- fprintf(stderr, "Key test result %d\n", ret); +-} +- +- +-#endif +diff -up openssl-1.0.1e/crypto/evp/c_allc.c.wrap openssl-1.0.1e/crypto/evp/c_allc.c +--- openssl-1.0.1e/crypto/evp/c_allc.c.wrap 2014-09-09 16:11:24.103379348 +0200 ++++ openssl-1.0.1e/crypto/evp/c_allc.c 2014-09-09 16:12:25.853801601 +0200 +@@ -98,6 +98,7 @@ void OpenSSL_add_all_ciphers(void) + EVP_add_cipher(EVP_des_ecb()); + EVP_add_cipher(EVP_des_ede()); + EVP_add_cipher(EVP_des_ede3()); ++ EVP_add_cipher(EVP_des_ede3_wrap()); + #endif + + #ifndef OPENSSL_NO_RC4 +@@ -177,6 +178,8 @@ void OpenSSL_add_all_ciphers(void) + 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_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()); +@@ -187,6 +190,8 @@ void OpenSSL_add_all_ciphers(void) + 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_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()); +@@ -198,6 +203,8 @@ void OpenSSL_add_all_ciphers(void) + 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_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) +@@ -250,6 +257,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 +@@ -262,6 +270,8 @@ void OpenSSL_add_all_ciphers(void) + 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_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()); +@@ -272,6 +282,8 @@ void OpenSSL_add_all_ciphers(void) + 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_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()); +@@ -283,6 +295,8 @@ void OpenSSL_add_all_ciphers(void) + 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_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.1e/crypto/evp/e_aes.c.wrap openssl-1.0.1e/crypto/evp/e_aes.c +--- openssl-1.0.1e/crypto/evp/e_aes.c.wrap 2014-09-09 16:11:24.103379348 +0200 ++++ openssl-1.0.1e/crypto/evp/e_aes.c 2014-09-09 16:12:25.853801601 +0200 +@@ -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 +@@ -1323,4 +1323,180 @@ BLOCK_CIPHER_custom(NID_aes,128,1,12,ccm + BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) + ++typedef struct ++ { ++ union { double align; AES_KEY ks; } ks; ++ /* Indicates if IV has been set */ ++ unsigned char *iv; ++ } EVP_AES_WRAP_CTX; ++ ++static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, ++ const unsigned char *iv, int enc) ++ { ++ EVP_AES_WRAP_CTX *wctx = ctx->cipher_data; ++ if (!iv && !key) ++ return 1; ++ if (key) ++ { ++ if (ctx->encrypt) ++ AES_set_encrypt_key(key, ctx->key_len * 8, &wctx->ks.ks); ++ else ++ AES_set_decrypt_key(key, ctx->key_len * 8, &wctx->ks.ks); ++ if (!iv) ++ wctx->iv = NULL; ++ } ++ if (iv) ++ { ++ memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); ++ wctx->iv = ctx->iv; ++ } ++ return 1; ++ } ++ ++static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inlen) ++ { ++ 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; ++ /* Input length must always be non-zero */ ++ if (!inlen) ++ return -1; ++ /* If decrypting need at least 16 bytes and multiple of 8 */ ++ if (!ctx->encrypt && (inlen < 16 || inlen & 0x7)) ++ return -1; ++ /* If not padding input must be multiple of 8 */ ++ if (!pad && inlen & 0x7) ++ return -1; ++ if (!out) ++ { ++ 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 ++ { ++ /* 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_pad(&wctx->ks.ks, wctx->iv, ++ out, in, inlen, ++ (block128_f)AES_encrypt); ++ else ++ 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 | EVP_CIPH_FLAG_FIPS \ ++ | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ ++ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1) ++ ++static const EVP_CIPHER aes_128_wrap = { ++ NID_id_aes128_wrap, ++ 8, 16, 8, 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(void) ++ { ++ return &aes_128_wrap; ++ } ++ ++static const EVP_CIPHER aes_192_wrap = { ++ NID_id_aes192_wrap, ++ 8, 24, 8, 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(void) ++ { ++ return &aes_192_wrap; ++ } ++ ++static const EVP_CIPHER aes_256_wrap = { ++ NID_id_aes256_wrap, ++ 8, 32, 8, 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(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; ++ } ++ + #endif +diff -up openssl-1.0.1e/crypto/evp/e_des3.c.wrap openssl-1.0.1e/crypto/evp/e_des3.c +--- openssl-1.0.1e/crypto/evp/e_des3.c.wrap 2014-09-09 16:11:24.104379372 +0200 ++++ openssl-1.0.1e/crypto/evp/e_des3.c 2014-09-09 16:12:25.854801627 +0200 +@@ -310,4 +310,112 @@ const EVP_CIPHER *EVP_des_ede3(void) + { + return &des_ede3_ecb; + } ++ ++#ifndef OPENSSL_NO_SHA ++ ++#include ++ ++static const unsigned char wrap_iv[8] = {0x4a,0xdd,0xa2,0x2c,0x79,0xe8,0x21,0x05}; ++ ++static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl) ++ { ++ unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH]; ++ int rv = -1; ++ if (inl < 24) ++ return -1; ++ if (!out) ++ return inl - 16; ++ memcpy(ctx->iv, wrap_iv, 8); ++ /* Decrypt first block which will end up as icv */ ++ des_ede_cbc_cipher(ctx, icv, in, 8); ++ /* Decrypt central blocks */ ++ /* If decrypting in place move whole output along a block ++ * so the next des_ede_cbc_cipher is in place. ++ */ ++ if (out == in) ++ { ++ memmove(out, out + 8, inl - 8); ++ in -= 8; ++ } ++ des_ede_cbc_cipher(ctx, out, in + 8, inl - 16); ++ /* Decrypt final block which will be IV */ ++ des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8); ++ /* Reverse order of everything */ ++ BUF_reverse(icv, NULL, 8); ++ BUF_reverse(out, NULL, inl - 16); ++ BUF_reverse(ctx->iv, iv, 8); ++ /* Decrypt again using new IV */ ++ des_ede_cbc_cipher(ctx, out, out, inl - 16); ++ des_ede_cbc_cipher(ctx, icv, icv, 8); ++ /* Work out SHA1 hash of first portion */ ++ SHA1(out, inl - 16, sha1tmp); ++ ++ if (!CRYPTO_memcmp(sha1tmp, icv, 8)) ++ rv = inl - 16; ++ OPENSSL_cleanse(icv, 8); ++ OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); ++ OPENSSL_cleanse(iv, 8); ++ OPENSSL_cleanse(ctx->iv, 8); ++ if (rv == -1) ++ OPENSSL_cleanse(out, inl - 16); ++ ++ return rv; ++ } ++ ++static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl) ++ { ++ unsigned char sha1tmp[SHA_DIGEST_LENGTH]; ++ if (!out) ++ return inl + 16; ++ /* Copy input to output buffer + 8 so we have space for IV */ ++ memmove(out + 8, in, inl); ++ /* Work out ICV */ ++ SHA1(in, inl, sha1tmp); ++ memcpy(out + inl + 8, sha1tmp, 8); ++ OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); ++ /* Generate random IV */ ++ RAND_bytes(ctx->iv, 8); ++ memcpy(out, ctx->iv, 8); ++ /* Encrypt everything after IV in place */ ++ des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8); ++ BUF_reverse(out, NULL, inl + 16); ++ memcpy(ctx->iv, wrap_iv, 8); ++ des_ede_cbc_cipher(ctx, out, out, inl + 16); ++ return inl + 16; ++ } ++ ++static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ++ const unsigned char *in, size_t inl) ++ { ++ /* Sanity check input length: we typically only wrap keys ++ * so EVP_MAXCHUNK is more than will ever be needed. Also ++ * input length must be a multiple of 8 bits. ++ */ ++ if (inl >= EVP_MAXCHUNK || inl % 8) ++ return -1; ++ if (ctx->encrypt) ++ return des_ede3_wrap(ctx, out, in, inl); ++ else ++ return des_ede3_unwrap(ctx, out, in, inl); ++ } ++ ++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_FIPS, ++ des_ede3_init_key, des_ede3_wrap_cipher, ++ NULL, ++ sizeof(DES_EDE_KEY), ++ NULL,NULL,NULL,NULL }; ++ ++ ++const EVP_CIPHER *EVP_des_ede3_wrap(void) ++ { ++ return &des3_wrap; ++ } ++ ++# endif + #endif +diff -up openssl-1.0.1e/crypto/evp/evp_enc.c.wrap openssl-1.0.1e/crypto/evp/evp_enc.c +--- openssl-1.0.1e/crypto/evp/evp_enc.c.wrap 2014-09-09 16:11:24.104379372 +0200 ++++ openssl-1.0.1e/crypto/evp/evp_enc.c 2014-09-09 16:12:25.854801627 +0200 +@@ -233,7 +233,8 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct + ctx->cipher_data = NULL; + } + ctx->key_len = cipher->key_len; +- ctx->flags = 0; ++ /* Preserve wrap enable flag, zero everything else */ ++ ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; + if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) + { + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) +@@ -256,6 +257,13 @@ skip_to_init: + || ctx->cipher->block_size == 8 + || ctx->cipher->block_size == 16); + ++ if(!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) ++ && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) ++ { ++ EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED); ++ return 0; ++ } ++ + if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { + switch(EVP_CIPHER_CTX_mode(ctx)) { + +diff -up openssl-1.0.1e/crypto/evp/evp_err.c.wrap openssl-1.0.1e/crypto/evp/evp_err.c +--- openssl-1.0.1e/crypto/evp/evp_err.c.wrap 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/evp_err.c 2014-09-09 16:12:25.854801627 +0200 +@@ -1,6 +1,6 @@ + /* crypto/evp/evp_err.c */ + /* ==================================================================== +- * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 1999-2013 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 +@@ -220,6 +220,7 @@ static ERR_STRING_DATA EVP_str_reasons[] + {ERR_REASON(EVP_R_UNSUPPORTED_PRF) ,"unsupported prf"}, + {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),"unsupported private key algorithm"}, + {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE) ,"unsupported salt type"}, ++{ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED) ,"wrap mode not allowed"}, + {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH),"wrong final block length"}, + {ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE) ,"wrong public key type"}, + {0,NULL} +diff -up openssl-1.0.1e/crypto/evp/evp.h.wrap openssl-1.0.1e/crypto/evp/evp.h +--- openssl-1.0.1e/crypto/evp/evp.h.wrap 2014-09-09 16:11:24.104379372 +0200 ++++ openssl-1.0.1e/crypto/evp/evp.h 2014-09-09 16:12:25.855801651 +0200 +@@ -336,6 +336,7 @@ struct evp_cipher_st + #define EVP_CIPH_GCM_MODE 0x6 + #define EVP_CIPH_CCM_MODE 0x7 + #define EVP_CIPH_XTS_MODE 0x10001 ++#define EVP_CIPH_WRAP_MODE 0x10002 + #define EVP_CIPH_MODE 0xF0007 + /* Set if variable length cipher */ + #define EVP_CIPH_VARIABLE_LENGTH 0x8 +@@ -367,6 +368,13 @@ struct evp_cipher_st + #define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 + #define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 + ++/* Cipher context flag to indicate we can handle ++ * wrap mode: if allowed in older applications it could ++ * overflow buffers. ++ */ ++ ++#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 ++ + /* ctrl() values */ + + #define EVP_CTRL_INIT 0x0 +@@ -729,6 +737,7 @@ const EVP_CIPHER *EVP_des_cbc(void); + const EVP_CIPHER *EVP_des_ede_cbc(void); + const EVP_CIPHER *EVP_des_ede3_cbc(void); + const EVP_CIPHER *EVP_desx_cbc(void); ++const EVP_CIPHER *EVP_des_ede3_wrap(void); + /* This should now be supported through the dev_crypto ENGINE. But also, why are + * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */ + #if 0 +@@ -788,6 +797,8 @@ const EVP_CIPHER *EVP_aes_128_ctr(void); + 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); +@@ -798,6 +809,8 @@ const EVP_CIPHER *EVP_aes_192_ofb(void); + 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); +@@ -809,6 +822,8 @@ const EVP_CIPHER *EVP_aes_256_ctr(void); + 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); +@@ -1397,6 +1412,7 @@ void ERR_load_EVP_strings(void); + #define EVP_R_UNSUPPORTED_PRF 125 + #define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 + #define EVP_R_UNSUPPORTED_SALT_TYPE 126 ++#define EVP_R_WRAP_MODE_NOT_ALLOWED 170 + #define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 + #define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 + +diff -up openssl-1.0.1e/crypto/evp/evp_lib.c.wrap openssl-1.0.1e/crypto/evp/evp_lib.c +--- openssl-1.0.1e/crypto/evp/evp_lib.c.wrap 2014-09-09 16:11:24.104379372 +0200 ++++ openssl-1.0.1e/crypto/evp/evp_lib.c 2014-09-09 16:12:25.855801651 +0200 +@@ -68,7 +68,15 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_ + if (c->cipher->set_asn1_parameters != NULL) + ret=c->cipher->set_asn1_parameters(c,type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) +- ret=EVP_CIPHER_set_asn1_iv(c, type); ++ { ++ if (EVP_CIPHER_CTX_mode(c) == EVP_CIPH_WRAP_MODE) ++ { ++ ASN1_TYPE_set(type, V_ASN1_NULL, NULL); ++ ret = 1; ++ } ++ else ++ ret=EVP_CIPHER_set_asn1_iv(c, type); ++ } + else + ret=-1; + return(ret); +@@ -81,7 +89,11 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_ + if (c->cipher->get_asn1_parameters != NULL) + ret=c->cipher->get_asn1_parameters(c,type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) ++ { ++ if (EVP_CIPHER_CTX_mode(c) == EVP_CIPH_WRAP_MODE) ++ return 1; + ret=EVP_CIPHER_get_asn1_iv(c, type); ++ } + else + ret=-1; + return(ret); +diff -up openssl-1.0.1e/crypto/evp/evp_test.c.wrap openssl-1.0.1e/crypto/evp/evp_test.c +--- openssl-1.0.1e/crypto/evp/evp_test.c.wrap 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/evp_test.c 2014-09-09 16:12:25.856801673 +0200 +@@ -141,7 +141,7 @@ static void test1(const EVP_CIPHER *c,co + { + EVP_CIPHER_CTX ctx; + unsigned char out[4096]; +- int outl,outl2; ++ int outl,outl2,mode; + + printf("Testing cipher %s%s\n",EVP_CIPHER_name(c), + (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); +@@ -151,6 +151,7 @@ static void test1(const EVP_CIPHER *c,co + hexdump(stdout,"Plaintext",plaintext,pn); + hexdump(stdout,"Ciphertext",ciphertext,cn); + ++ mode = EVP_CIPHER_mode(c); + if(kn != c->key_len) + { + fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn, +@@ -158,9 +159,19 @@ static void test1(const EVP_CIPHER *c,co + test1_exit(5); + } + EVP_CIPHER_CTX_init(&ctx); ++ EVP_CIPHER_CTX_set_flags(&ctx,EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + if (encdec != 0) + { +- if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv)) ++ if (mode == EVP_CIPH_WRAP_MODE) ++ { ++ if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,in ? iv : NULL)) ++ { ++ fprintf(stderr,"EncryptInit failed\n"); ++ ERR_print_errors_fp(stderr); ++ test1_exit(10); ++ } ++ } ++ else if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv)) + { + fprintf(stderr,"EncryptInit failed\n"); + ERR_print_errors_fp(stderr); +@@ -199,7 +210,16 @@ static void test1(const EVP_CIPHER *c,co + + if (encdec <= 0) + { +- if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv)) ++ if (mode == EVP_CIPH_WRAP_MODE) ++ { ++ if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,in ? iv : NULL)) ++ { ++ fprintf(stderr,"EncryptInit failed\n"); ++ ERR_print_errors_fp(stderr); ++ test1_exit(10); ++ } ++ } ++ else if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv)) + { + fprintf(stderr,"DecryptInit failed\n"); + ERR_print_errors_fp(stderr); +@@ -339,7 +359,7 @@ int main(int argc,char **argv) + perror(szTestFile); + EXIT(2); + } +- ++ ERR_load_crypto_strings(); + /* Load up the software EVP_CIPHER and EVP_MD definitions */ + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +diff -up openssl-1.0.1e/crypto/evp/evptests.txt.wrap openssl-1.0.1e/crypto/evp/evptests.txt +--- openssl-1.0.1e/crypto/evp/evptests.txt.wrap 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/evptests.txt 2014-09-09 16:12:25.856801673 +0200 +@@ -332,3 +332,15 @@ SEED-ECB:0000000000000000000000000000000 + SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1 + SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1 + SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1 ++ ++# AES wrap tests from RFC3394 ++id-aes128-wrap:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5 ++id-aes192-wrap:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D ++id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7 ++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.1e/crypto/modes/Makefile.wrap openssl-1.0.1e/crypto/modes/Makefile +--- openssl-1.0.1e/crypto/modes/Makefile.wrap 2014-09-09 16:11:24.079378796 +0200 ++++ openssl-1.0.1e/crypto/modes/Makefile 2014-09-09 16:12:25.856801673 +0200 +@@ -22,9 +22,9 @@ APPS= + + LIB=$(TOP)/libcrypto.a + LIBSRC= cbc128.c ctr128.c cts128.c cfb128.c ofb128.c gcm128.c \ +- ccm128.c xts128.c ++ ccm128.c xts128.c wrap128.c + LIBOBJ= cbc128.o ctr128.o cts128.o cfb128.o ofb128.o gcm128.o \ +- ccm128.o xts128.o $(MODES_ASM_OBJ) ++ ccm128.o xts128.o wrap128.o $(MODES_ASM_OBJ) + + SRC= $(LIBSRC) + +diff -up openssl-1.0.1e/crypto/modes/modes.h.wrap openssl-1.0.1e/crypto/modes/modes.h +--- openssl-1.0.1e/crypto/modes/modes.h.wrap 2014-09-09 16:11:23.726370665 +0200 ++++ openssl-1.0.1e/crypto/modes/modes.h 2014-09-09 16:12:25.857801695 +0200 +@@ -133,3 +133,17 @@ typedef struct xts128_context XTS128_CON + + int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, size_t len, int enc); ++ ++size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, ++ unsigned char *out, ++ const unsigned char *in, size_t inlen, block128_f block); ++ ++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 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); +diff -up openssl-1.0.1e/crypto/modes/wrap128.c.wrap openssl-1.0.1e/crypto/modes/wrap128.c +--- openssl-1.0.1e/crypto/modes/wrap128.c.wrap 2014-09-09 16:12:25.857801695 +0200 ++++ openssl-1.0.1e/crypto/modes/wrap128.c 2014-09-09 16:12:25.857801695 +0200 +@@ -0,0 +1,372 @@ ++/* crypto/modes/wrap128.c */ ++/* 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. ++ * ++ * 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. ++ * ==================================================================== ++ */ ++ ++/** 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, ++}; ++ ++/** 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, block128_f block) ++ { ++ unsigned char *A, B[16], *R; ++ size_t i, j, t; ++ if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) ++ return 0; ++ A = B; ++ t = 1; ++ memmove(out + 8, in, inlen); ++ if (!iv) ++ iv = default_iv; ++ ++ memcpy(A, iv, 8); ++ ++ for (j = 0; j < 6; j++) ++ { ++ R = out + 8; ++ for (i = 0; i < inlen; i += 8, t++, R += 8) ++ { ++ memcpy(B + 8, R, 8); ++ block(B, B, key); ++ A[7] ^= (unsigned char)(t & 0xff); ++ if (t > 0xff) ++ { ++ A[6] ^= (unsigned char)((t >> 8) & 0xff); ++ A[5] ^= (unsigned char)((t >> 16) & 0xff); ++ A[4] ^= (unsigned char)((t >> 24) & 0xff); ++ } ++ memcpy(R, B + 8, 8); ++ } ++ } ++ memcpy(out, A, 8); ++ return inlen + 8; ++ } ++ ++ ++/** 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) ++ { ++ unsigned char *A, B[16], *R; ++ size_t i, j, t; ++ inlen -= 8; ++ if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) ++ return 0; ++ A = B; ++ t = 6 * (inlen >> 3); ++ memcpy(A, in, 8); ++ memmove(out, in + 8, inlen); ++ for (j = 0; j < 6; j++) ++ { ++ R = out + inlen - 8; ++ for (i = 0; i < inlen; i += 8, t--, R -= 8) ++ { ++ A[7] ^= (unsigned char)(t & 0xff); ++ if (t > 0xff) ++ { ++ A[6] ^= (unsigned char)((t >> 8) & 0xff); ++ A[5] ^= (unsigned char)((t >> 16) & 0xff); ++ A[4] ^= (unsigned char)((t >> 24) & 0xff); ++ } ++ memcpy(B + 8, R, 8); ++ block(B, B, key); ++ 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 (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; ++ } ++ } ++ ++ /* 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.1e-fallback-scsv.patch b/SOURCES/openssl-1.0.1e-fallback-scsv.patch new file mode 100755 index 00000000..0c307c32 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-fallback-scsv.patch @@ -0,0 +1,466 @@ +diff -up openssl-1.0.1e/apps/s_client.c.fallback-scsv openssl-1.0.1e/apps/s_client.c +--- openssl-1.0.1e/apps/s_client.c.fallback-scsv 2014-10-15 17:06:01.000000000 +0200 ++++ openssl-1.0.1e/apps/s_client.c 2014-10-15 17:07:36.392502320 +0200 +@@ -336,6 +336,7 @@ static void sc_usage(void) + BIO_printf(bio_err," -tls1_1 - just use TLSv1.1\n"); + BIO_printf(bio_err," -tls1 - just use TLSv1\n"); + BIO_printf(bio_err," -dtls1 - just use DTLSv1\n"); ++ BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n"); + BIO_printf(bio_err," -mtu - set the link layer MTU\n"); + BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n"); + BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n"); +@@ -616,6 +617,7 @@ int MAIN(int argc, char **argv) + char *sess_out = NULL; + struct sockaddr peer; + int peerlen = sizeof(peer); ++ int fallback_scsv = 0; + int enable_timeouts = 0 ; + long socket_mtu = 0; + #ifndef OPENSSL_NO_JPAKE +@@ -829,6 +831,10 @@ int MAIN(int argc, char **argv) + socket_mtu = atol(*(++argv)); + } + #endif ++ else if (strcmp(*argv,"-fallback_scsv") == 0) ++ { ++ fallback_scsv = 1; ++ } + else if (strcmp(*argv,"-bugs") == 0) + bugs=1; + else if (strcmp(*argv,"-keyform") == 0) +@@ -1240,6 +1246,10 @@ bad: + SSL_set_session(con, sess); + SSL_SESSION_free(sess); + } ++ ++ if (fallback_scsv) ++ SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV); ++ + #ifndef OPENSSL_NO_TLSEXT + if (servername != NULL) + { +diff -up openssl-1.0.1e/doc/apps/s_client.pod.fallback-scsv openssl-1.0.1e/doc/apps/s_client.pod +--- openssl-1.0.1e/doc/apps/s_client.pod.fallback-scsv 2014-10-15 17:06:01.000000000 +0200 ++++ openssl-1.0.1e/doc/apps/s_client.pod 2014-10-15 17:08:17.354427053 +0200 +@@ -41,6 +41,7 @@ B B + [B<-no_tls1>] + [B<-no_tls1_1>] + [B<-no_tls1_2>] ++[B<-fallback_scsv>] + [B<-bugs>] + [B<-cipher cipherlist>] + [B<-starttls protocol>] +@@ -200,6 +201,10 @@ cannot handle this technique and will fa + work if TLS is turned off with the B<-no_tls> option others will only + support SSL v2 and may need the B<-ssl2> option. + ++=item B<-fallback_scsv> ++ ++Send TLS_FALLBACK_SCSV in the ClientHello. ++ + =item B<-bugs> + + there are several known bug in SSL and TLS implementations. Adding this +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_mode.pod.fallback-scsv openssl-1.0.1e/doc/ssl/SSL_CTX_set_mode.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_mode.pod.fallback-scsv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_mode.pod 2014-10-15 17:09:57.577689637 +0200 +@@ -71,6 +71,12 @@ SSL_CTX->freelist_max_len, which default + save around 34k per idle SSL connection. + This flag has no effect on SSL v2 connections, or on DTLS connections. + ++=item SSL_MODE_SEND_FALLBACK_SCSV ++ ++Send TLS_FALLBACK_SCSV in the ClientHello. ++To be set by applications that reconnect with a downgraded protocol ++version; see draft-ietf-tls-downgrade-scsv-00 for details. ++ + =back + + =head1 RETURN VALUES +diff -up openssl-1.0.1e/ssl/dtls1.h.fallback-scsv openssl-1.0.1e/ssl/dtls1.h +--- openssl-1.0.1e/ssl/dtls1.h.fallback-scsv 2014-10-15 14:45:25.492913542 +0200 ++++ openssl-1.0.1e/ssl/dtls1.h 2014-10-15 14:45:25.596915890 +0200 +@@ -84,6 +84,8 @@ extern "C" { + #endif + + #define DTLS1_VERSION 0xFEFF ++#define DTLS_MAX_VERSION DTLS1_VERSION ++ + #define DTLS1_BAD_VER 0x0100 + + #if 0 +@@ -284,4 +286,3 @@ typedef struct dtls1_record_data_st + } + #endif + #endif +- +diff -up openssl-1.0.1e/ssl/d1_lib.c.fallback-scsv openssl-1.0.1e/ssl/d1_lib.c +--- openssl-1.0.1e/ssl/d1_lib.c.fallback-scsv 2014-10-15 14:45:25.539914603 +0200 ++++ openssl-1.0.1e/ssl/d1_lib.c 2014-10-15 14:45:25.596915890 +0200 +@@ -263,6 +263,16 @@ long dtls1_ctrl(SSL *s, int cmd, long la + case DTLS_CTRL_LISTEN: + ret = dtls1_listen(s, parg); + break; ++ case SSL_CTRL_CHECK_PROTO_VERSION: ++ /* For library-internal use; checks that the current protocol ++ * is the highest enabled version (according to s->ctx->method, ++ * as version negotiation may have changed s->method). */ ++#if DTLS_MAX_VERSION != DTLS1_VERSION ++# error Code needs update for DTLS_method() support beyond DTLS1_VERSION. ++#endif ++ /* Just one protocol version is supported so far; ++ * fail closed if the version is not as expected. */ ++ return s->version == DTLS_MAX_VERSION; + + default: + ret = ssl3_ctrl(s, cmd, larg, parg); +diff -up openssl-1.0.1e/ssl/ssl_err.c.fallback-scsv openssl-1.0.1e/ssl/ssl_err.c +--- openssl-1.0.1e/ssl/ssl_err.c.fallback-scsv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/ssl_err.c 2014-10-15 14:45:25.596915890 +0200 +@@ -382,6 +382,7 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"}, + {ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"}, + {ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"}, ++{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK),"inappropriate fallback"}, + {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"}, + {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"}, + {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, +@@ -528,6 +529,7 @@ static ERR_STRING_DATA SSL_str_reasons[] + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"}, ++{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),"tlsv1 alert inappropriate fallback"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"}, +diff -up openssl-1.0.1e/ssl/ssl.h.fallback-scsv openssl-1.0.1e/ssl/ssl.h +--- openssl-1.0.1e/ssl/ssl.h.fallback-scsv 2014-10-15 14:45:25.588915709 +0200 ++++ openssl-1.0.1e/ssl/ssl.h 2014-10-15 14:47:04.423146935 +0200 +@@ -638,6 +638,10 @@ struct ssl_session_st + * TLS only.) "Released" buffers are put onto a free-list in the context + * or just freed (depending on the context's setting for freelist_max_len). */ + #define SSL_MODE_RELEASE_BUFFERS 0x00000010L ++/* Send TLS_FALLBACK_SCSV in the ClientHello. ++ * To be set by applications that reconnect with a downgraded protocol ++ * version; see draft-ietf-tls-downgrade-scsv-00 for details. */ ++#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L + + /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, + * they cannot be used to clear bits. */ +@@ -1453,6 +1457,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE + #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE + #define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ ++#define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */ + + #define SSL_ERROR_NONE 0 + #define SSL_ERROR_SSL 1 +@@ -1566,6 +1571,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + #define SSL_CTRL_SET_ECDH_AUTO 94 + #define SSL_CTRL_GET_SERVER_TMP_KEY 109 + ++#define SSL_CTRL_CHECK_PROTO_VERSION 119 ++ + #define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) + #define DTLSv1_handle_timeout(ssl) \ +@@ -2304,6 +2311,7 @@ void ERR_load_SSL_strings(void); + #define SSL_R_HTTPS_PROXY_REQUEST 155 + #define SSL_R_HTTP_REQUEST 156 + #define SSL_R_ILLEGAL_PADDING 283 ++#define SSL_R_INAPPROPRIATE_FALLBACK 373 + #define SSL_R_INCONSISTENT_COMPRESSION 340 + #define SSL_R_INVALID_CHALLENGE_LENGTH 158 + #define SSL_R_INVALID_COMMAND 280 +@@ -2450,6 +2458,7 @@ void ERR_load_SSL_strings(void); + #define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 + #define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 + #define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 ++#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 + #define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 + #define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 + #define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +diff -up openssl-1.0.1e/ssl/ssl_lib.c.fallback-scsv openssl-1.0.1e/ssl/ssl_lib.c +--- openssl-1.0.1e/ssl/ssl_lib.c.fallback-scsv 2014-10-15 14:45:25.589915731 +0200 ++++ openssl-1.0.1e/ssl/ssl_lib.c 2014-10-15 14:45:25.597915912 +0200 +@@ -1383,6 +1383,8 @@ int ssl_cipher_list_to_bytes(SSL *s,STAC + + if (sk == NULL) return(0); + q=p; ++ if (put_cb == NULL) ++ put_cb = s->method->put_cipher_by_char; + + for (i=0; ipsk_client_callback == NULL) + continue; + #endif /* OPENSSL_NO_PSK */ +- j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p); ++ j = put_cb(c,p); + p+=j; + } +- /* If p == q, no ciphers and caller indicates an error. Otherwise +- * add SCSV if not renegotiating. +- */ +- if (p != q && !s->renegotiate) ++ /* If p == q, no ciphers; caller indicates an error. ++ * Otherwise, add applicable SCSVs. */ ++ if (p != q) + { +- static SSL_CIPHER scsv = ++ if (!s->renegotiate) + { +- 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 +- }; +- j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p); +- p+=j; ++ static SSL_CIPHER scsv = ++ { ++ 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++ }; ++ j = put_cb(&scsv,p); ++ p+=j; + #ifdef OPENSSL_RI_DEBUG +- fprintf(stderr, "SCSV sent by client\n"); ++ fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); + #endif +- } ++ } ++ ++ if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) ++ { ++ static SSL_CIPHER scsv = ++ { ++ 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++ }; ++ j = put_cb(&scsv,p); ++ p+=j; ++ } ++ } + + return(p-q); + } +@@ -1430,11 +1444,12 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe + const SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + int i,n; ++ + if (s->s3) + s->s3->send_connection_binding = 0; + + n=ssl_put_cipher_by_char(s,NULL,NULL); +- if ((num%n) != 0) ++ if (n == 0 || (num%n) != 0) + { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return(NULL); +@@ -1449,7 +1464,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe + + for (i=0; is3 && (n != 3 || !p[0]) && + (p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && + (p[n-1] == (SSL3_CK_SCSV & 0xff))) +@@ -1469,6 +1484,23 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe + continue; + } + ++ /* Check for TLS_FALLBACK_SCSV */ ++ if ((n != 3 || !p[0]) && ++ (p[n-2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && ++ (p[n-1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) ++ { ++ /* The SCSV indicates that the client previously tried a higher version. ++ * Fail if the current version is an unexpected downgrade. */ ++ if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) ++ { ++ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_INAPPROPRIATE_FALLBACK); ++ if (s->s3) ++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK); ++ goto err; ++ } ++ continue; ++ } ++ + c=ssl_get_cipher_by_char(s,p); + p+=n; + if (c != NULL) +diff -up openssl-1.0.1e/ssl/ssl3.h.fallback-scsv openssl-1.0.1e/ssl/ssl3.h +--- openssl-1.0.1e/ssl/ssl3.h.fallback-scsv 2014-10-15 14:45:25.570915303 +0200 ++++ openssl-1.0.1e/ssl/ssl3.h 2014-10-15 14:45:25.598915935 +0200 +@@ -128,9 +128,14 @@ + extern "C" { + #endif + +-/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */ ++/* Signalling cipher suite value from RFC 5746 ++ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */ + #define SSL3_CK_SCSV 0x030000FF + ++/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 ++ * (TLS_FALLBACK_SCSV) */ ++#define SSL3_CK_FALLBACK_SCSV 0x03005600 ++ + #define SSL3_CK_RSA_NULL_MD5 0x03000001 + #define SSL3_CK_RSA_NULL_SHA 0x03000002 + #define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +diff -up openssl-1.0.1e/ssl/s2_lib.c.fallback-scsv openssl-1.0.1e/ssl/s2_lib.c +--- openssl-1.0.1e/ssl/s2_lib.c.fallback-scsv 2014-10-15 14:45:25.526914309 +0200 ++++ openssl-1.0.1e/ssl/s2_lib.c 2014-10-15 14:45:25.598915935 +0200 +@@ -391,6 +391,8 @@ long ssl2_ctrl(SSL *s, int cmd, long lar + case SSL_CTRL_GET_SESSION_REUSED: + ret=s->hit; + break; ++ case SSL_CTRL_CHECK_PROTO_VERSION: ++ return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg); + default: + break; + } +@@ -437,7 +439,7 @@ int ssl2_put_cipher_by_char(const SSL_CI + if (p != NULL) + { + l=c->id; +- if ((l & 0xff000000) != 0x02000000) return(0); ++ if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0); + p[0]=((unsigned char)(l>>16L))&0xFF; + p[1]=((unsigned char)(l>> 8L))&0xFF; + p[2]=((unsigned char)(l ))&0xFF; +diff -up openssl-1.0.1e/ssl/s23_clnt.c.fallback-scsv openssl-1.0.1e/ssl/s23_clnt.c +--- openssl-1.0.1e/ssl/s23_clnt.c.fallback-scsv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/s23_clnt.c 2014-10-15 14:45:25.598915935 +0200 +@@ -715,6 +715,9 @@ static int ssl23_get_server_hello(SSL *s + goto err; + } + ++ /* ensure that TLS_MAX_VERSION is up-to-date */ ++ OPENSSL_assert(s->version <= TLS_MAX_VERSION); ++ + if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) + { + /* fatal alert */ +diff -up openssl-1.0.1e/ssl/s23_srvr.c.fallback-scsv openssl-1.0.1e/ssl/s23_srvr.c +--- openssl-1.0.1e/ssl/s23_srvr.c.fallback-scsv 2014-10-15 14:45:25.584915619 +0200 ++++ openssl-1.0.1e/ssl/s23_srvr.c 2014-10-15 14:45:25.598915935 +0200 +@@ -421,6 +421,9 @@ int ssl23_get_client_hello(SSL *s) + } + } + ++ /* ensure that TLS_MAX_VERSION is up-to-date */ ++ OPENSSL_assert(s->version <= TLS_MAX_VERSION); ++ + #ifdef OPENSSL_FIPS + if (FIPS_mode() && (s->version < TLS1_VERSION)) + { +diff -up openssl-1.0.1e/ssl/s3_enc.c.fallback-scsv openssl-1.0.1e/ssl/s3_enc.c +--- openssl-1.0.1e/ssl/s3_enc.c.fallback-scsv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/s3_enc.c 2014-10-15 14:45:25.598915935 +0200 +@@ -892,7 +892,7 @@ int ssl3_alert_code(int code) + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); ++ case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK); + default: return(-1); + } + } +- +diff -up openssl-1.0.1e/ssl/s3_lib.c.fallback-scsv openssl-1.0.1e/ssl/s3_lib.c +--- openssl-1.0.1e/ssl/s3_lib.c.fallback-scsv 2014-10-15 14:45:25.590915754 +0200 ++++ openssl-1.0.1e/ssl/s3_lib.c 2014-10-15 14:45:25.599915957 +0200 +@@ -3394,6 +3394,33 @@ long ssl3_ctrl(SSL *s, int cmd, long lar + EVP_PKEY_free(ptmp); + return 0; + } ++ ++ case SSL_CTRL_CHECK_PROTO_VERSION: ++ /* For library-internal use; checks that the current protocol ++ * is the highest enabled version (according to s->ctx->method, ++ * as version negotiation may have changed s->method). */ ++ if (s->version == s->ctx->method->version) ++ return 1; ++ /* Apparently we're using a version-flexible SSL_METHOD ++ * (not at its highest protocol version). */ ++ if (s->ctx->method->version == SSLv23_method()->version) ++ { ++#if TLS_MAX_VERSION != TLS1_2_VERSION ++# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION. ++#endif ++ if (!(s->options & SSL_OP_NO_TLSv1_2)) ++ return s->version == TLS1_2_VERSION; ++ if (!(s->options & SSL_OP_NO_TLSv1_1)) ++ return s->version == TLS1_1_VERSION; ++ if (!(s->options & SSL_OP_NO_TLSv1)) ++ return s->version == TLS1_VERSION; ++ if (!(s->options & SSL_OP_NO_SSLv3)) ++ return s->version == SSL3_VERSION; ++ if (!(s->options & SSL_OP_NO_SSLv2)) ++ return s->version == SSL2_VERSION; ++ } ++ return 0; /* Unexpected state; fail closed. */ ++ + default: + break; + } +@@ -3759,6 +3786,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx + break; + #endif + #endif ++ + default: + return(0); + } +@@ -4337,4 +4365,3 @@ long ssl_get_algorithm2(SSL *s) + return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; + return alg2; + } +- +diff -up openssl-1.0.1e/ssl/tls1.h.fallback-scsv openssl-1.0.1e/ssl/tls1.h +--- openssl-1.0.1e/ssl/tls1.h.fallback-scsv 2014-10-15 14:45:25.382911058 +0200 ++++ openssl-1.0.1e/ssl/tls1.h 2014-10-15 14:45:25.599915957 +0200 +@@ -159,17 +159,19 @@ extern "C" { + + #define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 + ++#define TLS1_VERSION 0x0301 ++#define TLS1_1_VERSION 0x0302 + #define TLS1_2_VERSION 0x0303 +-#define TLS1_2_VERSION_MAJOR 0x03 +-#define TLS1_2_VERSION_MINOR 0x03 ++#define TLS_MAX_VERSION TLS1_2_VERSION ++ ++#define TLS1_VERSION_MAJOR 0x03 ++#define TLS1_VERSION_MINOR 0x01 + +-#define TLS1_1_VERSION 0x0302 + #define TLS1_1_VERSION_MAJOR 0x03 + #define TLS1_1_VERSION_MINOR 0x02 + +-#define TLS1_VERSION 0x0301 +-#define TLS1_VERSION_MAJOR 0x03 +-#define TLS1_VERSION_MINOR 0x01 ++#define TLS1_2_VERSION_MAJOR 0x03 ++#define TLS1_2_VERSION_MINOR 0x03 + + #define TLS1_get_version(s) \ + ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0) +@@ -187,6 +189,7 @@ extern "C" { + #define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ + #define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ + #define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ ++#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */ + #define TLS1_AD_USER_CANCELLED 90 + #define TLS1_AD_NO_RENEGOTIATION 100 + /* codes 110-114 are from RFC3546 */ +diff -up openssl-1.0.1e/ssl/t1_enc.c.fallback-scsv openssl-1.0.1e/ssl/t1_enc.c +--- openssl-1.0.1e/ssl/t1_enc.c.fallback-scsv 2014-10-15 14:45:25.557915009 +0200 ++++ openssl-1.0.1e/ssl/t1_enc.c 2014-10-15 14:45:25.599915957 +0200 +@@ -1265,6 +1265,7 @@ int tls1_alert_code(int code) + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); + case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY); ++ case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK); + #if 0 /* not appropriate for TLS, not used for DTLS */ + case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return + (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); diff --git a/SOURCES/openssl-1.0.1e-fips-ctor.patch b/SOURCES/openssl-1.0.1e-fips-ctor.patch new file mode 100755 index 00000000..44576ef7 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-fips-ctor.patch @@ -0,0 +1,179 @@ +diff -up openssl-1.0.1e/crypto/fips/fips.c.fips-ctor openssl-1.0.1e/crypto/fips/fips.c +--- openssl-1.0.1e/crypto/fips/fips.c.fips-ctor 2013-09-26 13:52:30.767885457 +0200 ++++ openssl-1.0.1e/crypto/fips/fips.c 2013-09-26 14:01:29.406010187 +0200 +@@ -60,6 +60,8 @@ + #include + #include + #include ++#include ++#include + #include "fips_locl.h" + + #ifdef OPENSSL_FIPS +@@ -198,8 +200,10 @@ bin2hex(void *buf, size_t len) + return hex; + } + +-#define HMAC_PREFIX "." +-#define HMAC_SUFFIX ".hmac" ++#define HMAC_PREFIX "." ++#ifndef HMAC_SUFFIX ++#define HMAC_SUFFIX ".hmac" ++#endif + #define READ_BUFFER_LENGTH 16384 + + static char * +@@ -279,19 +283,13 @@ end: + } + + static int +-FIPSCHECK_verify(const char *libname, const char *symbolname) ++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) +@@ -341,6 +339,53 @@ end: + 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; +@@ -379,15 +424,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.1e/crypto/fips/fips.h.fips-ctor openssl-1.0.1e/crypto/fips/fips.h +--- openssl-1.0.1e/crypto/fips/fips.h.fips-ctor 2013-09-26 13:52:30.814886515 +0200 ++++ openssl-1.0.1e/crypto/fips/fips.h 2013-09-26 13:52:30.816886560 +0200 +@@ -74,6 +74,7 @@ struct hmac_ctx_st; + + 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.1e/crypto/o_init.c.fips-ctor openssl-1.0.1e/crypto/o_init.c +--- openssl-1.0.1e/crypto/o_init.c.fips-ctor 2013-09-26 13:52:30.807886357 +0200 ++++ openssl-1.0.1e/crypto/o_init.c 2013-09-26 14:00:21.000000000 +0200 +@@ -71,6 +71,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'; +@@ -85,9 +88,15 @@ static void init_fips_mode(void) + * otherwise. + */ + +- if (buf[0] == '1') ++ if (buf[0] != '1') ++ { ++ /* drop down to non-FIPS mode if it is not requested */ ++ FIPS_mode_set(0); ++ } ++ else + { +- FIPS_mode_set(1); ++ /* abort if selftest failed */ ++ FIPS_selftest_check(); + } + } + #endif +@@ -96,13 +105,17 @@ static void init_fips_mode(void) + * Currently only 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.1e-fips-ec.patch b/SOURCES/openssl-1.0.1e-fips-ec.patch new file mode 100755 index 00000000..e1f648c7 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-fips-ec.patch @@ -0,0 +1,2039 @@ +diff -up openssl-1.0.1e/crypto/ecdh/ecdh.h.fips-ec openssl-1.0.1e/crypto/ecdh/ecdh.h +--- openssl-1.0.1e/crypto/ecdh/ecdh.h.fips-ec 2013-11-08 17:59:42.755019363 +0100 ++++ openssl-1.0.1e/crypto/ecdh/ecdh.h 2013-11-08 17:59:43.147028002 +0100 +@@ -85,6 +85,8 @@ + extern "C" { + #endif + ++#define EC_FLAG_COFACTOR_ECDH 0x1000 ++ + const ECDH_METHOD *ECDH_OpenSSL(void); + + void ECDH_set_default_method(const ECDH_METHOD *); +diff -up openssl-1.0.1e/crypto/ecdh/ecdhtest.c.fips-ec openssl-1.0.1e/crypto/ecdh/ecdhtest.c +--- openssl-1.0.1e/crypto/ecdh/ecdhtest.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ecdh/ecdhtest.c 2013-11-08 17:59:54.712282862 +0100 +@@ -323,8 +323,10 @@ int main(int argc, char *argv[]) + if ((ctx=BN_CTX_new()) == NULL) 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; + if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) goto err; + if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) goto err; +diff -up openssl-1.0.1e/crypto/ecdh/ech_lib.c.fips-ec openssl-1.0.1e/crypto/ecdh/ech_lib.c +--- openssl-1.0.1e/crypto/ecdh/ech_lib.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ecdh/ech_lib.c 2013-11-08 17:59:43.148028024 +0100 +@@ -94,14 +94,7 @@ const ECDH_METHOD *ECDH_get_default_meth + { + 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.1e/crypto/ecdh/ech_ossl.c.fips-ec openssl-1.0.1e/crypto/ecdh/ech_ossl.c +--- openssl-1.0.1e/crypto/ecdh/ech_ossl.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ecdh/ech_ossl.c 2013-11-08 17:59:43.148028024 +0100 +@@ -79,6 +79,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, void *out, size_t *outlen)); +@@ -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 */ + }; + +@@ -118,6 +122,14 @@ 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 */ +@@ -137,6 +149,18 @@ static int ecdh_compute_key(void *out, s + } + + group = EC_KEY_get0_group(ecdh); ++ ++ if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) ++ { ++ if (!EC_GROUP_get_cofactor(group, x, ctx) || ++ !BN_mul(x, x, priv_key, ctx)) ++ { ++ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); ++ goto err; ++ } ++ priv_key = x; ++ } ++ + if ((tmp=EC_POINT_new(group)) == NULL) + { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE); +diff -up openssl-1.0.1e/crypto/ecdsa/ecdsatest.c.fips-ec openssl-1.0.1e/crypto/ecdsa/ecdsatest.c +--- openssl-1.0.1e/crypto/ecdsa/ecdsatest.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ecdsa/ecdsatest.c 2013-11-08 17:59:43.148028024 +0100 +@@ -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", +@@ -157,7 +160,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) +@@ -550,7 +553,9 @@ 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; + + ret = 0; +diff -up openssl-1.0.1e/crypto/ecdsa/ecs_lib.c.fips-ec openssl-1.0.1e/crypto/ecdsa/ecs_lib.c +--- openssl-1.0.1e/crypto/ecdsa/ecs_lib.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ecdsa/ecs_lib.c 2013-11-08 17:59:43.148028024 +0100 +@@ -81,14 +81,7 @@ const ECDSA_METHOD *ECDSA_get_default_me + { + 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.1e/crypto/ecdsa/ecs_ossl.c.fips-ec openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c +--- openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ecdsa/ecs_ossl.c 2013-11-08 17:59:43.148028024 +0100 +@@ -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 *, EC_KEY *eckey); +@@ -77,7 +80,7 @@ static ECDSA_METHOD openssl_ecdsa_meth = + NULL, /* init */ + NULL, /* finish */ + #endif +- 0, /* flags */ ++ ECDSA_FLAG_FIPS_METHOD, /* flags */ + NULL /* app_data */ + }; + +@@ -231,6 +234,14 @@ 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); +@@ -360,6 +371,14 @@ 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.1e/crypto/ec/ec_key.c.fips-ec openssl-1.0.1e/crypto/ec/ec_key.c +--- openssl-1.0.1e/crypto/ec/ec_key.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ec/ec_key.c 2013-11-08 17:59:43.148028024 +0100 +@@ -64,9 +64,6 @@ + #include + #include "ec_lcl.h" + #include +-#ifdef OPENSSL_FIPS +-#include +-#endif + + EC_KEY *EC_KEY_new(void) + { +@@ -234,6 +231,39 @@ 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; +@@ -242,8 +272,11 @@ 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) +@@ -287,6 +320,15 @@ 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: +@@ -429,10 +471,12 @@ int EC_KEY_set_public_key_affine_coordin + tx, ty, ctx)) + 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); +diff -up openssl-1.0.1e/crypto/ec/ecp_mont.c.fips-ec openssl-1.0.1e/crypto/ec/ecp_mont.c +--- openssl-1.0.1e/crypto/ec/ecp_mont.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ec/ecp_mont.c 2013-11-08 17:59:43.149028046 +0100 +@@ -63,18 +63,11 @@ + + #include + +-#ifdef OPENSSL_FIPS +-#include +-#endif +- + #include "ec_lcl.h" + + + const EC_METHOD *EC_GFp_mont_method(void) + { +-#ifdef OPENSSL_FIPS +- return fips_ec_gfp_mont_method(); +-#else + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, +@@ -115,7 +108,6 @@ const EC_METHOD *EC_GFp_mont_method(void + ec_GFp_mont_field_set_to_one }; + + return &ret; +-#endif + } + + +diff -up openssl-1.0.1e/crypto/ec/ecp_nist.c.fips-ec openssl-1.0.1e/crypto/ec/ecp_nist.c +--- openssl-1.0.1e/crypto/ec/ecp_nist.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ec/ecp_nist.c 2013-11-08 17:59:43.149028046 +0100 +@@ -67,15 +67,8 @@ + #include + #include "ec_lcl.h" + +-#ifdef OPENSSL_FIPS +-#include +-#endif +- + const EC_METHOD *EC_GFp_nist_method(void) + { +-#ifdef OPENSSL_FIPS +- return fips_ec_gfp_nist_method(); +-#else + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, +@@ -116,7 +109,6 @@ const EC_METHOD *EC_GFp_nist_method(void + 0 /* field_set_to_one */ }; + + return &ret; +-#endif + } + + int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) +diff -up openssl-1.0.1e/crypto/ec/ecp_smpl.c.fips-ec openssl-1.0.1e/crypto/ec/ecp_smpl.c +--- openssl-1.0.1e/crypto/ec/ecp_smpl.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ec/ecp_smpl.c 2013-11-08 17:59:43.149028046 +0100 +@@ -65,17 +65,10 @@ + #include + #include + +-#ifdef OPENSSL_FIPS +-#include +-#endif +- + #include "ec_lcl.h" + + const EC_METHOD *EC_GFp_simple_method(void) + { +-#ifdef OPENSSL_FIPS +- return fips_ec_gfp_simple_method(); +-#else + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, +@@ -116,7 +109,6 @@ const EC_METHOD *EC_GFp_simple_method(vo + 0 /* field_set_to_one */ }; + + return &ret; +-#endif + } + + +@@ -186,6 +178,12 @@ 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(); +diff -up openssl-1.0.1e/crypto/evp/m_ecdsa.c.fips-ec openssl-1.0.1e/crypto/evp/m_ecdsa.c +--- openssl-1.0.1e/crypto/evp/m_ecdsa.c.fips-ec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/m_ecdsa.c 2013-11-08 17:59:43.149028046 +0100 +@@ -116,7 +116,6 @@ + #include + + #ifndef OPENSSL_NO_SHA +-#ifndef OPENSSL_FIPS + + static int init(EVP_MD_CTX *ctx) + { return SHA1_Init(ctx->md_data); } +@@ -132,7 +131,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, +@@ -148,4 +147,3 @@ const EVP_MD *EVP_ecdsa(void) + return(&ecdsa_md); + } + #endif +-#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c.fips-ec openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c.fips-ec 2013-11-08 17:59:43.149028046 +0100 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_ecdhvs.c 2013-11-08 17:59:43.149028046 +0100 +@@ -0,0 +1,496 @@ ++/* 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.1e/crypto/fips/cavs/fips_ecdsavs.c.fips-ec openssl-1.0.1e/crypto/fips/cavs/fips_ecdsavs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_ecdsavs.c.fips-ec 2013-11-08 17:59:43.150028068 +0100 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_ecdsavs.c 2013-11-08 17:59:43.150028068 +0100 +@@ -0,0 +1,533 @@ ++/* 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.1e/crypto/fips/fips_ecdh_selftest.c.fips-ec openssl-1.0.1e/crypto/fips/fips_ecdh_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_ecdh_selftest.c.fips-ec 2013-11-08 17:59:43.150028068 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_ecdh_selftest.c 2013-11-08 17:59:43.150028068 +0100 +@@ -0,0 +1,252 @@ ++/* 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.1e/crypto/fips/fips_ecdsa_selftest.c.fips-ec openssl-1.0.1e/crypto/fips/fips_ecdsa_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_ecdsa_selftest.c.fips-ec 2013-11-08 17:59:43.150028068 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_ecdsa_selftest.c 2013-11-08 17:59:43.150028068 +0100 +@@ -0,0 +1,167 @@ ++/* 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.1e/crypto/fips/fips.h.fips-ec openssl-1.0.1e/crypto/fips/fips.h +--- openssl-1.0.1e/crypto/fips/fips.h.fips-ec 2013-11-08 17:59:43.116027318 +0100 ++++ openssl-1.0.1e/crypto/fips/fips.h 2013-11-08 17:59:43.150028068 +0100 +@@ -93,6 +93,8 @@ int FIPS_selftest_rsa(void); + 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.1e/crypto/fips/fips_post.c.fips-ec openssl-1.0.1e/crypto/fips/fips_post.c +--- openssl-1.0.1e/crypto/fips/fips_post.c.fips-ec 2013-11-08 17:59:43.117027340 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_post.c 2013-11-08 17:59:43.150028068 +0100 +@@ -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.1e/crypto/fips/Makefile.fips-ec openssl-1.0.1e/crypto/fips/Makefile +--- openssl-1.0.1e/crypto/fips/Makefile.fips-ec 2013-11-08 17:59:43.119027384 +0100 ++++ openssl-1.0.1e/crypto/fips/Makefile 2013-11-08 17:59:43.151028090 +0100 +@@ -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 + +@@ -118,6 +118,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 +@@ -231,6 +246,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 +@@ -245,6 +300,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.1e/version.map.fips-ec openssl-1.0.1e/version.map +--- openssl-1.0.1e/version.map.fips-ec 2013-11-08 17:59:43.131027649 +0100 ++++ openssl-1.0.1e/version.map 2013-11-08 17:59:43.151028090 +0100 +@@ -6,3 +6,7 @@ OPENSSL_1.0.1 { + _original*; + _current*; + }; ++OPENSSL_1.0.1_EC { ++ global: ++ EC*; ++}; diff --git a/SOURCES/openssl-1.0.1e-fips.patch b/SOURCES/openssl-1.0.1e-fips.patch new file mode 100755 index 00000000..d1a7e7fb --- /dev/null +++ b/SOURCES/openssl-1.0.1e-fips.patch @@ -0,0 +1,20452 @@ +diff -up openssl-1.0.1e/apps/pkcs12.c.fips openssl-1.0.1e/apps/pkcs12.c +--- openssl-1.0.1e/apps/pkcs12.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/pkcs12.c 2013-10-04 11:48:04.172693955 +0200 +@@ -67,6 +67,9 @@ + #include + #include + #include ++#ifdef OPENSSL_FIPS ++#include ++#endif + + #define PROG pkcs12_main + +@@ -130,6 +133,11 @@ int MAIN(int argc, char **argv) + + apps_startup(); + ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode()) ++ cert_pbe = key_pbe; /* cannot use RC2 in the FIPS mode */ ++#endif ++ + enc = EVP_des_ede3_cbc(); + if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); + +diff -up openssl-1.0.1e/apps/speed.c.fips openssl-1.0.1e/apps/speed.c +--- openssl-1.0.1e/apps/speed.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/speed.c 2013-10-04 11:49:56.384227859 +0200 +@@ -195,7 +195,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 +@@ -203,7 +202,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 +@@ -941,7 +939,12 @@ int MAIN(int argc, char **argv) + #ifndef OPENSSL_NO_RSA + if (strcmp(*argv,"rsa") == 0) + { ++#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; +@@ -951,7 +954,12 @@ int MAIN(int argc, char **argv) + #ifndef OPENSSL_NO_DSA + if (strcmp(*argv,"dsa") == 0) + { ++#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; + } +@@ -1162,12 +1170,18 @@ int MAIN(int argc, char **argv) + { + for (i=0; i) + + 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.1e/crypto/aes/aes_misc.c.fips openssl-1.0.1e/crypto/aes/aes_misc.c +--- openssl-1.0.1e/crypto/aes/aes_misc.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/aes/aes_misc.c 2013-10-04 11:48:04.173693978 +0200 +@@ -69,17 +69,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.1e/crypto/cmac/cmac.c.fips openssl-1.0.1e/crypto/cmac/cmac.c +--- openssl-1.0.1e/crypto/cmac/cmac.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/cmac/cmac.c 2013-10-04 11:48:04.173693978 +0200 +@@ -107,13 +107,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); +@@ -164,11 +157,6 @@ int CMAC_Init(CMAC_CTX *ctx, const void + EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS); + return 0; + } +- /* 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 */ +@@ -216,10 +204,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) +@@ -261,10 +245,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.1e/crypto/crypto.h.fips openssl-1.0.1e/crypto/crypto.h +--- openssl-1.0.1e/crypto/crypto.h.fips 2013-10-04 11:48:04.058691381 +0200 ++++ openssl-1.0.1e/crypto/crypto.h 2013-10-04 11:48:04.173693978 +0200 +@@ -553,24 +553,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 + +@@ -587,6 +592,9 @@ int CRYPTO_memcmp(const void *a, const v + */ + 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.1e/crypto/des/des.h.fips openssl-1.0.1e/crypto/des/des.h +--- openssl-1.0.1e/crypto/des/des.h.fips 2013-10-04 11:48:04.088692058 +0200 ++++ openssl-1.0.1e/crypto/des/des.h 2013-10-04 11:48:04.173693978 +0200 +@@ -224,9 +224,6 @@ int DES_set_key(const_DES_cblock *key,DE + 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,long length, +diff -up openssl-1.0.1e/crypto/des/set_key.c.fips openssl-1.0.1e/crypto/des/set_key.c +--- openssl-1.0.1e/crypto/des/set_key.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/des/set_key.c 2013-10-04 11:48:04.174694001 +0200 +@@ -336,13 +336,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}; + register DES_LONG c,d,t,s,t2; +diff -up openssl-1.0.1e/crypto/dh/dh_gen.c.fips openssl-1.0.1e/crypto/dh/dh_gen.c +--- openssl-1.0.1e/crypto/dh/dh_gen.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dh/dh_gen.c 2013-10-04 11:48:04.174694001 +0200 +@@ -84,11 +84,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); + } + +@@ -123,6 +118,20 @@ 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; + BN_CTX_start(ctx); +diff -up openssl-1.0.1e/crypto/dh/dh.h.fips openssl-1.0.1e/crypto/dh/dh.h +--- openssl-1.0.1e/crypto/dh/dh.h.fips 2014-02-06 18:04:19.000000000 +0100 ++++ openssl-1.0.1e/crypto/dh/dh.h 2014-02-11 16:01:17.039345356 +0100 +@@ -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 + #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH + * implementation now uses constant time +@@ -210,6 +212,7 @@ int DH_check(const DH *dh,int *codes); + int DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes); + int DH_generate_key(DH *dh); + int DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh); ++int DH_compute_key_padded(unsigned char *key,const BIGNUM *pub_key,DH *dh); + DH * d2i_DHparams(DH **a,const unsigned char **pp, long length); + int i2d_DHparams(const DH *a,unsigned char **pp); + #ifndef OPENSSL_NO_FP_API +diff -up openssl-1.0.1e/crypto/dh/dh_key.c.fips openssl-1.0.1e/crypto/dh/dh_key.c +--- openssl-1.0.1e/crypto/dh/dh_key.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dh/dh_key.c 2014-02-11 15:57:55.266840301 +0100 +@@ -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,6 +100,21 @@ int DH_compute_key(unsigned char *key, c + return dh->meth->compute_key(key, pub_key, dh); + } + ++int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) ++ { ++ int rv, pad; ++ rv = DH_compute_key(key, pub_key, dh); ++ if (rv <= 0) ++ return rv; ++ pad = BN_num_bytes(dh->p) - rv; ++ if (pad > 0) ++ { ++ memmove(key + pad, key, rv); ++ memset(key, 0, pad); ++ } ++ return rv + pad; ++ } ++ + static DH_METHOD dh_ossl = { + "OpenSSL DH Method", + generate_key, +@@ -104,7 +122,7 @@ compute_key, + dh_bn_mod_exp, + dh_init, + dh_finish, +-0, ++DH_FLAG_FIPS_METHOD, + NULL, + NULL + }; +@@ -123,6 +141,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; + +@@ -213,6 +239,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) goto err; +@@ -280,6 +313,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.1e/crypto/dh/dh_lib.c.fips openssl-1.0.1e/crypto/dh/dh_lib.c +--- openssl-1.0.1e/crypto/dh/dh_lib.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dh/dh_lib.c 2013-10-04 11:48:04.174694001 +0200 +@@ -81,14 +81,7 @@ const DH_METHOD *DH_get_default_method(v + { + 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.1e/crypto/dsa/dsa_err.c.fips openssl-1.0.1e/crypto/dsa/dsa_err.c +--- openssl-1.0.1e/crypto/dsa/dsa_err.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_err.c 2013-10-04 11:48:04.174694001 +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_DO_SIGN), "DSA_do_sign"}, + {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, + {ERR_FUNC(DSA_F_DSA_GENERATE_KEY), "DSA_generate_key"}, +@@ -106,6 +108,8 @@ static ERR_STRING_DATA DSA_str_reasons[] + {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, + {ERR_REASON(DSA_R_DECODE_ERROR) ,"decode error"}, + {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, ++{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.1e/crypto/dsa/dsa_gen.c.fips openssl-1.0.1e/crypto/dsa/dsa_gen.c +--- openssl-1.0.1e/crypto/dsa/dsa_gen.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_gen.c 2013-10-04 11:48:04.175694023 +0200 +@@ -85,6 +85,14 @@ + #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, BN_GENCB *cb) +@@ -100,14 +108,6 @@ 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; +@@ -125,27 +125,119 @@ int DSA_generate_parameters_ex(DSA *ret, + } + + return dsa_builtin_paramgen(ret, bits, qbits, evpmd, +- seed_in, seed_len, NULL, counter_ret, h_ret, cb); ++ 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, + 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) +@@ -153,51 +245,43 @@ int dsa_builtin_paramgen(DSA *ret, size_ + return 0; + + if (evpmd == NULL) +- /* use SHA1 as default */ +- evpmd = EVP_sha1(); ++ { ++ 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 ((ctx=BN_CTX_new()) == NULL) +- goto err; +- +- if ((mont=BN_MONT_CTX_new()) == NULL) +- goto err; +- +- BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); +- g = BN_CTX_get(ctx); + W = BN_CTX_get(ctx); +- q = BN_CTX_get(ctx); ++ *q_ret = q = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); +- p = BN_CTX_get(ctx); ++ *p_ret = p = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + + if (!BN_lshift(test,BN_value_one(),bits-1)) + goto err; + ++ /* step 3 n = \lceil bits / qbits \rceil - 1 */ ++ n = (bits+qbits-1)/qbits - 1; ++ /* step 4 b = bits - 1 - n * qbits */ ++ b = bits - 1 - n*qbits; ++ + for (;;) + { + for (;;) /* find q */ + { + int seed_is_random; + +- /* step 1 */ ++ /* step 5 generate seed */ + if(!BN_GENCB_call(cb, 0, m++)) + goto err; + +@@ -212,30 +296,18 @@ int dsa_builtin_paramgen(DSA *ret, size_ + seed_len=0; /* use random seed if 'seed_in' turns out to 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) +@@ -243,27 +315,22 @@ 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)) goto err; + 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: */ +@@ -278,28 +345,30 @@ int dsa_builtin_paramgen(DSA *ret, size_ + NULL)) + goto err; + +- /* step 8 */ + if (!BN_bin2bn(md, qsize, r0)) + goto err; +- if (!BN_lshift(r0,r0,(qsize << 3)*k)) goto err; ++ 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) +@@ -308,19 +377,45 @@ int dsa_builtin_paramgen(DSA *ret, size_ + goto err; + } + +- /* step 13 */ ++ /* step 11.9 */ + counter++; + /* "offset = offset + n + 1" */ + +- /* step 14 */ +- if (counter >= 4096) break; ++ /* step 12 */ ++ if (counter >= 4*bits) break; + } + } + end: + 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; + if (!BN_div(r0,NULL,test,q,ctx)) goto err; +@@ -344,26 +439,7 @@ end: + 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; +diff -up openssl-1.0.1e/crypto/dsa/dsa.h.fips openssl-1.0.1e/crypto/dsa/dsa.h +--- openssl-1.0.1e/crypto/dsa/dsa.h.fips 2013-10-04 11:48:03.956689078 +0200 ++++ openssl-1.0.1e/crypto/dsa/dsa.h 2013-10-04 11:48:04.175694023 +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 + #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA + * implementation now uses constant time +@@ -264,6 +266,17 @@ 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) +@@ -285,10 +298,13 @@ 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_KEYGEN 124 ++#define DSA_F_DSA_BUILTIN_PARAMGEN 123 + #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 +@@ -314,11 +330,15 @@ 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_KEY_SIZE_INVALID 113 ++#define DSA_R_KEY_SIZE_TOO_SMALL 110 + #define DSA_R_MISSING_PARAMETERS 101 + #define DSA_R_MODULUS_TOO_LARGE 103 +-#define DSA_R_NEED_NEW_SETUP_VALUES 110 ++#define DSA_R_NEED_NEW_SETUP_VALUES 112 + #define DSA_R_NON_FIPS_DSA_METHOD 111 ++#define DSA_R_NON_FIPS_METHOD 111 + #define DSA_R_NO_PARAMETERS_SET 107 ++#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE /* unused */ 112 + #define DSA_R_PARAMETER_ENCODING_ERROR 105 + + #ifdef __cplusplus +diff -up openssl-1.0.1e/crypto/dsa/dsa_key.c.fips openssl-1.0.1e/crypto/dsa/dsa_key.c +--- openssl-1.0.1e/crypto/dsa/dsa_key.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_key.c 2013-10-04 11:48:04.175694023 +0200 +@@ -66,6 +66,35 @@ + + #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); +@@ -82,10 +111,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); + } + +@@ -95,6 +120,15 @@ 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; + + if (dsa->priv_key == NULL) +@@ -133,6 +167,14 @@ 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.1e/crypto/dsa/dsa_lib.c.fips openssl-1.0.1e/crypto/dsa/dsa_lib.c +--- openssl-1.0.1e/crypto/dsa/dsa_lib.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_lib.c 2013-10-04 11:48:04.175694023 +0200 +@@ -87,14 +87,7 @@ const DSA_METHOD *DSA_get_default_method + { + 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.1e/crypto/dsa/dsa_locl.h.fips openssl-1.0.1e/crypto/dsa/dsa_locl.h +--- openssl-1.0.1e/crypto/dsa/dsa_locl.h.fips 2013-10-04 11:48:03.958689123 +0200 ++++ openssl-1.0.1e/crypto/dsa/dsa_locl.h 2013-10-04 11:48:04.175694023 +0200 +@@ -56,5 +56,4 @@ + + int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len, +- unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); +diff -up openssl-1.0.1e/crypto/dsa/dsa_ossl.c.fips openssl-1.0.1e/crypto/dsa/dsa_ossl.c +--- openssl-1.0.1e/crypto/dsa/dsa_ossl.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_ossl.c 2013-10-04 11:48:04.175694023 +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, BIGNUM **rp); +@@ -82,7 +85,7 @@ NULL, /* dsa_mod_exp, */ + NULL, /* dsa_bn_mod_exp, */ + dsa_init, + dsa_finish, +-0, ++DSA_FLAG_FIPS_METHOD, + NULL, + NULL, + NULL +@@ -138,6 +141,21 @@ 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); + +@@ -325,6 +343,21 @@ static int dsa_do_verify(const unsigned + 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); +@@ -399,6 +432,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.1e/crypto/dsa/dsa_pmeth.c.fips openssl-1.0.1e/crypto/dsa/dsa_pmeth.c +--- openssl-1.0.1e/crypto/dsa/dsa_pmeth.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_pmeth.c 2013-10-04 11:48:04.175694023 +0200 +@@ -255,7 +255,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.1e/crypto/dsa/dsatest.c.fips openssl-1.0.1e/crypto/dsa/dsatest.c +--- openssl-1.0.1e/crypto/dsa/dsatest.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsatest.c 2013-10-04 11:48:04.176694045 +0200 +@@ -96,36 +96,41 @@ static int MS_CALLBACK dsa_cb(int p, int + /* seed, out_p, out_q, out_g are taken from the updated Appendix 5 to + * FIPS 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"; +@@ -157,7 +162,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)) + goto end; + +@@ -170,9 +175,9 @@ 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) ++ if (counter != 239) + { +- BIO_printf(bio_err,"counter should be 105\n"); ++ BIO_printf(bio_err,"counter should be 239\n"); + goto end; + } + if (h != 2) +diff -up openssl-1.0.1e/crypto/engine/eng_all.c.fips openssl-1.0.1e/crypto/engine/eng_all.c +--- openssl-1.0.1e/crypto/engine/eng_all.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/engine/eng_all.c 2013-10-04 11:48:04.176694045 +0200 +@@ -58,11 +58,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 is the *only* way for standard builtin implementations to be be +diff -up openssl-1.0.1e/crypto/evp/c_allc.c.fips openssl-1.0.1e/crypto/evp/c_allc.c +--- openssl-1.0.1e/crypto/evp/c_allc.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/c_allc.c 2013-10-04 11:48:04.176694045 +0200 +@@ -65,6 +65,11 @@ + 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()); +@@ -227,4 +232,60 @@ 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_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_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_alias(SN_aes_256_cbc,"AES256"); ++ EVP_add_cipher_alias(SN_aes_256_cbc,"aes256"); ++#endif ++ } ++#endif + } +diff -up openssl-1.0.1e/crypto/evp/c_alld.c.fips openssl-1.0.1e/crypto/evp/c_alld.c +--- openssl-1.0.1e/crypto/evp/c_alld.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/c_alld.c 2013-10-04 11:48:04.176694045 +0200 +@@ -64,6 +64,11 @@ + + 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()); + #endif +@@ -111,4 +116,32 @@ void OpenSSL_add_all_digests(void) + #ifndef OPENSSL_NO_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.1e/crypto/evp/digest.c.fips openssl-1.0.1e/crypto/evp/digest.c +--- openssl-1.0.1e/crypto/evp/digest.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/digest.c 2013-10-04 11:48:04.176694045 +0200 +@@ -142,9 +142,50 @@ 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_selftest_failed()) ++ { ++ FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); ++ ctx->digest = &bad_md; ++ return 0; ++ } ++#endif + #ifndef OPENSSL_NO_ENGINE + /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts + * so this context may already have an ENGINE! Try to avoid releasing +@@ -201,6 +242,18 @@ 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->digest=type; +@@ -229,26 +282,15 @@ skip_to_init: + } + if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) + return 1; +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- { +- if (FIPS_digestinit(ctx, type)) +- return 1; +- OPENSSL_free(ctx->md_data); +- ctx->md_data = NULL; +- return 0; +- } +-#endif + return ctx->digest->init(ctx); + } + + int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) + { + #ifdef OPENSSL_FIPS +- return FIPS_digestupdate(ctx, data, count); +-#else +- return ctx->update(ctx,data,count); ++ FIPS_selftest_check(); + #endif ++ return ctx->update(ctx,data,count); + } + + /* The caller can assume that this removes any secret data from the context */ +@@ -263,11 +305,11 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, uns + /* The caller can assume that this removes any secret data from the context */ + int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) + { +-#ifdef OPENSSL_FIPS +- return FIPS_digestfinal(ctx, md, size); +-#else + int ret; + ++#ifdef OPENSSL_FIPS ++ FIPS_selftest_check(); ++#endif + OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ret=ctx->digest->final(ctx,md); + if (size != NULL) +@@ -279,7 +321,6 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, + } + memset(ctx->md_data,0,ctx->digest->ctx_size); + return ret; +-#endif + } + + int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) +@@ -373,7 +414,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. + */ +@@ -386,7 +426,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 +@@ -395,9 +434,6 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) + * functional reference we held for this reason. */ + 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.1e/crypto/evp/e_aes.c.fips openssl-1.0.1e/crypto/evp/e_aes.c +--- openssl-1.0.1e/crypto/evp/e_aes.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/e_aes.c 2013-10-04 11:48:04.177694068 +0200 +@@ -56,7 +56,6 @@ + #include + #include + #include "evp_locl.h" +-#ifndef OPENSSL_FIPS + #include "modes_lcl.h" + #include + +@@ -716,7 +715,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX * + if (arg <= 0) + return 0; + #ifdef OPENSSL_FIPS +- if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) ++ if (FIPS_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) + && arg < 12) + return 0; + #endif +@@ -1128,7 +1127,7 @@ static int aes_xts_cipher(EVP_CIPHER_CTX + return 0; + #ifdef OPENSSL_FIPS + /* Requirement of SP800-38E */ +- if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && ++ if (FIPS_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && + (len > (1UL<<20)*16)) + { + EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); +@@ -1311,4 +1310,3 @@ BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm + BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) + + #endif +-#endif +diff -up openssl-1.0.1e/crypto/evp/e_des3.c.fips openssl-1.0.1e/crypto/evp/e_des3.c +--- openssl-1.0.1e/crypto/evp/e_des3.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/e_des3.c 2013-10-04 11:48:04.177694068 +0200 +@@ -65,8 +65,6 @@ + #include + #include + +-#ifndef OPENSSL_FIPS +- + static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); + +@@ -208,9 +206,9 @@ static int des_ede3_cfb8_cipher(EVP_CIPH + } + + BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, +- EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, +- EVP_CIPHER_set_asn1_iv, +- EVP_CIPHER_get_asn1_iv, ++ EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, ++ des_ede_init_key, ++ NULL, NULL, NULL, + des3_ctrl) + + #define des_ede3_cfb64_cipher des_ede_cfb64_cipher +@@ -219,21 +217,21 @@ BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, + #define des_ede3_ecb_cipher des_ede_ecb_cipher + + BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, +- EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, +- EVP_CIPHER_set_asn1_iv, +- EVP_CIPHER_get_asn1_iv, ++ EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, ++ des_ede3_init_key, ++ NULL, NULL, NULL, + des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1, +- EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, +- EVP_CIPHER_set_asn1_iv, +- EVP_CIPHER_get_asn1_iv, ++ EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, ++ des_ede3_init_key, ++ NULL, NULL, NULL, + des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8, +- EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL, +- EVP_CIPHER_set_asn1_iv, +- EVP_CIPHER_get_asn1_iv, ++ EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1, ++ des_ede3_init_key, ++ NULL, NULL, NULL, + des3_ctrl) + + static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, +@@ -313,4 +311,3 @@ const EVP_CIPHER *EVP_des_ede3(void) + return &des_ede3_ecb; + } + #endif +-#endif +diff -up openssl-1.0.1e/crypto/evp/e_null.c.fips openssl-1.0.1e/crypto/evp/e_null.c +--- openssl-1.0.1e/crypto/evp/e_null.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/e_null.c 2013-10-04 11:48:04.177694068 +0200 +@@ -61,8 +61,6 @@ + #include + #include + +-#ifndef OPENSSL_FIPS +- + static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv,int enc); + static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, +@@ -71,7 +69,7 @@ static const EVP_CIPHER n_cipher= + { + NID_undef, + 1,0,0, +- 0, ++ EVP_CIPH_FLAG_FIPS, + null_init_key, + null_cipher, + NULL, +@@ -101,4 +99,3 @@ static int null_cipher(EVP_CIPHER_CTX *c + memcpy((char *)out,(const char *)in,inl); + return 1; + } +-#endif +diff -up openssl-1.0.1e/crypto/evp/evp_enc.c.fips openssl-1.0.1e/crypto/evp/evp_enc.c +--- openssl-1.0.1e/crypto/evp/evp_enc.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/evp_enc.c 2013-10-04 11:48:04.177694068 +0200 +@@ -69,17 +69,58 @@ + #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 + + + 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; */ + } +@@ -111,6 +152,14 @@ 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 this context may already have an ENGINE! Try to avoid releasing +@@ -169,10 +218,6 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ct + ctx->engine = NULL; + #endif + +-#ifdef OPENSSL_FIPS +- if (FIPS_mode()) +- return FIPS_cipherinit(ctx, cipher, key, iv, enc); +-#endif + ctx->cipher=cipher; + if (ctx->cipher->ctx_size) + { +@@ -206,10 +251,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 +@@ -249,6 +290,22 @@ skip_to_init: + } + } + ++#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)) return 0; + } +@@ -568,7 +625,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)) +@@ -579,16 +635,12 @@ 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) + /* The EVP_CIPHER we used belongs to an ENGINE, release the + * functional reference we held for this reason. */ + 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.1e/crypto/evp/evp.h.fips openssl-1.0.1e/crypto/evp/evp.h +--- openssl-1.0.1e/crypto/evp/evp.h.fips 2013-10-04 11:48:04.071691675 +0200 ++++ openssl-1.0.1e/crypto/evp/evp.h 2013-10-04 11:48:04.177694068 +0200 +@@ -75,6 +75,10 @@ + #include + #endif + ++#ifdef OPENSSL_FIPS ++#include ++#endif ++ + /* + #define EVP_RC2_KEY_SIZE 16 + #define EVP_RC4_KEY_SIZE 16 +@@ -282,10 +286,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 */ + +@@ -297,6 +297,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 */ + +@@ -348,15 +352,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.1e/crypto/evp/evp_lib.c.fips openssl-1.0.1e/crypto/evp/evp_lib.c +--- openssl-1.0.1e/crypto/evp/evp_lib.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/evp_lib.c 2013-10-04 11:48:04.177694068 +0200 +@@ -190,6 +190,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); + } + +diff -up openssl-1.0.1e/crypto/evp/evp_locl.h.fips openssl-1.0.1e/crypto/evp/evp_locl.h +--- openssl-1.0.1e/crypto/evp/evp_locl.h.fips 2013-10-04 11:48:04.067691584 +0200 ++++ openssl-1.0.1e/crypto/evp/evp_locl.h 2013-10-04 11:48:04.178694091 +0200 +@@ -258,10 +258,9 @@ 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 + { +@@ -367,11 +366,6 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_ + #define MD2_Init private_MD2_Init + #define MDC2_Init private_MDC2_Init + #define SHA_Init private_SHA_Init +-#define SHA1_Init private_SHA1_Init +-#define SHA224_Init private_SHA224_Init +-#define SHA256_Init private_SHA256_Init +-#define SHA384_Init private_SHA384_Init +-#define SHA512_Init private_SHA512_Init + + #define BF_set_key private_BF_set_key + #define CAST_set_key private_CAST_set_key +@@ -379,7 +373,6 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_ + #define SEED_set_key private_SEED_set_key + #define RC2_set_key private_RC2_set_key + #define RC4_set_key private_RC4_set_key +-#define DES_set_key_unchecked private_DES_set_key_unchecked + #define Camellia_set_key private_Camellia_set_key + + #endif +diff -up openssl-1.0.1e/crypto/evp/Makefile.fips openssl-1.0.1e/crypto/evp/Makefile +--- openssl-1.0.1e/crypto/evp/Makefile.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/Makefile 2013-10-04 11:48:04.178694091 +0200 +@@ -28,7 +28,7 @@ LIBSRC= encode.c digest.c evp_enc.c evp_ + bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ + c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \ + evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \ +- e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c evp_fips.c \ ++ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \ + e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c + + LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \ +@@ -41,7 +41,7 @@ LIBOBJ= encode.o digest.o evp_enc.o evp_ + bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \ + c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \ + evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \ +- e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o evp_fips.o \ ++ e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o \ + e_aes_cbc_hmac_sha1.o e_rc4_hmac_md5.o + + SRC= $(LIBSRC) +diff -up openssl-1.0.1e/crypto/evp/m_dss.c.fips openssl-1.0.1e/crypto/evp/m_dss.c +--- openssl-1.0.1e/crypto/evp/m_dss.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/m_dss.c 2013-10-04 11:48:04.178694091 +0200 +@@ -66,7 +66,6 @@ + #endif + + #ifndef OPENSSL_NO_SHA +-#ifndef OPENSSL_FIPS + + static int init(EVP_MD_CTX *ctx) + { return SHA1_Init(ctx->md_data); } +@@ -82,7 +81,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, +@@ -98,4 +97,3 @@ const EVP_MD *EVP_dss(void) + return(&dsa_md); + } + #endif +-#endif +diff -up openssl-1.0.1e/crypto/evp/m_dss1.c.fips openssl-1.0.1e/crypto/evp/m_dss1.c +--- openssl-1.0.1e/crypto/evp/m_dss1.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/m_dss1.c 2013-10-04 11:48:04.178694091 +0200 +@@ -68,8 +68,6 @@ + #include + #endif + +-#ifndef OPENSSL_FIPS +- + static int init(EVP_MD_CTX *ctx) + { return SHA1_Init(ctx->md_data); } + +@@ -84,7 +82,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, +@@ -100,4 +98,3 @@ const EVP_MD *EVP_dss1(void) + return(&dss1_md); + } + #endif +-#endif +diff -up openssl-1.0.1e/crypto/evp/m_md2.c.fips openssl-1.0.1e/crypto/evp/m_md2.c +--- openssl-1.0.1e/crypto/evp/m_md2.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/m_md2.c 2013-10-04 11:48:04.178694091 +0200 +@@ -68,6 +68,7 @@ + #ifndef OPENSSL_NO_RSA + #include + #endif ++#include "evp_locl.h" + + static int init(EVP_MD_CTX *ctx) + { return MD2_Init(ctx->md_data); } +diff -up openssl-1.0.1e/crypto/evp/m_sha1.c.fips openssl-1.0.1e/crypto/evp/m_sha1.c +--- openssl-1.0.1e/crypto/evp/m_sha1.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/m_sha1.c 2013-10-04 11:48:04.178694091 +0200 +@@ -59,8 +59,6 @@ + #include + #include "cryptlib.h" + +-#ifndef OPENSSL_FIPS +- + #ifndef OPENSSL_NO_SHA + + #include +@@ -85,7 +83,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, +@@ -122,7 +121,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, +@@ -141,7 +141,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, +@@ -172,7 +173,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, +@@ -191,7 +193,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, +@@ -206,4 +209,3 @@ const EVP_MD *EVP_sha512(void) + { return(&sha512_md); } + #endif /* ifndef OPENSSL_NO_SHA512 */ + +-#endif +diff -up openssl-1.0.1e/crypto/evp/p_sign.c.fips openssl-1.0.1e/crypto/evp/p_sign.c +--- openssl-1.0.1e/crypto/evp/p_sign.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/p_sign.c 2013-10-04 11:48:04.179694114 +0200 +@@ -61,6 +61,7 @@ + #include + #include + #include ++#include + + #ifdef undef + void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) +@@ -103,6 +104,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.1e/crypto/evp/p_verify.c.fips openssl-1.0.1e/crypto/evp/p_verify.c +--- openssl-1.0.1e/crypto/evp/p_verify.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/evp/p_verify.c 2013-10-04 11:48:04.179694114 +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) +@@ -88,6 +89,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.1e/crypto/fips/cavs/fips_aesavs.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_aesavs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_aesavs.c.fips 2013-10-04 11:48:04.179694114 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_aesavs.c 2013-10-04 11:48:04.179694114 +0200 +@@ -0,0 +1,939 @@ ++/* ==================================================================== ++ * Copyright (c) 2004 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++/*--------------------------------------------- ++ NIST AES Algorithm Validation Suite ++ Test Program ++ ++ Donated to OpenSSL by: ++ V-ONE Corporation ++ 20250 Century Blvd, Suite 300 ++ Germantown, MD 20874 ++ U.S.A. ++ ----------------------------------------------*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "e_os.h" ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS AES support\n"); ++ return(0); ++} ++ ++#else ++ ++#include ++#include "fips_utl.h" ++ ++#define AES_BLOCK_SIZE 16 ++ ++#define VERBOSE 0 ++ ++/*-----------------------------------------------*/ ++ ++int AESTest(EVP_CIPHER_CTX *ctx, ++ char *amode, int akeysz, unsigned char *aKey, ++ unsigned char *iVec, ++ int dir, /* 0 = decrypt, 1 = encrypt */ ++ unsigned char *plaintext, unsigned char *ciphertext, int len) ++ { ++ const EVP_CIPHER *cipher = NULL; ++ ++ if (strcasecmp(amode, "CBC") == 0) ++ { ++ switch (akeysz) ++ { ++ case 128: ++ cipher = EVP_aes_128_cbc(); ++ break; ++ ++ case 192: ++ cipher = EVP_aes_192_cbc(); ++ break; ++ ++ case 256: ++ cipher = EVP_aes_256_cbc(); ++ break; ++ } ++ ++ } ++ else if (strcasecmp(amode, "ECB") == 0) ++ { ++ switch (akeysz) ++ { ++ case 128: ++ cipher = EVP_aes_128_ecb(); ++ break; ++ ++ case 192: ++ cipher = EVP_aes_192_ecb(); ++ break; ++ ++ case 256: ++ cipher = EVP_aes_256_ecb(); ++ break; ++ } ++ } ++ else if (strcasecmp(amode, "CFB128") == 0) ++ { ++ switch (akeysz) ++ { ++ case 128: ++ cipher = EVP_aes_128_cfb128(); ++ break; ++ ++ case 192: ++ cipher = EVP_aes_192_cfb128(); ++ break; ++ ++ case 256: ++ cipher = EVP_aes_256_cfb128(); ++ break; ++ } ++ ++ } ++ else if (strncasecmp(amode, "OFB", 3) == 0) ++ { ++ switch (akeysz) ++ { ++ case 128: ++ cipher = EVP_aes_128_ofb(); ++ break; ++ ++ case 192: ++ cipher = EVP_aes_192_ofb(); ++ break; ++ ++ case 256: ++ cipher = EVP_aes_256_ofb(); ++ break; ++ } ++ } ++ else if(!strcasecmp(amode,"CFB1")) ++ { ++ switch (akeysz) ++ { ++ case 128: ++ cipher = EVP_aes_128_cfb1(); ++ break; ++ ++ case 192: ++ cipher = EVP_aes_192_cfb1(); ++ break; ++ ++ case 256: ++ cipher = EVP_aes_256_cfb1(); ++ break; ++ } ++ } ++ else if(!strcasecmp(amode,"CFB8")) ++ { ++ switch (akeysz) ++ { ++ case 128: ++ cipher = EVP_aes_128_cfb8(); ++ break; ++ ++ case 192: ++ cipher = EVP_aes_192_cfb8(); ++ break; ++ ++ case 256: ++ cipher = EVP_aes_256_cfb8(); ++ break; ++ } ++ } ++ else ++ { ++ printf("Unknown mode: %s\n", amode); ++ return 0; ++ } ++ if (!cipher) ++ { ++ printf("Invalid key size: %d\n", akeysz); ++ return 0; ++ } ++ if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) ++ return 0; ++ if(!strcasecmp(amode,"CFB1")) ++ M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); ++ if (dir) ++ EVP_Cipher(ctx, ciphertext, plaintext, len); ++ else ++ EVP_Cipher(ctx, plaintext, ciphertext, len); ++ return 1; ++ } ++ ++/*-----------------------------------------------*/ ++char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; ++char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"}; ++enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128}; ++enum XCrypt {XDECRYPT, XENCRYPT}; ++ ++/*=============================*/ ++/* Monte Carlo Tests */ ++/*-----------------------------*/ ++ ++/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/ ++/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/ ++ ++#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1) ++#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8))) ++ ++int do_mct(char *amode, ++ int akeysz, unsigned char *aKey,unsigned char *iVec, ++ int dir, unsigned char *text, int len, ++ FILE *rfp) ++ { ++ int ret = 0; ++ unsigned char key[101][32]; ++ unsigned char iv[101][AES_BLOCK_SIZE]; ++ unsigned char ptext[1001][32]; ++ unsigned char ctext[1001][32]; ++ unsigned char ciphertext[64+4]; ++ int i, j, n, n1, n2; ++ int imode = 0, nkeysz = akeysz/8; ++ EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX_init(&ctx); ++ ++ if (len > 32) ++ { ++ printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n", ++ amode, akeysz); ++ return -1; ++ } ++ for (imode = 0; imode < 6; ++imode) ++ if (strcmp(amode, t_mode[imode]) == 0) ++ break; ++ if (imode == 6) ++ { ++ printf("Unrecognized mode: %s\n", amode); ++ return -1; ++ } ++ ++ memcpy(key[0], aKey, nkeysz); ++ if (iVec) ++ memcpy(iv[0], iVec, AES_BLOCK_SIZE); ++ if (dir == XENCRYPT) ++ memcpy(ptext[0], text, len); ++ else ++ memcpy(ctext[0], text, len); ++ for (i = 0; i < 100; ++i) ++ { ++ /* printf("Iteration %d\n", i); */ ++ if (i > 0) ++ { ++ fprintf(rfp,"COUNT = %d\n",i); ++ OutputValue("KEY",key[i],nkeysz,rfp,0); ++ if (imode != ECB) /* ECB */ ++ OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0); ++ /* Output Ciphertext | Plaintext */ ++ OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp, ++ imode == CFB1); ++ } ++ for (j = 0; j < 1000; ++j) ++ { ++ switch (imode) ++ { ++ case ECB: ++ if (j == 0) ++ { /* set up encryption */ ++ ret = AESTest(&ctx, amode, akeysz, key[i], NULL, ++ dir, /* 0 = decrypt, 1 = encrypt */ ++ ptext[j], ctext[j], len); ++ if (dir == XENCRYPT) ++ memcpy(ptext[j+1], ctext[j], len); ++ else ++ memcpy(ctext[j+1], ptext[j], len); ++ } ++ else ++ { ++ if (dir == XENCRYPT) ++ { ++ EVP_Cipher(&ctx, ctext[j], ptext[j], len); ++ memcpy(ptext[j+1], ctext[j], len); ++ } ++ else ++ { ++ EVP_Cipher(&ctx, ptext[j], ctext[j], len); ++ memcpy(ctext[j+1], ptext[j], len); ++ } ++ } ++ break; ++ ++ case CBC: ++ case OFB: ++ case CFB128: ++ if (j == 0) ++ { ++ ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], ++ dir, /* 0 = decrypt, 1 = encrypt */ ++ ptext[j], ctext[j], len); ++ if (dir == XENCRYPT) ++ memcpy(ptext[j+1], iv[i], len); ++ else ++ memcpy(ctext[j+1], iv[i], len); ++ } ++ else ++ { ++ if (dir == XENCRYPT) ++ { ++ EVP_Cipher(&ctx, ctext[j], ptext[j], len); ++ memcpy(ptext[j+1], ctext[j-1], len); ++ } ++ else ++ { ++ EVP_Cipher(&ctx, ptext[j], ctext[j], len); ++ memcpy(ctext[j+1], ptext[j-1], len); ++ } ++ } ++ break; ++ ++ case CFB8: ++ if (j == 0) ++ { ++ ret = AESTest(&ctx, amode, akeysz, key[i], iv[i], ++ dir, /* 0 = decrypt, 1 = encrypt */ ++ ptext[j], ctext[j], len); ++ } ++ else ++ { ++ if (dir == XENCRYPT) ++ EVP_Cipher(&ctx, ctext[j], ptext[j], len); ++ else ++ EVP_Cipher(&ctx, ptext[j], ctext[j], len); ++ } ++ if (dir == XENCRYPT) ++ { ++ if (j < 16) ++ memcpy(ptext[j+1], &iv[i][j], len); ++ else ++ memcpy(ptext[j+1], ctext[j-16], len); ++ } ++ else ++ { ++ if (j < 16) ++ memcpy(ctext[j+1], &iv[i][j], len); ++ else ++ memcpy(ctext[j+1], ptext[j-16], len); ++ } ++ break; ++ ++ case CFB1: ++ if(j == 0) ++ { ++#if 0 ++ /* compensate for wrong endianness of input file */ ++ if(i == 0) ++ ptext[0][0]<<=7; ++#endif ++ ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir, ++ ptext[j], ctext[j], len); ++ } ++ else ++ { ++ if (dir == XENCRYPT) ++ EVP_Cipher(&ctx, ctext[j], ptext[j], len); ++ else ++ EVP_Cipher(&ctx, ptext[j], ctext[j], len); ++ ++ } ++ if(dir == XENCRYPT) ++ { ++ if(j < 128) ++ sb(ptext[j+1],0,gb(iv[i],j)); ++ else ++ sb(ptext[j+1],0,gb(ctext[j-128],0)); ++ } ++ else ++ { ++ if(j < 128) ++ sb(ctext[j+1],0,gb(iv[i],j)); ++ else ++ sb(ctext[j+1],0,gb(ptext[j-128],0)); ++ } ++ break; ++ } ++ } ++ --j; /* reset to last of range */ ++ /* Output Ciphertext | Plaintext */ ++ OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp, ++ imode == CFB1); ++ fprintf(rfp, "\n"); /* add separator */ ++ ++ /* Compute next KEY */ ++ if (dir == XENCRYPT) ++ { ++ if (imode == CFB8) ++ { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ ++ for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) ++ ciphertext[n1] = ctext[j-n2][0]; ++ } ++ else if(imode == CFB1) ++ { ++ for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) ++ sb(ciphertext,n1,gb(ctext[j-n2],0)); ++ } ++ else ++ switch (akeysz) ++ { ++ case 128: ++ memcpy(ciphertext, ctext[j], 16); ++ break; ++ case 192: ++ memcpy(ciphertext, ctext[j-1]+8, 8); ++ memcpy(ciphertext+8, ctext[j], 16); ++ break; ++ case 256: ++ memcpy(ciphertext, ctext[j-1], 16); ++ memcpy(ciphertext+16, ctext[j], 16); ++ break; ++ } ++ } ++ else ++ { ++ if (imode == CFB8) ++ { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */ ++ for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2) ++ ciphertext[n1] = ptext[j-n2][0]; ++ } ++ else if(imode == CFB1) ++ { ++ for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2) ++ sb(ciphertext,n1,gb(ptext[j-n2],0)); ++ } ++ else ++ switch (akeysz) ++ { ++ case 128: ++ memcpy(ciphertext, ptext[j], 16); ++ break; ++ case 192: ++ memcpy(ciphertext, ptext[j-1]+8, 8); ++ memcpy(ciphertext+8, ptext[j], 16); ++ break; ++ case 256: ++ memcpy(ciphertext, ptext[j-1], 16); ++ memcpy(ciphertext+16, ptext[j], 16); ++ break; ++ } ++ } ++ /* Compute next key: Key[i+1] = Key[i] xor ct */ ++ for (n = 0; n < nkeysz; ++n) ++ key[i+1][n] = key[i][n] ^ ciphertext[n]; ++ ++ /* Compute next IV and text */ ++ if (dir == XENCRYPT) ++ { ++ switch (imode) ++ { ++ case ECB: ++ memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE); ++ break; ++ case CBC: ++ case OFB: ++ case CFB128: ++ memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE); ++ memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE); ++ break; ++ case CFB8: ++ /* IV[i+1] = ct */ ++ for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) ++ iv[i+1][n1] = ctext[j-n2][0]; ++ ptext[0][0] = ctext[j-16][0]; ++ break; ++ case CFB1: ++ for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) ++ sb(iv[i+1],n1,gb(ctext[j-n2],0)); ++ ptext[0][0]=ctext[j-128][0]&0x80; ++ break; ++ } ++ } ++ else ++ { ++ switch (imode) ++ { ++ case ECB: ++ memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE); ++ break; ++ case CBC: ++ case OFB: ++ case CFB128: ++ memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE); ++ memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE); ++ break; ++ case CFB8: ++ for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2) ++ iv[i+1][n1] = ptext[j-n2][0]; ++ ctext[0][0] = ptext[j-16][0]; ++ break; ++ case CFB1: ++ for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2) ++ sb(iv[i+1],n1,gb(ptext[j-n2],0)); ++ ctext[0][0]=ptext[j-128][0]&0x80; ++ break; ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++/*================================================*/ ++/*---------------------------- ++ # Config info for v-one ++ # AESVS MMT test data for ECB ++ # State : Encrypt and Decrypt ++ # Key Length : 256 ++ # Fri Aug 30 04:07:22 PM ++ ----------------------------*/ ++ ++int proc_file(char *rqfile, char *rspfile) ++ { ++ char afn[256], rfn[256]; ++ FILE *afp = NULL, *rfp = NULL; ++ char ibuf[2048]; ++ char tbuf[2048]; ++ int ilen, len, ret = 0; ++ char algo[8] = ""; ++ char amode[8] = ""; ++ char atest[8] = ""; ++ int akeysz = 0; ++ unsigned char iVec[20], aKey[40]; ++ int dir = -1, err = 0, step = 0; ++ unsigned char plaintext[2048]; ++ unsigned char ciphertext[2048]; ++ char *rp; ++ EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX_init(&ctx); ++ ++ if (!rqfile || !(*rqfile)) ++ { ++ printf("No req file\n"); ++ return -1; ++ } ++ strcpy(afn, rqfile); ++ ++ if ((afp = fopen(afn, "r")) == NULL) ++ { ++ printf("Cannot open file: %s, %s\n", ++ afn, strerror(errno)); ++ return -1; ++ } ++ if (!rspfile) ++ { ++ strcpy(rfn,afn); ++ rp=strstr(rfn,"req/"); ++#ifdef OPENSSL_SYS_WIN32 ++ if (!rp) ++ rp=strstr(rfn,"req\\"); ++#endif ++ assert(rp); ++ memcpy(rp,"rsp",3); ++ rp = strstr(rfn, ".req"); ++ memcpy(rp, ".rsp", 4); ++ rspfile = rfn; ++ } ++ if ((rfp = fopen(rspfile, "w")) == NULL) ++ { ++ printf("Cannot open file: %s, %s\n", ++ rfn, strerror(errno)); ++ fclose(afp); ++ afp = NULL; ++ return -1; ++ } ++ while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) ++ { ++ tidy_line(tbuf, ibuf); ++ ilen = strlen(ibuf); ++ /* printf("step=%d ibuf=%s",step,ibuf); */ ++ switch (step) ++ { ++ case 0: /* read preamble */ ++ if (ibuf[0] == '\n') ++ { /* end of preamble */ ++ if ((*algo == '\0') || ++ (*amode == '\0') || ++ (akeysz == 0)) ++ { ++ printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n", ++ algo,amode,akeysz); ++ err = 1; ++ } ++ else ++ { ++ fputs(ibuf, rfp); ++ ++ step; ++ } ++ } ++ else if (ibuf[0] != '#') ++ { ++ printf("Invalid preamble item: %s\n", ibuf); ++ err = 1; ++ } ++ else ++ { /* process preamble */ ++ char *xp, *pp = ibuf+2; ++ int n; ++ if (akeysz) ++ { /* insert current time & date */ ++ time_t rtim = time(0); ++ fprintf(rfp, "# %s", ctime(&rtim)); ++ } ++ else ++ { ++ fputs(ibuf, rfp); ++ if (strncmp(pp, "AESVS ", 6) == 0) ++ { ++ strcpy(algo, "AES"); ++ /* get test type */ ++ pp += 6; ++ xp = strchr(pp, ' '); ++ n = xp-pp; ++ strncpy(atest, pp, n); ++ atest[n] = '\0'; ++ /* get mode */ ++ xp = strrchr(pp, ' '); /* get mode" */ ++ n = strlen(xp+1)-1; ++ strncpy(amode, xp+1, n); ++ amode[n] = '\0'; ++ /* amode[3] = '\0'; */ ++ if (VERBOSE) ++ printf("Test = %s, Mode = %s\n", atest, amode); ++ } ++ else if (strncasecmp(pp, "Key Length : ", 13) == 0) ++ { ++ akeysz = atoi(pp+13); ++ if (VERBOSE) ++ printf("Key size = %d\n", akeysz); ++ } ++ } ++ } ++ break; ++ ++ case 1: /* [ENCRYPT] | [DECRYPT] */ ++ if (ibuf[0] == '[') ++ { ++ fputs(ibuf, rfp); ++ ++step; ++ if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) ++ dir = 1; ++ else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) ++ dir = 0; ++ else ++ { ++ printf("Invalid keyword: %s\n", ibuf); ++ err = 1; ++ } ++ break; ++ } ++ else if (dir == -1) ++ { ++ err = 1; ++ printf("Missing ENCRYPT/DECRYPT keyword\n"); ++ break; ++ } ++ else ++ step = 2; ++ ++ case 2: /* KEY = xxxx */ ++ fputs(ibuf, rfp); ++ if(*ibuf == '\n') ++ break; ++ if(!strncasecmp(ibuf,"COUNT = ",8)) ++ break; ++ ++ if (strncasecmp(ibuf, "KEY = ", 6) != 0) ++ { ++ printf("Missing KEY\n"); ++ err = 1; ++ } ++ else ++ { ++ len = hex2bin((char*)ibuf+6, aKey); ++ if (len < 0) ++ { ++ printf("Invalid KEY\n"); ++ err =1; ++ break; ++ } ++ PrintValue("KEY", aKey, len); ++ if (strcmp(amode, "ECB") == 0) ++ { ++ memset(iVec, 0, sizeof(iVec)); ++ step = (dir)? 4: 5; /* no ivec for ECB */ ++ } ++ else ++ ++step; ++ } ++ break; ++ ++ case 3: /* IV = xxxx */ ++ fputs(ibuf, rfp); ++ if (strncasecmp(ibuf, "IV = ", 5) != 0) ++ { ++ printf("Missing IV\n"); ++ err = 1; ++ } ++ else ++ { ++ len = hex2bin((char*)ibuf+5, iVec); ++ if (len < 0) ++ { ++ printf("Invalid IV\n"); ++ err =1; ++ break; ++ } ++ PrintValue("IV", iVec, len); ++ step = (dir)? 4: 5; ++ } ++ break; ++ ++ case 4: /* PLAINTEXT = xxxx */ ++ fputs(ibuf, rfp); ++ if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) ++ { ++ printf("Missing PLAINTEXT\n"); ++ err = 1; ++ } ++ else ++ { ++ int nn = strlen(ibuf+12); ++ if(!strcmp(amode,"CFB1")) ++ len=bint2bin(ibuf+12,nn-1,plaintext); ++ else ++ len=hex2bin(ibuf+12, plaintext); ++ if (len < 0) ++ { ++ printf("Invalid PLAINTEXT: %s", ibuf+12); ++ err =1; ++ break; ++ } ++ if (len >= sizeof(plaintext)) ++ { ++ printf("Buffer overflow\n"); ++ } ++ PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); ++ if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ ++ { ++ if(do_mct(amode, akeysz, aKey, iVec, ++ dir, (unsigned char*)plaintext, len, ++ rfp) < 0) ++ EXIT(1); ++ } ++ else ++ { ++ ret = AESTest(&ctx, amode, akeysz, aKey, iVec, ++ dir, /* 0 = decrypt, 1 = encrypt */ ++ plaintext, ciphertext, len); ++ OutputValue("CIPHERTEXT",ciphertext,len,rfp, ++ !strcmp(amode,"CFB1")); ++ } ++ step = 6; ++ } ++ break; ++ ++ case 5: /* CIPHERTEXT = xxxx */ ++ fputs(ibuf, rfp); ++ if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) ++ { ++ printf("Missing KEY\n"); ++ err = 1; ++ } ++ else ++ { ++ if(!strcmp(amode,"CFB1")) ++ len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); ++ else ++ len = hex2bin(ibuf+13,ciphertext); ++ if (len < 0) ++ { ++ printf("Invalid CIPHERTEXT\n"); ++ err =1; ++ break; ++ } ++ ++ PrintValue("CIPHERTEXT", ciphertext, len); ++ if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */ ++ { ++ do_mct(amode, akeysz, aKey, iVec, ++ dir, ciphertext, len, rfp); ++ } ++ else ++ { ++ ret = AESTest(&ctx, amode, akeysz, aKey, iVec, ++ dir, /* 0 = decrypt, 1 = encrypt */ ++ plaintext, ciphertext, len); ++ OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, ++ !strcmp(amode,"CFB1")); ++ } ++ step = 6; ++ } ++ break; ++ ++ case 6: ++ if (ibuf[0] != '\n') ++ { ++ err = 1; ++ printf("Missing terminator\n"); ++ } ++ else if (strcmp(atest, "MCT") != 0) ++ { /* MCT already added terminating nl */ ++ fputs(ibuf, rfp); ++ } ++ step = 1; ++ break; ++ } ++ } ++ if (rfp) ++ fclose(rfp); ++ if (afp) ++ fclose(afp); ++ return err; ++ } ++ ++/*-------------------------------------------------- ++ Processes either a single file or ++ a set of files whose names are passed in a file. ++ A single file is specified as: ++ aes_test -f xxx.req ++ A set of files is specified as: ++ aes_test -d xxxxx.xxx ++ The default is: -d req.txt ++--------------------------------------------------*/ ++int main(int argc, char **argv) ++ { ++ char *rqlist = "req.txt", *rspfile = NULL; ++ FILE *fp = NULL; ++ char fn[250] = "", rfn[256] = ""; ++ int f_opt = 0, d_opt = 1; ++ ++#ifdef OPENSSL_FIPS ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ EXIT(1); ++ } ++#endif ++ if (argc > 1) ++ { ++ if (strcasecmp(argv[1], "-d") == 0) ++ { ++ d_opt = 1; ++ } ++ else if (strcasecmp(argv[1], "-f") == 0) ++ { ++ f_opt = 1; ++ d_opt = 0; ++ } ++ else ++ { ++ printf("Invalid parameter: %s\n", argv[1]); ++ return 0; ++ } ++ if (argc < 3) ++ { ++ printf("Missing parameter\n"); ++ return 0; ++ } ++ if (d_opt) ++ rqlist = argv[2]; ++ else ++ { ++ strcpy(fn, argv[2]); ++ rspfile = argv[3]; ++ } ++ } ++ if (d_opt) ++ { /* list of files (directory) */ ++ if (!(fp = fopen(rqlist, "r"))) ++ { ++ printf("Cannot open req list file\n"); ++ return -1; ++ } ++ while (fgets(fn, sizeof(fn), fp)) ++ { ++ strtok(fn, "\r\n"); ++ strcpy(rfn, fn); ++ if (VERBOSE) ++ printf("Processing: %s\n", rfn); ++ if (proc_file(rfn, rspfile)) ++ { ++ printf(">>> Processing failed for: %s <<<\n", rfn); ++ EXIT(1); ++ } ++ } ++ fclose(fp); ++ } ++ else /* single file */ ++ { ++ if (VERBOSE) ++ printf("Processing: %s\n", fn); ++ if (proc_file(fn, rspfile)) ++ { ++ printf(">>> Processing failed for: %s <<<\n", fn); ++ } ++ } ++ EXIT(0); ++ return 0; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_cmactest.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_cmactest.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_cmactest.c.fips 2013-10-04 11:48:04.179694114 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_cmactest.c 2013-10-04 11:48:04.179694114 +0200 +@@ -0,0 +1,517 @@ ++/* fips_cmactest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2005. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2005 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++#define OPENSSL_FIPSAPI ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS CMAC support\n"); ++ return(0); ++} ++ ++#else ++ ++#include ++#include "fips_utl.h" ++ ++static int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in, ++ int mode, int Klen_counts_keys, int known_keylen); ++static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out, ++ unsigned char *Key, int Klen, ++ unsigned char *Msg, int Msglen, ++ int Tlen); ++static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out, ++ unsigned char *Key, int Klen, ++ unsigned char *Msg, int Msglen, ++ unsigned char *Mac, int Maclen, ++ int Tlen); ++ ++#ifdef FIPS_ALGVS ++int fips_cmactest_main(int argc, char **argv) ++#else ++int main(int argc, char **argv) ++#endif ++ { ++ FILE *in = NULL, *out = NULL; ++ int mode = 0; /* 0 => Generate, 1 => Verify */ ++ int Klen_counts_keys = 0; /* 0 => Klen is size of one key ++ 1 => Klen is amount of keys ++ */ ++ int known_keylen = 0; /* Only set when Klen_counts_keys = 1 */ ++ const EVP_CIPHER *cipher = 0; ++ int ret = 1; ++ fips_algtest_init(); ++ ++ while (argc > 1 && argv[1][0] == '-') ++ { ++ switch (argv[1][1]) ++ { ++ case 'a': ++ { ++ char *p = &argv[1][2]; ++ if (*p == '\0') ++ { ++ if (argc <= 2) ++ { ++ fprintf(stderr, "Option %s needs a value\n", argv[1]); ++ goto end; ++ } ++ argv++; ++ argc--; ++ p = &argv[1][0]; ++ } ++ if (!strcmp(p, "aes128")) ++ cipher = EVP_aes_128_cbc(); ++ else if (!strcmp(p, "aes192")) ++ cipher = EVP_aes_192_cbc(); ++ else if (!strcmp(p, "aes256")) ++ cipher = EVP_aes_256_cbc(); ++ else if (!strcmp(p, "tdea3") || !strcmp(p, "tdes3")) ++ { ++ cipher = EVP_des_ede3_cbc(); ++ Klen_counts_keys = 1; ++ known_keylen = 8; ++ } ++ else ++ { ++ fprintf(stderr, "Unknown algorithm %s\n", p); ++ goto end; ++ } ++ } ++ break; ++ case 'g': ++ mode = 0; ++ break; ++ case 'v': ++ mode = 1; ++ break; ++ default: ++ fprintf(stderr, "Unknown option %s\n", argv[1]); ++ goto end; ++ } ++ argv++; ++ argc--; ++ } ++ if (argc == 1) ++ in = stdin; ++ else ++ in = fopen(argv[1], "r"); ++ ++ if (argc < 2) ++ out = stdout; ++ else ++ out = fopen(argv[2], "w"); ++ ++ if (!in) ++ { ++ fprintf(stderr, "FATAL input initialization error\n"); ++ goto end; ++ } ++ ++ if (!out) ++ { ++ fprintf(stderr, "FATAL output initialization error\n"); ++ goto end; ++ } ++ ++ if (!cmac_test(cipher, out, in, mode, ++ Klen_counts_keys, known_keylen)) ++ { ++ fprintf(stderr, "FATAL cmac file processing error\n"); ++ goto end; ++ } ++ else ++ ret = 0; ++ ++ end: ++ ++ if (in && (in != stdin)) ++ fclose(in); ++ if (out && (out != stdout)) ++ fclose(out); ++ ++ return ret; ++ ++ } ++ ++#define CMAC_TEST_MAXLINELEN 150000 ++ ++int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in, ++ int mode, int Klen_counts_keys, int known_keylen) ++ { ++ char *linebuf, *olinebuf, *p, *q; ++ char *keyword, *value; ++ unsigned char **Keys = NULL, *Msg = NULL, *Mac = NULL; ++ unsigned char *Key = NULL; ++ int Count, Klen, Mlen, Tlen; ++ long Keylen, Msglen, Maclen; ++ int ret = 0; ++ int lnum = 0; ++ ++ olinebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN); ++ linebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN); ++ ++ if (!linebuf || !olinebuf) ++ goto error; ++ ++ Count = -1; ++ Klen = -1; ++ Mlen = -1; ++ Tlen = -1; ++ ++ while (fgets(olinebuf, CMAC_TEST_MAXLINELEN, in)) ++ { ++ lnum++; ++ strcpy(linebuf, olinebuf); ++ keyword = linebuf; ++ /* Skip leading space */ ++ while (isspace((unsigned char)*keyword)) ++ keyword++; ++ ++ /* Skip comments */ ++ if (keyword[0] == '#') ++ { ++ if (fputs(olinebuf, out) < 0) ++ goto error; ++ continue; ++ } ++ ++ /* Look for = sign */ ++ p = strchr(linebuf, '='); ++ ++ /* If no = or starts with [ (for [L=20] line) just copy */ ++ if (!p) ++ { ++ if (fputs(olinebuf, out) < 0) ++ goto error; ++ continue; ++ } ++ ++ q = p - 1; ++ ++ /* Remove trailing space */ ++ while (isspace((unsigned char)*q)) ++ *q-- = 0; ++ ++ *p = 0; ++ value = p + 1; ++ ++ /* Remove leading space from value */ ++ while (isspace((unsigned char)*value)) ++ value++; ++ ++ /* Remove trailing space from value */ ++ p = value + strlen(value) - 1; ++ ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ ++ if (!strcmp(keyword, "Count")) ++ { ++ if (Count != -1) ++ goto parse_error; ++ Count = atoi(value); ++ if (Count < 0) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Klen")) ++ { ++ if (Klen != -1) ++ goto parse_error; ++ Klen = atoi(value); ++ if (Klen < 0) ++ goto parse_error; ++ if (Klen_counts_keys) ++ { ++ Keys = OPENSSL_malloc(sizeof(*Keys) * Klen); ++ memset(Keys, '\0', sizeof(*Keys) * Klen); ++ } ++ else ++ { ++ Keys = OPENSSL_malloc(sizeof(*Keys)); ++ memset(Keys, '\0', sizeof(*Keys)); ++ } ++ } ++ else if (!strcmp(keyword, "Mlen")) ++ { ++ if (Mlen != -1) ++ goto parse_error; ++ Mlen = atoi(value); ++ if (Mlen < 0) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Tlen")) ++ { ++ if (Tlen != -1) ++ goto parse_error; ++ Tlen = atoi(value); ++ if (Tlen < 0) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Key") && !Klen_counts_keys) ++ { ++ if (Keys[0]) ++ goto parse_error; ++ Keys[0] = hex2bin_m(value, &Keylen); ++ if (!Keys[0]) ++ goto parse_error; ++ } ++ else if (!strncmp(keyword, "Key", 3) && Klen_counts_keys) ++ { ++ int keynum = atoi(keyword + 3); ++ if (!keynum || keynum > Klen || Keys[keynum-1]) ++ goto parse_error; ++ Keys[keynum-1] = hex2bin_m(value, &Keylen); ++ if (!Keys[keynum-1]) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Msg")) ++ { ++ if (Msg) ++ goto parse_error; ++ Msg = hex2bin_m(value, &Msglen); ++ if (!Msg) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Mac")) ++ { ++ if (mode == 0) ++ continue; ++ if (Mac) ++ goto parse_error; ++ Mac = hex2bin_m(value, &Maclen); ++ if (!Mac) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Result")) ++ { ++ if (mode == 1) ++ continue; ++ goto parse_error; ++ } ++ else ++ goto parse_error; ++ ++ fputs(olinebuf, out); ++ ++ if (Keys && Msg && (!mode || Mac) && (Tlen > 0) && (Klen > 0)) ++ { ++ if (Klen_counts_keys) ++ { ++ int x; ++ Key = OPENSSL_malloc(Klen * known_keylen); ++ for (x = 0; x < Klen; x++) ++ { ++ memcpy(Key + x * known_keylen, ++ Keys[x], known_keylen); ++ OPENSSL_free(Keys[x]); ++ } ++ Klen *= known_keylen; ++ } ++ else ++ { ++ Key = OPENSSL_malloc(Klen); ++ memcpy(Key, Keys[0], Klen); ++ OPENSSL_free(Keys[0]); ++ } ++ OPENSSL_free(Keys); ++ ++ switch(mode) ++ { ++ case 0: ++ if (!print_cmac_gen(cipher, out, ++ Key, Klen, ++ Msg, Mlen, ++ Tlen)) ++ goto error; ++ break; ++ case 1: ++ if (!print_cmac_ver(cipher, out, ++ Key, Klen, ++ Msg, Mlen, ++ Mac, Maclen, ++ Tlen)) ++ goto error; ++ break; ++ } ++ ++ OPENSSL_free(Key); ++ Key = NULL; ++ OPENSSL_free(Msg); ++ Msg = NULL; ++ OPENSSL_free(Mac); ++ Mac = NULL; ++ Klen = -1; ++ Mlen = -1; ++ Tlen = -1; ++ Count = -1; ++ } ++ } ++ ++ ++ ret = 1; ++ ++ ++ error: ++ ++ if (olinebuf) ++ OPENSSL_free(olinebuf); ++ if (linebuf) ++ OPENSSL_free(linebuf); ++ if (Key) ++ OPENSSL_free(Key); ++ if (Msg) ++ OPENSSL_free(Msg); ++ if (Mac) ++ OPENSSL_free(Mac); ++ ++ return ret; ++ ++ parse_error: ++ ++ fprintf(stderr, "FATAL parse error processing line %d\n", lnum); ++ ++ goto error; ++ ++ } ++ ++static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out, ++ unsigned char *Key, int Klen, ++ unsigned char *Msg, int Mlen, ++ int Tlen) ++ { ++ int rc, i; ++ size_t reslen; ++ unsigned char res[128]; ++ CMAC_CTX *cmac_ctx = CMAC_CTX_new(); ++ ++ CMAC_Init(cmac_ctx, Key, Klen, cipher, 0); ++ CMAC_Update(cmac_ctx, Msg, Mlen); ++ if (!CMAC_Final(cmac_ctx, res, &reslen)) ++ { ++ fputs("Error calculating CMAC\n", stderr); ++ rc = 0; ++ } ++ else if (Tlen > (int)reslen) ++ { ++ fputs("Parameter error, Tlen > CMAC length\n", stderr); ++ rc = 0; ++ } ++ else ++ { ++ fputs("Mac = ", out); ++ for (i = 0; i < Tlen; i++) ++ fprintf(out, "%02x", res[i]); ++ fputs(RESP_EOL, out); ++ rc = 1; ++ } ++ CMAC_CTX_free(cmac_ctx); ++ return rc; ++ } ++ ++static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out, ++ unsigned char *Key, int Klen, ++ unsigned char *Msg, int Mlen, ++ unsigned char *Mac, int Maclen, ++ int Tlen) ++ { ++ int rc = 1; ++ size_t reslen; ++ unsigned char res[128]; ++ CMAC_CTX *cmac_ctx = CMAC_CTX_new(); ++ ++ CMAC_Init(cmac_ctx, Key, Klen, cipher, 0); ++ CMAC_Update(cmac_ctx, Msg, Mlen); ++ if (!CMAC_Final(cmac_ctx, res, &reslen)) ++ { ++ fputs("Error calculating CMAC\n", stderr); ++ rc = 0; ++ } ++ else if (Tlen > (int)reslen) ++ { ++ fputs("Parameter error, Tlen > CMAC length\n", stderr); ++ rc = 0; ++ } ++ else if (Tlen != Maclen) ++ { ++ fputs("Parameter error, Tlen != resulting Mac length\n", stderr); ++ rc = 0; ++ } ++ else ++ { ++ if (!memcmp(Mac, res, Maclen)) ++ fputs("Result = P" RESP_EOL, out); ++ else ++ fputs("Result = F" RESP_EOL, out); ++ } ++ CMAC_CTX_free(cmac_ctx); ++ return rc; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_desmovs.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_desmovs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_desmovs.c.fips 2013-10-04 11:48:04.180694136 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_desmovs.c 2013-10-04 11:48:04.180694136 +0200 +@@ -0,0 +1,702 @@ ++/* ==================================================================== ++ * Copyright (c) 2004 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++/*--------------------------------------------- ++ NIST DES Modes of Operation Validation System ++ Test Program ++ ++ Based on the AES Validation Suite, which was: ++ Donated to OpenSSL by: ++ V-ONE Corporation ++ 20250 Century Blvd, Suite 300 ++ Germantown, MD 20874 ++ U.S.A. ++ ----------------------------------------------*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "e_os.h" ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS DES support\n"); ++ return(0); ++} ++ ++#else ++ ++#include ++#include "fips_utl.h" ++ ++#define DES_BLOCK_SIZE 8 ++ ++#define VERBOSE 0 ++ ++int DESTest(EVP_CIPHER_CTX *ctx, ++ char *amode, int akeysz, unsigned char *aKey, ++ unsigned char *iVec, ++ int dir, /* 0 = decrypt, 1 = encrypt */ ++ unsigned char *out, unsigned char *in, int len) ++ { ++ const EVP_CIPHER *cipher = NULL; ++ ++ if (akeysz != 192) ++ { ++ printf("Invalid key size: %d\n", akeysz); ++ EXIT(1); ++ } ++ ++ if (strcasecmp(amode, "CBC") == 0) ++ cipher = EVP_des_ede3_cbc(); ++ else if (strcasecmp(amode, "ECB") == 0) ++ cipher = EVP_des_ede3_ecb(); ++ else if (strcasecmp(amode, "CFB64") == 0) ++ cipher = EVP_des_ede3_cfb64(); ++ else if (strncasecmp(amode, "OFB", 3) == 0) ++ cipher = EVP_des_ede3_ofb(); ++ else if(!strcasecmp(amode,"CFB8")) ++ cipher = EVP_des_ede3_cfb8(); ++ else if(!strcasecmp(amode,"CFB1")) ++ cipher = EVP_des_ede3_cfb1(); ++ else ++ { ++ printf("Unknown mode: %s\n", amode); ++ EXIT(1); ++ } ++ ++ if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0) ++ return 0; ++ if(!strcasecmp(amode,"CFB1")) ++ M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS); ++ EVP_Cipher(ctx, out, in, len); ++ ++ return 1; ++ } ++ ++void DebugValue(char *tag, unsigned char *val, int len) ++ { ++ char obuf[2048]; ++ int olen; ++ olen = bin2hex(val, len, obuf); ++ printf("%s = %.*s\n", tag, olen, obuf); ++ } ++ ++void shiftin(unsigned char *dst,unsigned char *src,int nbits) ++ { ++ int n; ++ ++ /* move the bytes... */ ++ memmove(dst,dst+nbits/8,3*8-nbits/8); ++ /* append new data */ ++ memcpy(dst+3*8-nbits/8,src,(nbits+7)/8); ++ /* left shift the bits */ ++ if(nbits%8) ++ for(n=0 ; n < 3*8 ; ++n) ++ dst[n]=(dst[n] << (nbits%8))|(dst[n+1] >> (8-nbits%8)); ++ } ++ ++/*-----------------------------------------------*/ ++char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"}; ++char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"}; ++enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64}; ++int Sizes[6]={64,64,64,1,8,64}; ++ ++void do_mct(char *amode, ++ int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec, ++ int dir, unsigned char *text, int len, ++ FILE *rfp) ++ { ++ int i,imode; ++ unsigned char nk[4*8]; /* longest key+8 */ ++ unsigned char text0[8]; ++ ++ for (imode=0 ; imode < 6 ; ++imode) ++ if(!strcmp(amode,t_mode[imode])) ++ break; ++ if (imode == 6) ++ { ++ printf("Unrecognized mode: %s\n", amode); ++ EXIT(1); ++ } ++ ++ for(i=0 ; i < 400 ; ++i) ++ { ++ int j; ++ int n; ++ int kp=akeysz/64; ++ unsigned char old_iv[8]; ++ EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX_init(&ctx); ++ ++ fprintf(rfp,"\nCOUNT = %d\n",i); ++ if(kp == 1) ++ OutputValue("KEY",akey,8,rfp,0); ++ else ++ for(n=0 ; n < kp ; ++n) ++ { ++ fprintf(rfp,"KEY%d",n+1); ++ OutputValue("",akey+n*8,8,rfp,0); ++ } ++ ++ if(imode != ECB) ++ OutputValue("IV",ivec,8,rfp,0); ++ OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1); ++#if 0 ++ /* compensate for endianness */ ++ if(imode == CFB1) ++ text[0]<<=7; ++#endif ++ memcpy(text0,text,8); ++ ++ for(j=0 ; j < 10000 ; ++j) ++ { ++ unsigned char old_text[8]; ++ ++ memcpy(old_text,text,8); ++ if(j == 0) ++ { ++ memcpy(old_iv,ivec,8); ++ DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len); ++ } ++ else ++ { ++ memcpy(old_iv,ctx.iv,8); ++ EVP_Cipher(&ctx,text,text,len); ++ } ++ if(j == 9999) ++ { ++ OutputValue(t_tag[dir],text,len,rfp,imode == CFB1); ++ /* memcpy(ivec,text,8); */ ++ } ++ /* DebugValue("iv",ctx.iv,8); */ ++ /* accumulate material for the next key */ ++ shiftin(nk,text,Sizes[imode]); ++ /* DebugValue("nk",nk,24);*/ ++ if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64 ++ || imode == CBC)) || imode == OFB) ++ memcpy(text,old_iv,8); ++ ++ if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64)) ++ { ++ /* the test specifies using the output of the raw DES operation ++ which we don't have, so reconstruct it... */ ++ for(n=0 ; n < 8 ; ++n) ++ text[n]^=old_text[n]; ++ } ++ } ++ for(n=0 ; n < 8 ; ++n) ++ akey[n]^=nk[16+n]; ++ for(n=0 ; n < 8 ; ++n) ++ akey[8+n]^=nk[8+n]; ++ for(n=0 ; n < 8 ; ++n) ++ akey[16+n]^=nk[n]; ++ if(numkeys < 3) ++ memcpy(&akey[2*8],akey,8); ++ if(numkeys < 2) ++ memcpy(&akey[8],akey,8); ++ DES_set_odd_parity((DES_cblock *)akey); ++ DES_set_odd_parity((DES_cblock *)(akey+8)); ++ DES_set_odd_parity((DES_cblock *)(akey+16)); ++ memcpy(ivec,ctx.iv,8); ++ ++ /* pointless exercise - the final text doesn't depend on the ++ initial text in OFB mode, so who cares what it is? (Who ++ designed these tests?) */ ++ if(imode == OFB) ++ for(n=0 ; n < 8 ; ++n) ++ text[n]=text0[n]^old_iv[n]; ++ } ++ } ++ ++int proc_file(char *rqfile, char *rspfile) ++ { ++ char afn[256], rfn[256]; ++ FILE *afp = NULL, *rfp = NULL; ++ char ibuf[2048], tbuf[2048]; ++ int ilen, len, ret = 0; ++ char amode[8] = ""; ++ char atest[100] = ""; ++ int akeysz=0; ++ unsigned char iVec[20], aKey[40]; ++ int dir = -1, err = 0, step = 0; ++ unsigned char plaintext[2048]; ++ unsigned char ciphertext[2048]; ++ char *rp; ++ EVP_CIPHER_CTX ctx; ++ int numkeys=1; ++ EVP_CIPHER_CTX_init(&ctx); ++ ++ if (!rqfile || !(*rqfile)) ++ { ++ printf("No req file\n"); ++ return -1; ++ } ++ strcpy(afn, rqfile); ++ ++ if ((afp = fopen(afn, "r")) == NULL) ++ { ++ printf("Cannot open file: %s, %s\n", ++ afn, strerror(errno)); ++ return -1; ++ } ++ if (!rspfile) ++ { ++ strcpy(rfn,afn); ++ rp=strstr(rfn,"req/"); ++#ifdef OPENSSL_SYS_WIN32 ++ if (!rp) ++ rp=strstr(rfn,"req\\"); ++#endif ++ assert(rp); ++ memcpy(rp,"rsp",3); ++ rp = strstr(rfn, ".req"); ++ memcpy(rp, ".rsp", 4); ++ rspfile = rfn; ++ } ++ if ((rfp = fopen(rspfile, "w")) == NULL) ++ { ++ printf("Cannot open file: %s, %s\n", ++ rfn, strerror(errno)); ++ fclose(afp); ++ afp = NULL; ++ return -1; ++ } ++ while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL) ++ { ++ tidy_line(tbuf, ibuf); ++ ilen = strlen(ibuf); ++ /* printf("step=%d ibuf=%s",step,ibuf);*/ ++ if(step == 3 && !strcmp(amode,"ECB")) ++ { ++ memset(iVec, 0, sizeof(iVec)); ++ step = (dir)? 4: 5; /* no ivec for ECB */ ++ } ++ switch (step) ++ { ++ case 0: /* read preamble */ ++ if (ibuf[0] == '\n') ++ { /* end of preamble */ ++ if (*amode == '\0') ++ { ++ printf("Missing Mode\n"); ++ err = 1; ++ } ++ else ++ { ++ fputs(ibuf, rfp); ++ ++ step; ++ } ++ } ++ else if (ibuf[0] != '#') ++ { ++ printf("Invalid preamble item: %s\n", ibuf); ++ err = 1; ++ } ++ else ++ { /* process preamble */ ++ char *xp, *pp = ibuf+2; ++ int n; ++ if(*amode) ++ { /* insert current time & date */ ++ time_t rtim = time(0); ++ fprintf(rfp, "# %s", ctime(&rtim)); ++ } ++ else ++ { ++ fputs(ibuf, rfp); ++ if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4) ++ || !strncmp(pp,"TDES ",5) ++ || !strncmp(pp,"PERMUTATION ",12) ++ || !strncmp(pp,"SUBSTITUTION ",13) ++ || !strncmp(pp,"VARIABLE ",9)) ++ { ++ /* get test type */ ++ if(!strncmp(pp,"DES ",4)) ++ pp+=4; ++ else if(!strncmp(pp,"TDES ",5)) ++ pp+=5; ++ xp = strchr(pp, ' '); ++ n = xp-pp; ++ strncpy(atest, pp, n); ++ atest[n] = '\0'; ++ /* get mode */ ++ xp = strrchr(pp, ' '); /* get mode" */ ++ n = strlen(xp+1)-1; ++ strncpy(amode, xp+1, n); ++ amode[n] = '\0'; ++ /* amode[3] = '\0'; */ ++ if (VERBOSE) ++ printf("Test=%s, Mode=%s\n",atest,amode); ++ } ++ } ++ } ++ break; ++ ++ case 1: /* [ENCRYPT] | [DECRYPT] */ ++ if(ibuf[0] == '\n') ++ break; ++ if (ibuf[0] == '[') ++ { ++ fputs(ibuf, rfp); ++ ++step; ++ if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0) ++ dir = 1; ++ else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0) ++ dir = 0; ++ else ++ { ++ printf("Invalid keyword: %s\n", ibuf); ++ err = 1; ++ } ++ break; ++ } ++ else if (dir == -1) ++ { ++ err = 1; ++ printf("Missing ENCRYPT/DECRYPT keyword\n"); ++ break; ++ } ++ else ++ step = 2; ++ ++ case 2: /* KEY = xxxx */ ++ if(*ibuf == '\n') ++ { ++ fputs(ibuf, rfp); ++ break; ++ } ++ if(!strncasecmp(ibuf,"COUNT = ",8)) ++ { ++ fputs(ibuf, rfp); ++ break; ++ } ++ if(!strncasecmp(ibuf,"COUNT=",6)) ++ { ++ fputs(ibuf, rfp); ++ break; ++ } ++ if(!strncasecmp(ibuf,"NumKeys = ",10)) ++ { ++ numkeys=atoi(ibuf+10); ++ break; ++ } ++ ++ fputs(ibuf, rfp); ++ if(!strncasecmp(ibuf,"KEY = ",6)) ++ { ++ akeysz=64; ++ len = hex2bin((char*)ibuf+6, aKey); ++ if (len < 0) ++ { ++ printf("Invalid KEY\n"); ++ err=1; ++ break; ++ } ++ PrintValue("KEY", aKey, len); ++ ++step; ++ } ++ else if(!strncasecmp(ibuf,"KEYs = ",7)) ++ { ++ akeysz=64*3; ++ len=hex2bin(ibuf+7,aKey); ++ if(len != 8) ++ { ++ printf("Invalid KEY\n"); ++ err=1; ++ break; ++ } ++ memcpy(aKey+8,aKey,8); ++ memcpy(aKey+16,aKey,8); ++ ibuf[4]='\0'; ++ PrintValue("KEYs",aKey,len); ++ ++step; ++ } ++ else if(!strncasecmp(ibuf,"KEY",3)) ++ { ++ int n=ibuf[3]-'1'; ++ ++ akeysz=64*3; ++ len=hex2bin(ibuf+7,aKey+n*8); ++ if(len != 8) ++ { ++ printf("Invalid KEY\n"); ++ err=1; ++ break; ++ } ++ ibuf[4]='\0'; ++ PrintValue(ibuf,aKey,len); ++ if(n == 2) ++ ++step; ++ } ++ else ++ { ++ printf("Missing KEY\n"); ++ err = 1; ++ } ++ break; ++ ++ case 3: /* IV = xxxx */ ++ fputs(ibuf, rfp); ++ if (strncasecmp(ibuf, "IV = ", 5) != 0) ++ { ++ printf("Missing IV\n"); ++ err = 1; ++ } ++ else ++ { ++ len = hex2bin((char*)ibuf+5, iVec); ++ if (len < 0) ++ { ++ printf("Invalid IV\n"); ++ err =1; ++ break; ++ } ++ PrintValue("IV", iVec, len); ++ step = (dir)? 4: 5; ++ } ++ break; ++ ++ case 4: /* PLAINTEXT = xxxx */ ++ fputs(ibuf, rfp); ++ if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0) ++ { ++ printf("Missing PLAINTEXT\n"); ++ err = 1; ++ } ++ else ++ { ++ int nn = strlen(ibuf+12); ++ if(!strcmp(amode,"CFB1")) ++ len=bint2bin(ibuf+12,nn-1,plaintext); ++ else ++ len=hex2bin(ibuf+12, plaintext); ++ if (len < 0) ++ { ++ printf("Invalid PLAINTEXT: %s", ibuf+12); ++ err =1; ++ break; ++ } ++ if (len >= sizeof(plaintext)) ++ { ++ printf("Buffer overflow\n"); ++ } ++ PrintValue("PLAINTEXT", (unsigned char*)plaintext, len); ++ if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ ++ { ++ do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp); ++ } ++ else ++ { ++ assert(dir == 1); ++ ret = DESTest(&ctx, amode, akeysz, aKey, iVec, ++ dir, /* 0 = decrypt, 1 = encrypt */ ++ ciphertext, plaintext, len); ++ OutputValue("CIPHERTEXT",ciphertext,len,rfp, ++ !strcmp(amode,"CFB1")); ++ } ++ step = 6; ++ } ++ break; ++ ++ case 5: /* CIPHERTEXT = xxxx */ ++ fputs(ibuf, rfp); ++ if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0) ++ { ++ printf("Missing KEY\n"); ++ err = 1; ++ } ++ else ++ { ++ if(!strcmp(amode,"CFB1")) ++ len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext); ++ else ++ len = hex2bin(ibuf+13,ciphertext); ++ if (len < 0) ++ { ++ printf("Invalid CIPHERTEXT\n"); ++ err =1; ++ break; ++ } ++ ++ PrintValue("CIPHERTEXT", ciphertext, len); ++ if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */ ++ { ++ do_mct(amode, akeysz, numkeys, aKey, iVec, ++ dir, ciphertext, len, rfp); ++ } ++ else ++ { ++ assert(dir == 0); ++ ret = DESTest(&ctx, amode, akeysz, aKey, iVec, ++ dir, /* 0 = decrypt, 1 = encrypt */ ++ plaintext, ciphertext, len); ++ OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp, ++ !strcmp(amode,"CFB1")); ++ } ++ step = 6; ++ } ++ break; ++ ++ case 6: ++ if (ibuf[0] != '\n') ++ { ++ err = 1; ++ printf("Missing terminator\n"); ++ } ++ else if (strcmp(atest, "MCT") != 0) ++ { /* MCT already added terminating nl */ ++ fputs(ibuf, rfp); ++ } ++ step = 1; ++ break; ++ } ++ } ++ if (rfp) ++ fclose(rfp); ++ if (afp) ++ fclose(afp); ++ return err; ++ } ++ ++/*-------------------------------------------------- ++ Processes either a single file or ++ a set of files whose names are passed in a file. ++ A single file is specified as: ++ aes_test -f xxx.req ++ A set of files is specified as: ++ aes_test -d xxxxx.xxx ++ The default is: -d req.txt ++--------------------------------------------------*/ ++int main(int argc, char **argv) ++ { ++ char *rqlist = "req.txt", *rspfile = NULL; ++ FILE *fp = NULL; ++ char fn[250] = "", rfn[256] = ""; ++ int f_opt = 0, d_opt = 1; ++ ++#ifdef OPENSSL_FIPS ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ EXIT(1); ++ } ++#endif ++ if (argc > 1) ++ { ++ if (strcasecmp(argv[1], "-d") == 0) ++ { ++ d_opt = 1; ++ } ++ else if (strcasecmp(argv[1], "-f") == 0) ++ { ++ f_opt = 1; ++ d_opt = 0; ++ } ++ else ++ { ++ printf("Invalid parameter: %s\n", argv[1]); ++ return 0; ++ } ++ if (argc < 3) ++ { ++ printf("Missing parameter\n"); ++ return 0; ++ } ++ if (d_opt) ++ rqlist = argv[2]; ++ else ++ { ++ strcpy(fn, argv[2]); ++ rspfile = argv[3]; ++ } ++ } ++ if (d_opt) ++ { /* list of files (directory) */ ++ if (!(fp = fopen(rqlist, "r"))) ++ { ++ printf("Cannot open req list file\n"); ++ return -1; ++ } ++ while (fgets(fn, sizeof(fn), fp)) ++ { ++ strtok(fn, "\r\n"); ++ strcpy(rfn, fn); ++ printf("Processing: %s\n", rfn); ++ if (proc_file(rfn, rspfile)) ++ { ++ printf(">>> Processing failed for: %s <<<\n", rfn); ++ EXIT(1); ++ } ++ } ++ fclose(fp); ++ } ++ else /* single file */ ++ { ++ if (VERBOSE) ++ printf("Processing: %s\n", fn); ++ if (proc_file(fn, rspfile)) ++ { ++ printf(">>> Processing failed for: %s <<<\n", fn); ++ } ++ } ++ EXIT(0); ++ return 0; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_dhvs.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_dhvs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_dhvs.c.fips 2013-10-04 11:48:04.180694136 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_dhvs.c 2013-10-04 11:48:04.180694136 +0200 +@@ -0,0 +1,292 @@ ++/* fips/dh/fips_dhvs.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++ ++#define OPENSSL_FIPSAPI ++#include ++ ++#ifndef OPENSSL_FIPS ++#include ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS DH support\n"); ++ return(0); ++} ++#else ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fips_utl.h" ++ ++static const EVP_MD *parse_md(char *line) ++ { ++ char *p; ++ if (line[0] != '[' || line[1] != 'F') ++ return NULL; ++ p = strchr(line, '-'); ++ if (!p) ++ return NULL; ++ line = p + 1; ++ p = strchr(line, ']'); ++ if (!p) ++ return NULL; ++ *p = 0; ++ p = line; ++ while(isspace(*p)) ++ p++; ++ if (!strcmp(p, "SHA1")) ++ return EVP_sha1(); ++ else if (!strcmp(p, "SHA224")) ++ return EVP_sha224(); ++ else if (!strcmp(p, "SHA256")) ++ return EVP_sha256(); ++ else if (!strcmp(p, "SHA384")) ++ return EVP_sha384(); ++ else if (!strcmp(p, "SHA512")) ++ return EVP_sha512(); ++ else ++ return NULL; ++ } ++ ++static void output_Zhash(FILE *out, int exout, ++ DH *dh, BIGNUM *peerkey, const EVP_MD *md, ++ unsigned char *rhash, size_t rhashlen) ++ { ++ unsigned char *Z; ++ unsigned char chash[EVP_MAX_MD_SIZE]; ++ int Zlen; ++ if (rhash == NULL) ++ { ++ rhashlen = M_EVP_MD_size(md); ++ if (!DH_generate_key(dh)) ++ exit (1); ++ do_bn_print_name(out, "YephemIUT", dh->pub_key); ++ if (exout) ++ do_bn_print_name(out, "XephemIUT", dh->priv_key); ++ } ++ Z = OPENSSL_malloc(BN_num_bytes(dh->p)); ++ if (!Z) ++ exit(1); ++ Zlen = DH_compute_key_padded(Z, peerkey, dh); ++ 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 ++ { ++ BN_clear_free(dh->priv_key); ++ BN_clear_free(dh->pub_key); ++ dh->priv_key = NULL; ++ dh->pub_key = NULL; ++ } ++ OPENSSL_cleanse(Z, Zlen); ++ OPENSSL_free(Z); ++ } ++ ++#ifdef FIPS_ALGVS ++int fips_dhvs_main(int argc, char **argv) ++#else ++int main(int argc, char **argv) ++#endif ++ { ++ char **args = argv + 1; ++ int argn = argc - 1; ++ FILE *in, *out; ++ char buf[2048], lbuf[2048]; ++ unsigned char *rhash; ++ long rhashlen; ++ DH *dh = NULL; ++ const EVP_MD *md = NULL; ++ BIGNUM *peerkey = NULL; ++ char *keyword = NULL, *value = NULL; ++ int do_verify = -1, exout = 0; ++ ++ fips_algtest_init(); ++ ++ if (argn && !strcmp(*args, "dhver")) ++ { ++ do_verify = 1; ++ args++; ++ argn--; ++ } ++ else if (argn && !strcmp(*args, "dhgen")) ++ { ++ do_verify = 0; ++ args++; ++ argn--; ++ } ++ ++ if (argn && !strcmp(*args, "-exout")) ++ { ++ exout = 1; ++ args++; ++ argn--; ++ } ++ ++ if (do_verify == -1) ++ { ++ fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]); ++ exit(1); ++ } ++ ++ if (argn == 2) ++ { ++ in = fopen(*args, "r"); ++ if (!in) ++ { ++ fprintf(stderr, "Error opening input file\n"); ++ exit(1); ++ } ++ out = fopen(args[1], "w"); ++ if (!out) ++ { ++ fprintf(stderr, "Error opening output file\n"); ++ exit(1); ++ } ++ } ++ else if (argn == 0) ++ { ++ in = stdin; ++ out = stdout; ++ } ++ else ++ { ++ fprintf(stderr,"%s [dhver|dhgen|] [-exout] (infile outfile)\n",argv[0]); ++ exit(1); ++ } ++ ++ dh = FIPS_dh_new(); ++ ++ while (fgets(buf, sizeof(buf), in) != NULL) ++ { ++ fputs(buf, out); ++ if (strlen(buf) > 6 && !strncmp(buf, "[F", 2)) ++ { ++ md = parse_md(buf); ++ if (md == NULL) ++ goto parse_error; ++ if (dh) ++ FIPS_dh_free(dh); ++ dh = FIPS_dh_new(); ++ continue; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if (!strcmp(keyword, "P")) ++ { ++ if (!do_hex2bn(&dh->p, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Q")) ++ { ++ if (!do_hex2bn(&dh->q, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "G")) ++ { ++ if (!do_hex2bn(&dh->g, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "XephemIUT")) ++ { ++ if (!do_hex2bn(&dh->priv_key, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "YephemIUT")) ++ { ++ if (!do_hex2bn(&dh->pub_key, value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "YephemCAVS")) ++ { ++ if (!do_hex2bn(&peerkey, value)) ++ goto parse_error; ++ if (do_verify == 0) ++ output_Zhash(out, exout, dh, peerkey, md, ++ NULL, 0); ++ } ++ else if (!strcmp(keyword, "CAVSHashZZ")) ++ { ++ if (!md) ++ goto parse_error; ++ rhash = hex2bin_m(value, &rhashlen); ++ if (!rhash || rhashlen != M_EVP_MD_size(md)) ++ goto parse_error; ++ output_Zhash(out, exout, dh, peerkey, md, ++ rhash, rhashlen); ++ } ++ } ++ if (in && in != stdin) ++ fclose(in); ++ if (out && out != stdout) ++ fclose(out); ++ return 0; ++ parse_error: ++ fprintf(stderr, "Error Parsing request file\n"); ++ exit(1); ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_drbgvs.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_drbgvs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_drbgvs.c.fips 2013-10-04 11:48:04.180694136 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_drbgvs.c 2013-10-04 11:48:04.180694136 +0200 +@@ -0,0 +1,416 @@ ++/* fips/rand/fips_drbgvs.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++ ++#define OPENSSL_FIPSAPI ++#include ++ ++#ifndef OPENSSL_FIPS ++#include ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS DRBG support\n"); ++ return(0); ++} ++#else ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fips_utl.h" ++ ++static int dparse_md(char *str) ++ { ++ switch(atoi(str + 5)) ++ { ++ case 1: ++ return NID_sha1; ++ ++ case 224: ++ return NID_sha224; ++ ++ case 256: ++ return NID_sha256; ++ ++ case 384: ++ return NID_sha384; ++ ++ case 512: ++ return NID_sha512; ++ ++ } ++ ++ return NID_undef; ++ } ++ ++static int parse_ec(char *str) ++ { ++ int curve_nid, md_nid; ++ char *md; ++ md = strchr(str, ' '); ++ if (!md) ++ return NID_undef; ++ if (!strncmp(str, "[P-256", 6)) ++ curve_nid = NID_X9_62_prime256v1; ++ else if (!strncmp(str, "[P-384", 6)) ++ curve_nid = NID_secp384r1; ++ else if (!strncmp(str, "[P-521", 6)) ++ curve_nid = NID_secp521r1; ++ else ++ return NID_undef; ++ md_nid = dparse_md(md); ++ if (md_nid == NID_undef) ++ return NID_undef; ++ return (curve_nid << 16) | md_nid; ++ } ++ ++static int parse_aes(char *str, int *pdf) ++ { ++ ++ if (!strncmp(str + 9, "no", 2)) ++ *pdf = 0; ++ else ++ *pdf = DRBG_FLAG_CTR_USE_DF; ++ ++ switch(atoi(str + 5)) ++ { ++ case 128: ++ return NID_aes_128_ctr; ++ ++ case 192: ++ return NID_aes_192_ctr; ++ ++ case 256: ++ return NID_aes_256_ctr; ++ ++ default: ++ return NID_undef; ++ ++ } ++ } ++ ++typedef struct ++ { ++ unsigned char *ent; ++ size_t entlen; ++ unsigned char *nonce; ++ size_t noncelen; ++ } TEST_ENT; ++ ++static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout, ++ int entropy, size_t min_len, size_t max_len) ++ { ++ TEST_ENT *t = FIPS_drbg_get_app_data(dctx); ++ *pout = (unsigned char *)t->ent; ++ return t->entlen; ++ } ++ ++static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout, ++ int entropy, size_t min_len, size_t max_len) ++ { ++ TEST_ENT *t = FIPS_drbg_get_app_data(dctx); ++ *pout = (unsigned char *)t->nonce; ++ return t->noncelen; ++ } ++ ++#ifdef FIPS_ALGVS ++int fips_drbgvs_main(int argc,char **argv) ++#else ++int main(int argc,char **argv) ++#endif ++ { ++ FILE *in = NULL, *out = NULL; ++ DRBG_CTX *dctx = NULL; ++ TEST_ENT t; ++ int r, nid = 0; ++ int pr = 0; ++ char buf[2048], lbuf[2048]; ++ unsigned char randout[2048]; ++ char *keyword = NULL, *value = NULL; ++ ++ unsigned char *ent = NULL, *nonce = NULL, *pers = NULL, *adin = NULL; ++ long entlen, noncelen, perslen, adinlen; ++ int df = 0; ++ ++ enum dtype { DRBG_NONE, DRBG_CTR, DRBG_HASH, DRBG_HMAC, DRBG_DUAL_EC } ++ drbg_type = DRBG_NONE; ++ ++ int randoutlen = 0; ++ ++ int gen = 0; ++ ++ fips_algtest_init(); ++ ++ if (argc == 3) ++ { ++ in = fopen(argv[1], "r"); ++ if (!in) ++ { ++ fprintf(stderr, "Error opening input file\n"); ++ exit(1); ++ } ++ out = fopen(argv[2], "w"); ++ if (!out) ++ { ++ fprintf(stderr, "Error opening output file\n"); ++ exit(1); ++ } ++ } ++ else if (argc == 1) ++ { ++ in = stdin; ++ out = stdout; ++ } ++ else ++ { ++ fprintf(stderr,"%s (infile outfile)\n",argv[0]); ++ exit(1); ++ } ++ ++ while (fgets(buf, sizeof(buf), in) != NULL) ++ { ++ fputs(buf, out); ++ if (drbg_type == DRBG_NONE) ++ { ++ if (strstr(buf, "CTR_DRBG")) ++ drbg_type = DRBG_CTR; ++ else if (strstr(buf, "Hash_DRBG")) ++ drbg_type = DRBG_HASH; ++ else if (strstr(buf, "HMAC_DRBG")) ++ drbg_type = DRBG_HMAC; ++ else if (strstr(buf, "Dual_EC_DRBG")) ++ drbg_type = DRBG_DUAL_EC; ++ else ++ continue; ++ } ++ if (strlen(buf) > 4 && !strncmp(buf, "[SHA-", 5)) ++ { ++ nid = dparse_md(buf); ++ if (nid == NID_undef) ++ exit(1); ++ if (drbg_type == DRBG_HMAC) ++ { ++ switch (nid) ++ { ++ case NID_sha1: ++ nid = NID_hmacWithSHA1; ++ break; ++ ++ case NID_sha224: ++ nid = NID_hmacWithSHA224; ++ break; ++ ++ case NID_sha256: ++ nid = NID_hmacWithSHA256; ++ break; ++ ++ case NID_sha384: ++ nid = NID_hmacWithSHA384; ++ break; ++ ++ case NID_sha512: ++ nid = NID_hmacWithSHA512; ++ break; ++ ++ default: ++ exit(1); ++ } ++ } ++ } ++ if (strlen(buf) > 12 && !strncmp(buf, "[AES-", 5)) ++ { ++ nid = parse_aes(buf, &df); ++ if (nid == NID_undef) ++ exit(1); ++ } ++ if (strlen(buf) > 12 && !strncmp(buf, "[P-", 3)) ++ { ++ nid = parse_ec(buf); ++ if (nid == NID_undef) ++ exit(1); ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ ++ if (!strcmp(keyword, "[PredictionResistance")) ++ { ++ if (!strcmp(value, "True]")) ++ pr = 1; ++ else if (!strcmp(value, "False]")) ++ pr = 0; ++ else ++ exit(1); ++ } ++ ++ if (!strcmp(keyword, "EntropyInput")) ++ { ++ ent = hex2bin_m(value, &entlen); ++ t.ent = ent; ++ t.entlen = entlen; ++ } ++ ++ if (!strcmp(keyword, "Nonce")) ++ { ++ nonce = hex2bin_m(value, &noncelen); ++ t.nonce = nonce; ++ t.noncelen = noncelen; ++ } ++ ++ if (!strcmp(keyword, "PersonalizationString")) ++ { ++ pers = hex2bin_m(value, &perslen); ++ if (nid == 0) ++ { ++ fprintf(stderr, "DRBG type not recognised!\n"); ++ exit (1); ++ } ++ dctx = FIPS_drbg_new(nid, df | DRBG_FLAG_TEST); ++ if (!dctx) ++ exit (1); ++ FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0, ++ test_nonce, 0); ++ FIPS_drbg_set_app_data(dctx, &t); ++ randoutlen = (int)FIPS_drbg_get_blocklength(dctx); ++ r = FIPS_drbg_instantiate(dctx, pers, perslen); ++ if (!r) ++ { ++ fprintf(stderr, "Error instantiating DRBG\n"); ++ exit(1); ++ } ++ OPENSSL_free(pers); ++ OPENSSL_free(ent); ++ OPENSSL_free(nonce); ++ ent = nonce = pers = NULL; ++ gen = 0; ++ } ++ ++ if (!strcmp(keyword, "AdditionalInput")) ++ { ++ adin = hex2bin_m(value, &adinlen); ++ if (pr) ++ continue; ++ r = FIPS_drbg_generate(dctx, randout, randoutlen, 0, ++ adin, adinlen); ++ if (!r) ++ { ++ fprintf(stderr, "Error generating DRBG bits\n"); ++ exit(1); ++ } ++ if (!r) ++ exit(1); ++ OPENSSL_free(adin); ++ adin = NULL; ++ gen++; ++ } ++ ++ if (pr) ++ { ++ if (!strcmp(keyword, "EntropyInputPR")) ++ { ++ ent = hex2bin_m(value, &entlen); ++ t.ent = ent; ++ t.entlen = entlen; ++ r = FIPS_drbg_generate(dctx, ++ randout, randoutlen, ++ 1, adin, adinlen); ++ if (!r) ++ { ++ fprintf(stderr, ++ "Error generating DRBG bits\n"); ++ exit(1); ++ } ++ OPENSSL_free(adin); ++ OPENSSL_free(ent); ++ adin = ent = NULL; ++ gen++; ++ } ++ } ++ if (!strcmp(keyword, "EntropyInputReseed")) ++ { ++ ent = hex2bin_m(value, &entlen); ++ t.ent = ent; ++ t.entlen = entlen; ++ } ++ if (!strcmp(keyword, "AdditionalInputReseed")) ++ { ++ adin = hex2bin_m(value, &adinlen); ++ FIPS_drbg_reseed(dctx, adin, adinlen); ++ OPENSSL_free(ent); ++ OPENSSL_free(adin); ++ ent = adin = NULL; ++ } ++ if (gen == 2) ++ { ++ OutputValue("ReturnedBits", randout, randoutlen, ++ out, 0); ++ FIPS_drbg_free(dctx); ++ dctx = NULL; ++ gen = 0; ++ } ++ ++ } ++ if (in && in != stdin) ++ fclose(in); ++ if (out && out != stdout) ++ fclose(out); ++ return 0; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_dssvs.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_dssvs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_dssvs.c.fips 2013-10-04 11:48:04.180694136 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_dssvs.c 2013-10-04 11:48:04.180694136 +0200 +@@ -0,0 +1,537 @@ ++#include ++ ++#ifndef OPENSSL_FIPS ++#include ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS DSA support\n"); ++ return(0); ++} ++#else ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fips_utl.h" ++ ++static void pbn(const char *name, BIGNUM *bn) ++ { ++ int len, i; ++ unsigned char *tmp; ++ len = BN_num_bytes(bn); ++ tmp = OPENSSL_malloc(len); ++ if (!tmp) ++ { ++ fprintf(stderr, "Memory allocation error\n"); ++ return; ++ } ++ BN_bn2bin(bn, tmp); ++ printf("%s = ", name); ++ for (i = 0; i < len; i++) ++ printf("%02X", tmp[i]); ++ fputs("\n", stdout); ++ OPENSSL_free(tmp); ++ return; ++ } ++ ++void primes() ++ { ++ char buf[10240]; ++ char lbuf[10240]; ++ char *keyword, *value; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ fputs(buf,stdout); ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if(!strcmp(keyword,"Prime")) ++ { ++ BIGNUM *pp; ++ ++ pp=BN_new(); ++ do_hex2bn(&pp,value); ++ printf("result= %c\n", ++ BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F'); ++ } ++ } ++ } ++ ++void pqg() ++ { ++ char buf[1024]; ++ char lbuf[1024]; ++ char *keyword, *value; ++ int nmod=0; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ { ++ fputs(buf,stdout); ++ continue; ++ } ++ if(!strcmp(keyword,"[mod")) ++ nmod=atoi(value); ++ else if(!strcmp(keyword,"N")) ++ { ++ int n=atoi(value); ++ ++ printf("[mod = %d]\n\n",nmod); ++ ++ while(n--) ++ { ++ unsigned char seed[20]; ++ DSA *dsa; ++ int counter; ++ unsigned long h; ++ dsa = FIPS_dsa_new(); ++ ++ if (!DSA_generate_parameters_ex(dsa, nmod,seed,0,&counter,&h,NULL)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ pbn("P",dsa->p); ++ pbn("Q",dsa->q); ++ pbn("G",dsa->g); ++ pv("Seed",seed,20); ++ printf("c = %d\n",counter); ++ printf("H = %lx\n",h); ++ putc('\n',stdout); ++ } ++ } ++ else ++ fputs(buf,stdout); ++ } ++ } ++ ++void pqgver() ++ { ++ char buf[1024]; ++ char lbuf[1024]; ++ char *keyword, *value; ++ BIGNUM *p = NULL, *q = NULL, *g = NULL; ++ int counter, counter2; ++ unsigned long h, h2; ++ DSA *dsa=NULL; ++ int nmod=0; ++ unsigned char seed[1024]; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ { ++ fputs(buf,stdout); ++ continue; ++ } ++ fputs(buf, stdout); ++ if(!strcmp(keyword,"[mod")) ++ nmod=atoi(value); ++ else if(!strcmp(keyword,"P")) ++ p=hex2bn(value); ++ else if(!strcmp(keyword,"Q")) ++ q=hex2bn(value); ++ else if(!strcmp(keyword,"G")) ++ g=hex2bn(value); ++ else if(!strcmp(keyword,"Seed")) ++ { ++ int slen = hex2bin(value, seed); ++ if (slen != 20) ++ { ++ fprintf(stderr, "Seed parse length error\n"); ++ exit (1); ++ } ++ } ++ else if(!strcmp(keyword,"c")) ++ counter =atoi(buf+4); ++ else if(!strcmp(keyword,"H")) ++ { ++ h = atoi(value); ++ if (!p || !q || !g) ++ { ++ fprintf(stderr, "Parse Error\n"); ++ exit (1); ++ } ++ dsa = FIPS_dsa_new(); ++ if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g) ++ || (counter != counter2) || (h != h2)) ++ printf("Result = F\n"); ++ else ++ printf("Result = P\n"); ++ BN_free(p); ++ BN_free(q); ++ BN_free(g); ++ p = NULL; ++ q = NULL; ++ g = NULL; ++ FIPS_dsa_free(dsa); ++ dsa = NULL; ++ } ++ } ++ } ++ ++/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2 ++ * algorithm tests. It is an additional test to perform sanity checks on the ++ * output of the KeyPair test. ++ */ ++ ++static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g, ++ BN_CTX *ctx) ++ { ++ BIGNUM *rem = NULL; ++ if (BN_num_bits(p) != nmod) ++ return 0; ++ if (BN_num_bits(q) != 160) ++ return 0; ++ if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1) ++ return 0; ++ if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1) ++ return 0; ++ rem = BN_new(); ++ if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem) ++ || (BN_cmp(g, BN_value_one()) <= 0) ++ || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) ++ { ++ BN_free(rem); ++ return 0; ++ } ++ /* Todo: check g */ ++ BN_free(rem); ++ return 1; ++ } ++ ++void keyver() ++ { ++ char buf[1024]; ++ char lbuf[1024]; ++ char *keyword, *value; ++ BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL; ++ BIGNUM *Y2; ++ BN_CTX *ctx = NULL; ++ int nmod=0, paramcheck = 0; ++ ++ ctx = BN_CTX_new(); ++ Y2 = BN_new(); ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ { ++ fputs(buf,stdout); ++ continue; ++ } ++ if(!strcmp(keyword,"[mod")) ++ { ++ if (p) ++ BN_free(p); ++ p = NULL; ++ if (q) ++ BN_free(q); ++ q = NULL; ++ if (g) ++ BN_free(g); ++ g = NULL; ++ paramcheck = 0; ++ nmod=atoi(value); ++ } ++ else if(!strcmp(keyword,"P")) ++ p=hex2bn(value); ++ else if(!strcmp(keyword,"Q")) ++ q=hex2bn(value); ++ else if(!strcmp(keyword,"G")) ++ g=hex2bn(value); ++ else if(!strcmp(keyword,"X")) ++ X=hex2bn(value); ++ else if(!strcmp(keyword,"Y")) ++ { ++ Y=hex2bn(value); ++ if (!p || !q || !g || !X || !Y) ++ { ++ fprintf(stderr, "Parse Error\n"); ++ exit (1); ++ } ++ pbn("P",p); ++ pbn("Q",q); ++ pbn("G",g); ++ pbn("X",X); ++ pbn("Y",Y); ++ if (!paramcheck) ++ { ++ if (dss_paramcheck(nmod, p, q, g, ctx)) ++ paramcheck = 1; ++ else ++ paramcheck = -1; ++ } ++ if (paramcheck != 1) ++ printf("Result = F\n"); ++ else ++ { ++ if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y)) ++ printf("Result = F\n"); ++ else ++ printf("Result = P\n"); ++ } ++ BN_free(X); ++ BN_free(Y); ++ X = NULL; ++ Y = NULL; ++ } ++ } ++ if (p) ++ BN_free(p); ++ if (q) ++ BN_free(q); ++ if (g) ++ BN_free(g); ++ if (Y2) ++ BN_free(Y2); ++ } ++ ++void keypair() ++ { ++ char buf[1024]; ++ char lbuf[1024]; ++ char *keyword, *value; ++ int nmod=0; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ { ++ fputs(buf,stdout); ++ continue; ++ } ++ if(!strcmp(keyword,"[mod")) ++ nmod=atoi(value); ++ else if(!strcmp(keyword,"N")) ++ { ++ DSA *dsa; ++ int n=atoi(value); ++ ++ printf("[mod = %d]\n\n",nmod); ++ dsa = FIPS_dsa_new(); ++ if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ pbn("P",dsa->p); ++ pbn("Q",dsa->q); ++ pbn("G",dsa->g); ++ putc('\n',stdout); ++ ++ while(n--) ++ { ++ if (!DSA_generate_key(dsa)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ ++ pbn("X",dsa->priv_key); ++ pbn("Y",dsa->pub_key); ++ putc('\n',stdout); ++ } ++ } ++ } ++ } ++ ++void siggen() ++ { ++ char buf[1024]; ++ char lbuf[1024]; ++ char *keyword, *value; ++ int nmod=0; ++ DSA *dsa=NULL; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ { ++ fputs(buf,stdout); ++ continue; ++ } ++ if(!strcmp(keyword,"[mod")) ++ { ++ nmod=atoi(value); ++ printf("[mod = %d]\n\n",nmod); ++ if (dsa) ++ FIPS_dsa_free(dsa); ++ dsa = FIPS_dsa_new(); ++ if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ pbn("P",dsa->p); ++ pbn("Q",dsa->q); ++ pbn("G",dsa->g); ++ putc('\n',stdout); ++ } ++ else if(!strcmp(keyword,"Msg")) ++ { ++ unsigned char msg[1024]; ++ unsigned char sbuf[60]; ++ unsigned int slen; ++ int n; ++ EVP_PKEY pk; ++ EVP_MD_CTX mctx; ++ DSA_SIG *sig; ++ EVP_MD_CTX_init(&mctx); ++ ++ n=hex2bin(value,msg); ++ pv("Msg",msg,n); ++ ++ if (!DSA_generate_key(dsa)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ pk.type = EVP_PKEY_DSA; ++ pk.pkey.dsa = dsa; ++ pbn("Y",dsa->pub_key); ++ ++ EVP_SignInit_ex(&mctx, EVP_dss1(), NULL); ++ EVP_SignUpdate(&mctx, msg, n); ++ EVP_SignFinal(&mctx, sbuf, &slen, &pk); ++ ++ sig = DSA_SIG_new(); ++ FIPS_dsa_sig_decode(sig, sbuf, slen); ++ ++ pbn("R",sig->r); ++ pbn("S",sig->s); ++ putc('\n',stdout); ++ DSA_SIG_free(sig); ++ EVP_MD_CTX_cleanup(&mctx); ++ } ++ } ++ if (dsa) ++ FIPS_dsa_free(dsa); ++ } ++ ++void sigver() ++ { ++ DSA *dsa=NULL; ++ char buf[1024]; ++ char lbuf[1024]; ++ unsigned char msg[1024]; ++ char *keyword, *value; ++ int nmod=0, n=0; ++ DSA_SIG sg, *sig = &sg; ++ ++ sig->r = NULL; ++ sig->s = NULL; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ { ++ fputs(buf,stdout); ++ continue; ++ } ++ if(!strcmp(keyword,"[mod")) ++ { ++ nmod=atoi(value); ++ if(dsa) ++ FIPS_dsa_free(dsa); ++ dsa=FIPS_dsa_new(); ++ } ++ else if(!strcmp(keyword,"P")) ++ dsa->p=hex2bn(value); ++ else if(!strcmp(keyword,"Q")) ++ dsa->q=hex2bn(value); ++ else if(!strcmp(keyword,"G")) ++ { ++ dsa->g=hex2bn(value); ++ ++ printf("[mod = %d]\n\n",nmod); ++ pbn("P",dsa->p); ++ pbn("Q",dsa->q); ++ pbn("G",dsa->g); ++ putc('\n',stdout); ++ } ++ else if(!strcmp(keyword,"Msg")) ++ { ++ n=hex2bin(value,msg); ++ pv("Msg",msg,n); ++ } ++ else if(!strcmp(keyword,"Y")) ++ dsa->pub_key=hex2bn(value); ++ else if(!strcmp(keyword,"R")) ++ sig->r=hex2bn(value); ++ else if(!strcmp(keyword,"S")) ++ { ++ EVP_MD_CTX mctx; ++ EVP_PKEY pk; ++ unsigned char sigbuf[60]; ++ unsigned int slen; ++ int r; ++ EVP_MD_CTX_init(&mctx); ++ pk.type = EVP_PKEY_DSA; ++ pk.pkey.dsa = dsa; ++ sig->s=hex2bn(value); ++ ++ pbn("Y",dsa->pub_key); ++ pbn("R",sig->r); ++ pbn("S",sig->s); ++ ++ slen = FIPS_dsa_sig_encode(sigbuf, sig); ++ EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL); ++ EVP_VerifyUpdate(&mctx, msg, n); ++ r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk); ++ EVP_MD_CTX_cleanup(&mctx); ++ ++ printf("Result = %c\n", r == 1 ? 'P' : 'F'); ++ putc('\n',stdout); ++ } ++ } ++ } ++ ++int main(int argc,char **argv) ++ { ++ if(argc != 2) ++ { ++ fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]); ++ exit(1); ++ } ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ if(!strcmp(argv[1],"prime")) ++ primes(); ++ else if(!strcmp(argv[1],"pqg")) ++ pqg(); ++ else if(!strcmp(argv[1],"pqgver")) ++ pqgver(); ++ else if(!strcmp(argv[1],"keypair")) ++ keypair(); ++ else if(!strcmp(argv[1],"keyver")) ++ keyver(); ++ else if(!strcmp(argv[1],"siggen")) ++ siggen(); ++ else if(!strcmp(argv[1],"sigver")) ++ sigver(); ++ else ++ { ++ fprintf(stderr,"Don't know how to %s.\n",argv[1]); ++ exit(1); ++ } ++ ++ return 0; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_gcmtest.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_gcmtest.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_gcmtest.c.fips 2013-10-04 11:48:04.181694158 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_gcmtest.c 2013-10-04 11:48:04.181694158 +0200 +@@ -0,0 +1,571 @@ ++/* fips/aes/fips_gcmtest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2011 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ */ ++ ++ ++#define OPENSSL_FIPSAPI ++#include ++ ++#ifndef OPENSSL_FIPS ++#include ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS GCM support\n"); ++ return(0); ++} ++#else ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fips_utl.h" ++ ++static void gcmtest(FILE *in, FILE *out, int encrypt) ++ { ++ char buf[2048]; ++ char lbuf[2048]; ++ char *keyword, *value; ++ int keylen = -1, ivlen = -1, aadlen = -1, taglen = -1, ptlen = -1; ++ int rv; ++ long l; ++ unsigned char *key = NULL, *iv = NULL, *aad = NULL, *tag = NULL; ++ unsigned char *ct = NULL, *pt = NULL; ++ EVP_CIPHER_CTX ctx; ++ const EVP_CIPHER *gcm = NULL; ++ FIPS_cipher_ctx_init(&ctx); ++ ++ while(fgets(buf,sizeof buf,in) != NULL) ++ { ++ fputs(buf,out); ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if(!strcmp(keyword,"[Keylen")) ++ { ++ keylen = atoi(value); ++ if (keylen == 128) ++ gcm = EVP_aes_128_gcm(); ++ else if (keylen == 192) ++ gcm = EVP_aes_192_gcm(); ++ else if (keylen == 256) ++ gcm = EVP_aes_256_gcm(); ++ else ++ { ++ fprintf(stderr, "Unsupported keylen %d\n", ++ keylen); ++ } ++ keylen >>= 3; ++ } ++ else if (!strcmp(keyword, "[IVlen")) ++ ivlen = atoi(value) >> 3; ++ else if (!strcmp(keyword, "[AADlen")) ++ aadlen = atoi(value) >> 3; ++ else if (!strcmp(keyword, "[Taglen")) ++ taglen = atoi(value) >> 3; ++ else if (!strcmp(keyword, "[PTlen")) ++ ptlen = atoi(value) >> 3; ++ else if(!strcmp(keyword,"Key")) ++ { ++ key = hex2bin_m(value, &l); ++ if (l != keylen) ++ { ++ fprintf(stderr, "Inconsistent Key length\n"); ++ exit(1); ++ } ++ } ++ else if(!strcmp(keyword,"IV")) ++ { ++ iv = hex2bin_m(value, &l); ++ if (l != ivlen) ++ { ++ fprintf(stderr, "Inconsistent IV length\n"); ++ exit(1); ++ } ++ } ++ else if(!strcmp(keyword,"PT")) ++ { ++ pt = hex2bin_m(value, &l); ++ if (l != ptlen) ++ { ++ fprintf(stderr, "Inconsistent PT length\n"); ++ exit(1); ++ } ++ } ++ else if(!strcmp(keyword,"CT")) ++ { ++ ct = hex2bin_m(value, &l); ++ if (l != ptlen) ++ { ++ fprintf(stderr, "Inconsistent CT length\n"); ++ exit(1); ++ } ++ } ++ else if(!strcmp(keyword,"AAD")) ++ { ++ aad = hex2bin_m(value, &l); ++ if (l != aadlen) ++ { ++ fprintf(stderr, "Inconsistent AAD length\n"); ++ exit(1); ++ } ++ } ++ else if(!strcmp(keyword,"Tag")) ++ { ++ tag = hex2bin_m(value, &l); ++ if (l != taglen) ++ { ++ fprintf(stderr, "Inconsistent Tag length\n"); ++ exit(1); ++ } ++ } ++ if (encrypt && pt && aad && (iv || encrypt==1)) ++ { ++ tag = OPENSSL_malloc(taglen); ++ FIPS_cipherinit(&ctx, gcm, NULL, NULL, 1); ++ /* Relax FIPS constraints for testing */ ++ M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0); ++ if (encrypt == 1) ++ { ++ static unsigned char iv_fixed[4] = {1,2,3,4}; ++ if (!iv) ++ iv = OPENSSL_malloc(ivlen); ++ FIPS_cipherinit(&ctx, NULL, key, NULL, 1); ++ FIPS_cipher_ctx_ctrl(&ctx, ++ EVP_CTRL_GCM_SET_IV_FIXED, ++ 4, iv_fixed); ++ if (!FIPS_cipher_ctx_ctrl(&ctx, ++ EVP_CTRL_GCM_IV_GEN, 0, iv)) ++ { ++ fprintf(stderr, "IV gen error\n"); ++ exit(1); ++ } ++ OutputValue("IV", iv, ivlen, out, 0); ++ } ++ else ++ FIPS_cipherinit(&ctx, NULL, key, iv, 1); ++ ++ ++ if (aadlen) ++ FIPS_cipher(&ctx, NULL, aad, aadlen); ++ if (ptlen) ++ { ++ ct = OPENSSL_malloc(ptlen); ++ rv = FIPS_cipher(&ctx, ct, pt, ptlen); ++ } ++ FIPS_cipher(&ctx, NULL, NULL, 0); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, ++ taglen, tag); ++ OutputValue("CT", ct, ptlen, out, 0); ++ OutputValue("Tag", tag, taglen, out, 0); ++ if (iv) ++ OPENSSL_free(iv); ++ if (aad) ++ OPENSSL_free(aad); ++ if (ct) ++ OPENSSL_free(ct); ++ if (pt) ++ OPENSSL_free(pt); ++ if (key) ++ OPENSSL_free(key); ++ if (tag) ++ OPENSSL_free(tag); ++ iv = aad = ct = pt = key = tag = NULL; ++ } ++ if (!encrypt && tag) ++ { ++ FIPS_cipherinit(&ctx, gcm, NULL, NULL, 0); ++ /* Relax FIPS constraints for testing */ ++ M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0); ++ FIPS_cipherinit(&ctx, NULL, key, iv, 0); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, taglen, tag); ++ if (aadlen) ++ FIPS_cipher(&ctx, NULL, aad, aadlen); ++ if (ptlen) ++ { ++ pt = OPENSSL_malloc(ptlen); ++ rv = FIPS_cipher(&ctx, pt, ct, ptlen); ++ } ++ rv = FIPS_cipher(&ctx, NULL, NULL, 0); ++ if (rv < 0) ++ fprintf(out, "FAIL" RESP_EOL); ++ else ++ OutputValue("PT", pt, ptlen, out, 0); ++ if (iv) ++ OPENSSL_free(iv); ++ if (aad) ++ OPENSSL_free(aad); ++ if (ct) ++ OPENSSL_free(ct); ++ if (pt) ++ OPENSSL_free(pt); ++ if (key) ++ OPENSSL_free(key); ++ if (tag) ++ OPENSSL_free(tag); ++ iv = aad = ct = pt = key = tag = NULL; ++ } ++ } ++ FIPS_cipher_ctx_cleanup(&ctx); ++ } ++ ++static void xtstest(FILE *in, FILE *out) ++ { ++ char buf[204800]; ++ char lbuf[204800]; ++ char *keyword, *value; ++ int inlen = 0; ++ int encrypt = 0; ++ long l; ++ unsigned char *key = NULL, *iv = NULL; ++ unsigned char *inbuf = NULL, *outbuf = NULL; ++ EVP_CIPHER_CTX ctx; ++ const EVP_CIPHER *xts = NULL; ++ FIPS_cipher_ctx_init(&ctx); ++ ++ while(fgets(buf,sizeof buf,in) != NULL) ++ { ++ fputs(buf,out); ++ if (buf[0] == '[' && strlen(buf) >= 9) ++ { ++ if(!strncmp(buf,"[ENCRYPT]", 9)) ++ encrypt = 1; ++ else if(!strncmp(buf,"[DECRYPT]", 9)) ++ encrypt = 0; ++ } ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ else if(!strcmp(keyword,"Key")) ++ { ++ key = hex2bin_m(value, &l); ++ if (l == 32) ++ xts = EVP_aes_128_xts(); ++ else if (l == 64) ++ xts = EVP_aes_256_xts(); ++ else ++ { ++ fprintf(stderr, "Inconsistent Key length\n"); ++ exit(1); ++ } ++ } ++ else if(!strcmp(keyword,"i")) ++ { ++ iv = hex2bin_m(value, &l); ++ if (l != 16) ++ { ++ fprintf(stderr, "Inconsistent i length\n"); ++ exit(1); ++ } ++ } ++ else if(encrypt && !strcmp(keyword,"PT")) ++ { ++ inbuf = hex2bin_m(value, &l); ++ inlen = l; ++ } ++ else if(!encrypt && !strcmp(keyword,"CT")) ++ { ++ inbuf = hex2bin_m(value, &l); ++ inlen = l; ++ } ++ if (inbuf) ++ { ++ FIPS_cipherinit(&ctx, xts, key, iv, encrypt); ++ outbuf = OPENSSL_malloc(inlen); ++ FIPS_cipher(&ctx, outbuf, inbuf, inlen); ++ OutputValue(encrypt ? "CT":"PT", outbuf, inlen, out, 0); ++ OPENSSL_free(inbuf); ++ OPENSSL_free(outbuf); ++ OPENSSL_free(key); ++ OPENSSL_free(iv); ++ iv = key = inbuf = outbuf = NULL; ++ } ++ } ++ FIPS_cipher_ctx_cleanup(&ctx); ++ } ++ ++static void ccmtest(FILE *in, FILE *out) ++ { ++ char buf[200048]; ++ char lbuf[200048]; ++ char *keyword, *value; ++ long l; ++ unsigned char *Key = NULL, *Nonce = NULL; ++ unsigned char *Adata = NULL, *Payload = NULL; ++ unsigned char *CT = NULL; ++ int Plen = -1, Nlen = -1, Tlen = -1, Alen = -1; ++ int decr = 0; ++ EVP_CIPHER_CTX ctx; ++ const EVP_CIPHER *ccm = NULL; ++ FIPS_cipher_ctx_init(&ctx); ++ ++ while(fgets(buf,sizeof buf,in) != NULL) ++ { ++ char *p; ++ fputs(buf,out); ++ redo: ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ ++ /* If surrounded by square brackets zap them */ ++ if (keyword[0] == '[') ++ { ++ keyword++; ++ p = strchr(value, ']'); ++ if (p) ++ *p = 0; ++ } ++ /* See if we have a comma separated list of parameters ++ * if so copy rest of line back to buffer and redo later. ++ */ ++ p = strchr(value, ','); ++ if (p) ++ { ++ *p = 0; ++ strcpy(buf, p + 1); ++ strcat(buf, "\n"); ++ decr = 1; ++ } ++ if (!strcmp(keyword,"Plen")) ++ Plen = atoi(value); ++ else if (!strcmp(keyword,"Nlen")) ++ Nlen = atoi(value); ++ else if (!strcmp(keyword,"Tlen")) ++ Tlen = atoi(value); ++ else if (!strcmp(keyword,"Alen")) ++ Alen = atoi(value); ++ if (p) ++ goto redo; ++ if (!strcmp(keyword,"Key")) ++ { ++ if (Key) ++ OPENSSL_free(Key); ++ Key = hex2bin_m(value, &l); ++ if (l == 16) ++ ccm = EVP_aes_128_ccm(); ++ else if (l == 24) ++ ccm = EVP_aes_192_ccm(); ++ else if (l == 32) ++ ccm = EVP_aes_256_ccm(); ++ else ++ { ++ fprintf(stderr, "Inconsistent Key length\n"); ++ exit(1); ++ } ++ } ++ else if (!strcmp(keyword,"Nonce")) ++ { ++ if (Nonce) ++ OPENSSL_free(Nonce); ++ Nonce = hex2bin_m(value, &l); ++ if (l != Nlen) ++ { ++ fprintf(stderr, "Inconsistent nonce length\n"); ++ exit(1); ++ } ++ } ++ else if (!strcmp(keyword,"Payload") && !decr) ++ { ++ Payload = hex2bin_m(value, &l); ++ if (Plen && l != Plen) ++ { ++ fprintf(stderr, "Inconsistent Payload length\n"); ++ exit(1); ++ } ++ } ++ else if (!strcmp(keyword,"Adata")) ++ { ++ if (Adata) ++ OPENSSL_free(Adata); ++ Adata = hex2bin_m(value, &l); ++ if (Alen && l != Alen) ++ { ++ fprintf(stderr, "Inconsistent Payload length\n"); ++ exit(1); ++ } ++ } ++ else if (!strcmp(keyword,"CT") && decr) ++ { ++ CT = hex2bin_m(value, &l); ++ if (l != (Plen + Tlen)) ++ { ++ fprintf(stderr, "Inconsistent CT length\n"); ++ exit(1); ++ } ++ } ++ if (Payload) ++ { ++ FIPS_cipherinit(&ctx, ccm, NULL, NULL, 1); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, Tlen, 0); ++ FIPS_cipherinit(&ctx, NULL, Key, Nonce, 1); ++ ++ FIPS_cipher(&ctx, NULL, NULL, Plen); ++ FIPS_cipher(&ctx, NULL, Adata, Alen); ++ CT = OPENSSL_malloc(Plen + Tlen); ++ FIPS_cipher(&ctx, CT, Payload, Plen); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, Tlen, ++ CT + Plen); ++ OutputValue("CT", CT, Plen + Tlen, out, 0); ++ OPENSSL_free(CT); ++ OPENSSL_free(Payload); ++ CT = Payload = NULL; ++ } ++ if (CT) ++ { ++ int rv; ++ int len = Plen == 0 ? 1: Plen; ++ FIPS_cipherinit(&ctx, ccm, NULL, NULL, 0); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0); ++ FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, ++ Tlen, CT + Plen); ++ FIPS_cipherinit(&ctx, NULL, Key, Nonce, 0); ++ FIPS_cipher(&ctx, NULL, NULL, Plen); ++ FIPS_cipher(&ctx, NULL, Adata, Alen); ++ Payload = OPENSSL_malloc(len); ++ rv = FIPS_cipher(&ctx, Payload, CT, Plen); ++ if (rv >= 0) ++ { ++ if (rv == 0) ++ Payload[0] = 0; ++ fputs("Result = Pass" RESP_EOL, out); ++ OutputValue("Payload", Payload, len, out, 0); ++ } ++ else ++ fputs("Result = Fail" RESP_EOL, out); ++ OPENSSL_free(CT); ++ OPENSSL_free(Payload); ++ CT = Payload = NULL; ++ } ++ } ++ if (Key) ++ OPENSSL_free(Key); ++ if (Nonce) ++ OPENSSL_free(Nonce); ++ if (Adata) ++ OPENSSL_free(Adata); ++ FIPS_cipher_ctx_cleanup(&ctx); ++ } ++ ++#ifdef FIPS_ALGVS ++int fips_gcmtest_main(int argc, char **argv) ++#else ++int main(int argc, char **argv) ++#endif ++ { ++ int encrypt; ++ int xts = 0, ccm = 0; ++ FILE *in, *out; ++ if (argc == 4) ++ { ++ in = fopen(argv[2], "r"); ++ if (!in) ++ { ++ fprintf(stderr, "Error opening input file\n"); ++ exit(1); ++ } ++ out = fopen(argv[3], "w"); ++ if (!out) ++ { ++ fprintf(stderr, "Error opening output file\n"); ++ exit(1); ++ } ++ } ++ else if (argc == 2) ++ { ++ in = stdin; ++ out = stdout; ++ } ++ else ++ { ++ fprintf(stderr,"%s [-encrypt|-decrypt]\n",argv[0]); ++ exit(1); ++ } ++ fips_algtest_init(); ++ if(!strcmp(argv[1],"-encrypt")) ++ encrypt = 1; ++ else if(!strcmp(argv[1],"-encryptIVext")) ++ encrypt = 2; ++ else if(!strcmp(argv[1],"-decrypt")) ++ encrypt = 0; ++ else if(!strcmp(argv[1],"-ccm")) ++ ccm = 1; ++ else if(!strcmp(argv[1],"-xts")) ++ xts = 1; ++ else ++ { ++ fprintf(stderr,"Don't know how to %s.\n",argv[1]); ++ exit(1); ++ } ++ ++ if (ccm) ++ ccmtest(in, out); ++ else if (xts) ++ xtstest(in, out); ++ else ++ gcmtest(in, out, encrypt); ++ ++ if (argc == 4) ++ { ++ fclose(in); ++ fclose(out); ++ } ++ ++ return 0; ++} ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_rngvs.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_rngvs.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_rngvs.c.fips 2013-10-04 11:48:04.181694158 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_rngvs.c 2013-10-04 11:48:04.181694158 +0200 +@@ -0,0 +1,230 @@ ++/* ++ * Crude test driver for processing the VST and MCT testvector files ++ * generated by the CMVP RNGVS product. ++ * ++ * Note the input files are assumed to have a _very_ specific format ++ * as described in the NIST document "The Random Number Generator ++ * Validation System (RNGVS)", May 25, 2004. ++ * ++ */ ++#include ++ ++#ifndef OPENSSL_FIPS ++#include ++ ++int main(int argc, char **argv) ++{ ++ printf("No FIPS RNG support\n"); ++ return 0; ++} ++#else ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fips_utl.h" ++ ++void vst() ++ { ++ unsigned char *key = NULL; ++ unsigned char *v = NULL; ++ unsigned char *dt = NULL; ++ unsigned char ret[16]; ++ char buf[1024]; ++ char lbuf[1024]; ++ char *keyword, *value; ++ long i, keylen; ++ ++ keylen = 0; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ fputs(buf,stdout); ++ if(!strncmp(buf,"[AES 128-Key]", 13)) ++ keylen = 16; ++ else if(!strncmp(buf,"[AES 192-Key]", 13)) ++ keylen = 24; ++ else if(!strncmp(buf,"[AES 256-Key]", 13)) ++ keylen = 32; ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if(!strcmp(keyword,"Key")) ++ { ++ key=hex2bin_m(value,&i); ++ if (i != keylen) ++ { ++ fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); ++ return; ++ } ++ } ++ else if(!strcmp(keyword,"DT")) ++ { ++ dt=hex2bin_m(value,&i); ++ if (i != 16) ++ { ++ fprintf(stderr, "Invalid DT length\n"); ++ return; ++ } ++ } ++ else if(!strcmp(keyword,"V")) ++ { ++ v=hex2bin_m(value,&i); ++ if (i != 16) ++ { ++ fprintf(stderr, "Invalid V length\n"); ++ return; ++ } ++ ++ if (!key || !dt) ++ { ++ fprintf(stderr, "Missing key or DT\n"); ++ return; ++ } ++ ++ FIPS_x931_set_key(key, keylen); ++ FIPS_x931_seed(v,16); ++ FIPS_x931_set_dt(dt); ++ if (FIPS_x931_bytes(ret,16) <= 0) ++ { ++ fprintf(stderr, "Error getting PRNG value\n"); ++ return; ++ } ++ ++ pv("R",ret,16); ++ OPENSSL_free(key); ++ key = NULL; ++ OPENSSL_free(dt); ++ dt = NULL; ++ OPENSSL_free(v); ++ v = NULL; ++ } ++ } ++ } ++ ++void mct() ++ { ++ unsigned char *key = NULL; ++ unsigned char *v = NULL; ++ unsigned char *dt = NULL; ++ unsigned char ret[16]; ++ char buf[1024]; ++ char lbuf[1024]; ++ char *keyword, *value; ++ long i, keylen; ++ int j; ++ ++ keylen = 0; ++ ++ while(fgets(buf,sizeof buf,stdin) != NULL) ++ { ++ fputs(buf,stdout); ++ if(!strncmp(buf,"[AES 128-Key]", 13)) ++ keylen = 16; ++ else if(!strncmp(buf,"[AES 192-Key]", 13)) ++ keylen = 24; ++ else if(!strncmp(buf,"[AES 256-Key]", 13)) ++ keylen = 32; ++ if (!parse_line(&keyword, &value, lbuf, buf)) ++ continue; ++ if(!strcmp(keyword,"Key")) ++ { ++ key=hex2bin_m(value,&i); ++ if (i != keylen) ++ { ++ fprintf(stderr, "Invalid key length, expecting %ld\n", keylen); ++ return; ++ } ++ } ++ else if(!strcmp(keyword,"DT")) ++ { ++ dt=hex2bin_m(value,&i); ++ if (i != 16) ++ { ++ fprintf(stderr, "Invalid DT length\n"); ++ return; ++ } ++ } ++ else if(!strcmp(keyword,"V")) ++ { ++ v=hex2bin_m(value,&i); ++ if (i != 16) ++ { ++ fprintf(stderr, "Invalid V length\n"); ++ return; ++ } ++ ++ if (!key || !dt) ++ { ++ fprintf(stderr, "Missing key or DT\n"); ++ return; ++ } ++ ++ FIPS_x931_set_key(key, keylen); ++ FIPS_x931_seed(v,16); ++ for (i = 0; i < 10000; i++) ++ { ++ FIPS_x931_set_dt(dt); ++ if (FIPS_x931_bytes(ret,16) <= 0) ++ { ++ fprintf(stderr, "Error getting PRNG value\n"); ++ return; ++ } ++ /* Increment DT */ ++ for (j = 15; j >= 0; j--) ++ { ++ dt[j]++; ++ if (dt[j]) ++ break; ++ } ++ } ++ ++ pv("R",ret,16); ++ OPENSSL_free(key); ++ key = NULL; ++ OPENSSL_free(dt); ++ dt = NULL; ++ OPENSSL_free(v); ++ v = NULL; ++ } ++ } ++ } ++ ++int main(int argc,char **argv) ++ { ++ if(argc != 2) ++ { ++ fprintf(stderr,"%s [mct|vst]\n",argv[0]); ++ exit(1); ++ } ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ exit(1); ++ } ++ FIPS_x931_reset(); ++ if (!FIPS_x931_test_mode()) ++ { ++ fprintf(stderr, "Error setting PRNG test mode\n"); ++ do_print_errors(); ++ exit(1); ++ } ++ if(!strcmp(argv[1],"mct")) ++ mct(); ++ else if(!strcmp(argv[1],"vst")) ++ vst(); ++ else ++ { ++ fprintf(stderr,"Don't know how to %s.\n",argv[1]); ++ exit(1); ++ } ++ ++ return 0; ++ } ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_rsagtest.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_rsagtest.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_rsagtest.c.fips 2013-10-04 11:48:04.181694158 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_rsagtest.c 2013-10-04 11:48:04.181694158 +0200 +@@ -0,0 +1,390 @@ ++/* fips_rsagtest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2005. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2005,2007 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS RSA support\n"); ++ return(0); ++} ++ ++#else ++ ++#include "fips_utl.h" ++ ++int rsa_test(FILE *out, FILE *in); ++static int rsa_printkey1(FILE *out, RSA *rsa, ++ BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, ++ BIGNUM *e); ++static int rsa_printkey2(FILE *out, RSA *rsa, ++ BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq); ++ ++int main(int argc, char **argv) ++ { ++ FILE *in = NULL, *out = NULL; ++ ++ int ret = 1; ++ ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ goto end; ++ } ++ ++ if (argc == 1) ++ in = stdin; ++ else ++ in = fopen(argv[1], "r"); ++ ++ if (argc < 2) ++ out = stdout; ++ else ++ out = fopen(argv[2], "w"); ++ ++ if (!in) ++ { ++ fprintf(stderr, "FATAL input initialization error\n"); ++ goto end; ++ } ++ ++ if (!out) ++ { ++ fprintf(stderr, "FATAL output initialization error\n"); ++ goto end; ++ } ++ ++ if (!rsa_test(out, in)) ++ { ++ fprintf(stderr, "FATAL RSAGTEST file processing error\n"); ++ goto end; ++ } ++ else ++ ret = 0; ++ ++ end: ++ ++ if (ret) ++ do_print_errors(); ++ ++ if (in && (in != stdin)) ++ fclose(in); ++ if (out && (out != stdout)) ++ fclose(out); ++ ++ return ret; ++ ++ } ++ ++#define RSA_TEST_MAXLINELEN 10240 ++ ++int rsa_test(FILE *out, FILE *in) ++ { ++ char *linebuf, *olinebuf, *p, *q; ++ char *keyword, *value; ++ RSA *rsa = NULL; ++ BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL; ++ BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL; ++ BIGNUM *e = NULL; ++ int ret = 0; ++ int lnum = 0; ++ ++ olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); ++ linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); ++ ++ if (!linebuf || !olinebuf) ++ goto error; ++ ++ while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) ++ { ++ lnum++; ++ strcpy(linebuf, olinebuf); ++ keyword = linebuf; ++ /* Skip leading space */ ++ while (isspace((unsigned char)*keyword)) ++ keyword++; ++ ++ /* Look for = sign */ ++ p = strchr(linebuf, '='); ++ ++ /* If no = or starts with [ (for [foo = bar] line) just copy */ ++ if (!p || *keyword=='[') ++ { ++ if (fputs(olinebuf, out) < 0) ++ goto error; ++ continue; ++ } ++ ++ q = p - 1; ++ ++ /* Remove trailing space */ ++ while (isspace((unsigned char)*q)) ++ *q-- = 0; ++ ++ *p = 0; ++ value = p + 1; ++ ++ /* Remove leading space from value */ ++ while (isspace((unsigned char)*value)) ++ value++; ++ ++ /* Remove trailing space from value */ ++ p = value + strlen(value) - 1; ++ ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ ++ if (!strcmp(keyword, "xp1")) ++ { ++ if (Xp1 || !do_hex2bn(&Xp1,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "xp2")) ++ { ++ if (Xp2 || !do_hex2bn(&Xp2,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Xp")) ++ { ++ if (Xp || !do_hex2bn(&Xp,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "xq1")) ++ { ++ if (Xq1 || !do_hex2bn(&Xq1,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "xq2")) ++ { ++ if (Xq2 || !do_hex2bn(&Xq2,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Xq")) ++ { ++ if (Xq || !do_hex2bn(&Xq,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "e")) ++ { ++ if (e || !do_hex2bn(&e,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "p1")) ++ continue; ++ else if (!strcmp(keyword, "p2")) ++ continue; ++ else if (!strcmp(keyword, "p")) ++ continue; ++ else if (!strcmp(keyword, "q1")) ++ continue; ++ else if (!strcmp(keyword, "q2")) ++ continue; ++ else if (!strcmp(keyword, "q")) ++ continue; ++ else if (!strcmp(keyword, "n")) ++ continue; ++ else if (!strcmp(keyword, "d")) ++ continue; ++ else ++ goto parse_error; ++ ++ fputs(olinebuf, out); ++ ++ if (e && Xp1 && Xp2 && Xp) ++ { ++ rsa = FIPS_rsa_new(); ++ if (!rsa) ++ goto error; ++ if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e)) ++ goto error; ++ BN_free(Xp1); ++ Xp1 = NULL; ++ BN_free(Xp2); ++ Xp2 = NULL; ++ BN_free(Xp); ++ Xp = NULL; ++ BN_free(e); ++ e = NULL; ++ } ++ ++ if (rsa && Xq1 && Xq2 && Xq) ++ { ++ if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq)) ++ goto error; ++ BN_free(Xq1); ++ Xq1 = NULL; ++ BN_free(Xq2); ++ Xq2 = NULL; ++ BN_free(Xq); ++ Xq = NULL; ++ FIPS_rsa_free(rsa); ++ rsa = NULL; ++ } ++ } ++ ++ ret = 1; ++ ++ error: ++ ++ if (olinebuf) ++ OPENSSL_free(olinebuf); ++ if (linebuf) ++ OPENSSL_free(linebuf); ++ ++ if (Xp1) ++ BN_free(Xp1); ++ if (Xp2) ++ BN_free(Xp2); ++ if (Xp) ++ BN_free(Xp); ++ if (Xq1) ++ BN_free(Xq1); ++ if (Xq1) ++ BN_free(Xq1); ++ if (Xq2) ++ BN_free(Xq2); ++ if (Xq) ++ BN_free(Xq); ++ if (e) ++ BN_free(e); ++ if (rsa) ++ FIPS_rsa_free(rsa); ++ ++ return ret; ++ ++ parse_error: ++ ++ fprintf(stderr, "FATAL parse error processing line %d\n", lnum); ++ ++ goto error; ++ ++ } ++ ++static int rsa_printkey1(FILE *out, RSA *rsa, ++ BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp, ++ BIGNUM *e) ++ { ++ int ret = 0; ++ BIGNUM *p1 = NULL, *p2 = NULL; ++ p1 = BN_new(); ++ p2 = BN_new(); ++ if (!p1 || !p2) ++ goto error; ++ ++ if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp, ++ NULL, NULL, NULL, e, NULL)) ++ goto error; ++ ++ do_bn_print_name(out, "p1", p1); ++ do_bn_print_name(out, "p2", p2); ++ do_bn_print_name(out, "p", rsa->p); ++ ++ ret = 1; ++ ++ error: ++ if (p1) ++ BN_free(p1); ++ if (p2) ++ BN_free(p2); ++ ++ return ret; ++ } ++ ++static int rsa_printkey2(FILE *out, RSA *rsa, ++ BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq) ++ { ++ int ret = 0; ++ BIGNUM *q1 = NULL, *q2 = NULL; ++ q1 = BN_new(); ++ q2 = BN_new(); ++ if (!q1 || !q2) ++ goto error; ++ ++ if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL, ++ Xq1, Xq2, Xq, NULL, NULL)) ++ goto error; ++ ++ do_bn_print_name(out, "q1", q1); ++ do_bn_print_name(out, "q2", q2); ++ do_bn_print_name(out, "q", rsa->q); ++ do_bn_print_name(out, "n", rsa->n); ++ do_bn_print_name(out, "d", rsa->d); ++ ++ ret = 1; ++ ++ error: ++ if (q1) ++ BN_free(q1); ++ if (q2) ++ BN_free(q2); ++ ++ return ret; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_rsastest.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_rsastest.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_rsastest.c.fips 2013-10-04 11:48:04.181694158 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_rsastest.c 2013-10-04 11:48:04.181694158 +0200 +@@ -0,0 +1,370 @@ ++/* fips_rsastest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2005. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2005 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS RSA support\n"); ++ return(0); ++} ++ ++#else ++ ++#include "fips_utl.h" ++ ++static int rsa_stest(FILE *out, FILE *in, int Saltlen); ++static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, ++ unsigned char *Msg, long Msglen, int Saltlen); ++ ++int main(int argc, char **argv) ++ { ++ FILE *in = NULL, *out = NULL; ++ ++ int ret = 1, Saltlen = -1; ++ ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ goto end; ++ } ++ ++ if ((argc > 2) && !strcmp("-saltlen", argv[1])) ++ { ++ Saltlen = atoi(argv[2]); ++ if (Saltlen < 0) ++ { ++ fprintf(stderr, "FATAL: Invalid salt length\n"); ++ goto end; ++ } ++ argc -= 2; ++ argv += 2; ++ } ++ else if ((argc > 1) && !strcmp("-x931", argv[1])) ++ { ++ Saltlen = -2; ++ argc--; ++ argv++; ++ } ++ ++ if (argc == 1) ++ in = stdin; ++ else ++ in = fopen(argv[1], "r"); ++ ++ if (argc < 2) ++ out = stdout; ++ else ++ out = fopen(argv[2], "w"); ++ ++ if (!in) ++ { ++ fprintf(stderr, "FATAL input initialization error\n"); ++ goto end; ++ } ++ ++ if (!out) ++ { ++ fprintf(stderr, "FATAL output initialization error\n"); ++ goto end; ++ } ++ ++ if (!rsa_stest(out, in, Saltlen)) ++ { ++ fprintf(stderr, "FATAL RSASTEST file processing error\n"); ++ goto end; ++ } ++ else ++ ret = 0; ++ ++ end: ++ ++ if (ret) ++ do_print_errors(); ++ ++ if (in && (in != stdin)) ++ fclose(in); ++ if (out && (out != stdout)) ++ fclose(out); ++ ++ return ret; ++ ++ } ++ ++#define RSA_TEST_MAXLINELEN 10240 ++ ++int rsa_stest(FILE *out, FILE *in, int Saltlen) ++ { ++ char *linebuf, *olinebuf, *p, *q; ++ char *keyword, *value; ++ RSA *rsa = NULL; ++ const EVP_MD *dgst = NULL; ++ unsigned char *Msg = NULL; ++ long Msglen = -1; ++ int keylen = -1, current_keylen = -1; ++ int ret = 0; ++ int lnum = 0; ++ ++ olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); ++ linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); ++ ++ if (!linebuf || !olinebuf) ++ goto error; ++ ++ while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) ++ { ++ lnum++; ++ strcpy(linebuf, olinebuf); ++ keyword = linebuf; ++ /* Skip leading space */ ++ while (isspace((unsigned char)*keyword)) ++ keyword++; ++ ++ /* Look for = sign */ ++ p = strchr(linebuf, '='); ++ ++ /* If no = just copy */ ++ if (!p) ++ { ++ if (fputs(olinebuf, out) < 0) ++ goto error; ++ continue; ++ } ++ ++ q = p - 1; ++ ++ /* Remove trailing space */ ++ while (isspace((unsigned char)*q)) ++ *q-- = 0; ++ ++ *p = 0; ++ value = p + 1; ++ ++ /* Remove leading space from value */ ++ while (isspace((unsigned char)*value)) ++ value++; ++ ++ /* Remove trailing space from value */ ++ p = value + strlen(value) - 1; ++ ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ ++ /* Look for [mod = XXX] for key length */ ++ ++ if (!strcmp(keyword, "[mod")) ++ { ++ p = value + strlen(value) - 1; ++ if (*p != ']') ++ goto parse_error; ++ *p = 0; ++ keylen = atoi(value); ++ if (keylen < 0) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "SHAAlg")) ++ { ++ if (!strcmp(value, "SHA1")) ++ dgst = EVP_sha1(); ++ else if (!strcmp(value, "SHA224")) ++ dgst = EVP_sha224(); ++ else if (!strcmp(value, "SHA256")) ++ dgst = EVP_sha256(); ++ else if (!strcmp(value, "SHA384")) ++ dgst = EVP_sha384(); ++ else if (!strcmp(value, "SHA512")) ++ dgst = EVP_sha512(); ++ else ++ { ++ fprintf(stderr, ++ "FATAL: unsupported algorithm \"%s\"\n", ++ value); ++ goto parse_error; ++ } ++ } ++ else if (!strcmp(keyword, "Msg")) ++ { ++ if (Msg) ++ goto parse_error; ++ if (strlen(value) & 1) ++ *(--value) = '0'; ++ Msg = hex2bin_m(value, &Msglen); ++ if (!Msg) ++ goto parse_error; ++ } ++ ++ fputs(olinebuf, out); ++ ++ /* If key length has changed, generate and output public ++ * key components of new RSA private key. ++ */ ++ ++ if (keylen != current_keylen) ++ { ++ BIGNUM *bn_e; ++ if (rsa) ++ FIPS_rsa_free(rsa); ++ rsa = FIPS_rsa_new(); ++ if (!rsa) ++ goto error; ++ bn_e = BN_new(); ++ if (!bn_e || !BN_set_word(bn_e, 0x1001)) ++ goto error; ++ if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL)) ++ goto error; ++ BN_free(bn_e); ++ fputs("n = ", out); ++ do_bn_print(out, rsa->n); ++ fputs("\ne = ", out); ++ do_bn_print(out, rsa->e); ++ fputs("\n", out); ++ current_keylen = keylen; ++ } ++ ++ if (Msg && dgst) ++ { ++ if (!rsa_printsig(out, rsa, dgst, Msg, Msglen, ++ Saltlen)) ++ goto error; ++ OPENSSL_free(Msg); ++ Msg = NULL; ++ } ++ ++ } ++ ++ ret = 1; ++ ++ error: ++ ++ if (olinebuf) ++ OPENSSL_free(olinebuf); ++ if (linebuf) ++ OPENSSL_free(linebuf); ++ if (rsa) ++ FIPS_rsa_free(rsa); ++ ++ return ret; ++ ++ parse_error: ++ ++ fprintf(stderr, "FATAL parse error processing line %d\n", lnum); ++ ++ goto error; ++ ++ } ++ ++static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst, ++ unsigned char *Msg, long Msglen, int Saltlen) ++ { ++ int ret = 0; ++ unsigned char *sigbuf = NULL; ++ int i, siglen; ++ /* EVP_PKEY structure */ ++ EVP_PKEY pk; ++ EVP_MD_CTX ctx; ++ pk.type = EVP_PKEY_RSA; ++ pk.pkey.rsa = rsa; ++ ++ siglen = RSA_size(rsa); ++ sigbuf = OPENSSL_malloc(siglen); ++ if (!sigbuf) ++ goto error; ++ ++ EVP_MD_CTX_init(&ctx); ++ ++ if (Saltlen >= 0) ++ { ++ M_EVP_MD_CTX_set_flags(&ctx, ++ EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); ++ } ++ else if (Saltlen == -2) ++ M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); ++ if (!EVP_SignInit_ex(&ctx, dgst, NULL)) ++ goto error; ++ if (!EVP_SignUpdate(&ctx, Msg, Msglen)) ++ goto error; ++ if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk)) ++ goto error; ++ ++ EVP_MD_CTX_cleanup(&ctx); ++ ++ fputs("S = ", out); ++ ++ for (i = 0; i < siglen; i++) ++ fprintf(out, "%02X", sigbuf[i]); ++ ++ fputs("\n", out); ++ ++ ret = 1; ++ ++ error: ++ ++ return ret; ++ } ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_rsavtest.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_rsavtest.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_rsavtest.c.fips 2013-10-04 11:48:04.181694158 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_rsavtest.c 2013-10-04 11:48:04.181694158 +0200 +@@ -0,0 +1,377 @@ ++/* fips_rsavtest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2005. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2005 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS RSA support\n"); ++ return(0); ++} ++ ++#else ++ ++#include "fips_utl.h" ++ ++int rsa_test(FILE *out, FILE *in, int saltlen); ++static int rsa_printver(FILE *out, ++ BIGNUM *n, BIGNUM *e, ++ const EVP_MD *dgst, ++ unsigned char *Msg, long Msglen, ++ unsigned char *S, long Slen, int Saltlen); ++ ++int main(int argc, char **argv) ++ { ++ FILE *in = NULL, *out = NULL; ++ ++ int ret = 1; ++ int Saltlen = -1; ++ ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ goto end; ++ } ++ ++ if ((argc > 2) && !strcmp("-saltlen", argv[1])) ++ { ++ Saltlen = atoi(argv[2]); ++ if (Saltlen < 0) ++ { ++ fprintf(stderr, "FATAL: Invalid salt length\n"); ++ goto end; ++ } ++ argc -= 2; ++ argv += 2; ++ } ++ else if ((argc > 1) && !strcmp("-x931", argv[1])) ++ { ++ Saltlen = -2; ++ argc--; ++ argv++; ++ } ++ ++ if (argc == 1) ++ in = stdin; ++ else ++ in = fopen(argv[1], "r"); ++ ++ if (argc < 2) ++ out = stdout; ++ else ++ out = fopen(argv[2], "w"); ++ ++ if (!in) ++ { ++ fprintf(stderr, "FATAL input initialization error\n"); ++ goto end; ++ } ++ ++ if (!out) ++ { ++ fprintf(stderr, "FATAL output initialization error\n"); ++ goto end; ++ } ++ ++ if (!rsa_test(out, in, Saltlen)) ++ { ++ fprintf(stderr, "FATAL RSAVTEST file processing error\n"); ++ goto end; ++ } ++ else ++ ret = 0; ++ ++ end: ++ ++ if (ret) ++ do_print_errors(); ++ ++ if (in && (in != stdin)) ++ fclose(in); ++ if (out && (out != stdout)) ++ fclose(out); ++ ++ return ret; ++ ++ } ++ ++#define RSA_TEST_MAXLINELEN 10240 ++ ++int rsa_test(FILE *out, FILE *in, int Saltlen) ++ { ++ char *linebuf, *olinebuf, *p, *q; ++ char *keyword, *value; ++ const EVP_MD *dgst = NULL; ++ BIGNUM *n = NULL, *e = NULL; ++ unsigned char *Msg = NULL, *S = NULL; ++ long Msglen, Slen; ++ int ret = 0; ++ int lnum = 0; ++ ++ olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); ++ linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN); ++ ++ if (!linebuf || !olinebuf) ++ goto error; ++ ++ while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in)) ++ { ++ lnum++; ++ strcpy(linebuf, olinebuf); ++ keyword = linebuf; ++ /* Skip leading space */ ++ while (isspace((unsigned char)*keyword)) ++ keyword++; ++ ++ /* Look for = sign */ ++ p = strchr(linebuf, '='); ++ ++ /* If no = or starts with [ (for [foo = bar] line) just copy */ ++ if (!p || *keyword=='[') ++ { ++ if (fputs(olinebuf, out) < 0) ++ goto error; ++ continue; ++ } ++ ++ q = p - 1; ++ ++ /* Remove trailing space */ ++ while (isspace((unsigned char)*q)) ++ *q-- = 0; ++ ++ *p = 0; ++ value = p + 1; ++ ++ /* Remove leading space from value */ ++ while (isspace((unsigned char)*value)) ++ value++; ++ ++ /* Remove trailing space from value */ ++ p = value + strlen(value) - 1; ++ ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ ++ if (!strcmp(keyword, "n")) ++ { ++ if (!do_hex2bn(&n,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "e")) ++ { ++ if (!do_hex2bn(&e,value)) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "SHAAlg")) ++ { ++ if (!strcmp(value, "SHA1")) ++ dgst = EVP_sha1(); ++ else if (!strcmp(value, "SHA224")) ++ dgst = EVP_sha224(); ++ else if (!strcmp(value, "SHA256")) ++ dgst = EVP_sha256(); ++ else if (!strcmp(value, "SHA384")) ++ dgst = EVP_sha384(); ++ else if (!strcmp(value, "SHA512")) ++ dgst = EVP_sha512(); ++ else ++ { ++ fprintf(stderr, ++ "FATAL: unsupported algorithm \"%s\"\n", ++ value); ++ goto parse_error; ++ } ++ } ++ else if (!strcmp(keyword, "Msg")) ++ { ++ if (Msg) ++ goto parse_error; ++ if (strlen(value) & 1) ++ *(--value) = '0'; ++ Msg = hex2bin_m(value, &Msglen); ++ if (!Msg) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "S")) ++ { ++ if (S) ++ goto parse_error; ++ if (strlen(value) & 1) ++ *(--value) = '0'; ++ S = hex2bin_m(value, &Slen); ++ if (!S) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Result")) ++ continue; ++ else ++ goto parse_error; ++ ++ fputs(olinebuf, out); ++ ++ if (n && e && Msg && S && dgst) ++ { ++ if (!rsa_printver(out, n, e, dgst, ++ Msg, Msglen, S, Slen, Saltlen)) ++ goto error; ++ OPENSSL_free(Msg); ++ Msg = NULL; ++ OPENSSL_free(S); ++ S = NULL; ++ } ++ ++ } ++ ++ ++ ret = 1; ++ ++ ++ error: ++ ++ if (olinebuf) ++ OPENSSL_free(olinebuf); ++ if (linebuf) ++ OPENSSL_free(linebuf); ++ if (n) ++ BN_free(n); ++ if (e) ++ BN_free(e); ++ ++ return ret; ++ ++ parse_error: ++ ++ fprintf(stderr, "FATAL parse error processing line %d\n", lnum); ++ ++ goto error; ++ ++ } ++ ++static int rsa_printver(FILE *out, ++ BIGNUM *n, BIGNUM *e, ++ const EVP_MD *dgst, ++ unsigned char *Msg, long Msglen, ++ unsigned char *S, long Slen, int Saltlen) ++ { ++ int ret = 0, r; ++ /* Setup RSA and EVP_PKEY structures */ ++ RSA *rsa_pubkey = NULL; ++ EVP_PKEY pk; ++ EVP_MD_CTX ctx; ++ unsigned char *buf = NULL; ++ rsa_pubkey = FIPS_rsa_new(); ++ if (!rsa_pubkey) ++ goto error; ++ rsa_pubkey->n = BN_dup(n); ++ rsa_pubkey->e = BN_dup(e); ++ if (!rsa_pubkey->n || !rsa_pubkey->e) ++ goto error; ++ pk.type = EVP_PKEY_RSA; ++ pk.pkey.rsa = rsa_pubkey; ++ ++ EVP_MD_CTX_init(&ctx); ++ ++ if (Saltlen >= 0) ++ { ++ M_EVP_MD_CTX_set_flags(&ctx, ++ EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16)); ++ } ++ else if (Saltlen == -2) ++ M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931); ++ if (!EVP_VerifyInit_ex(&ctx, dgst, NULL)) ++ goto error; ++ if (!EVP_VerifyUpdate(&ctx, Msg, Msglen)) ++ goto error; ++ ++ r = EVP_VerifyFinal(&ctx, S, Slen, &pk); ++ ++ ++ EVP_MD_CTX_cleanup(&ctx); ++ ++ if (r < 0) ++ goto error; ++ ERR_clear_error(); ++ ++ if (r == 0) ++ fputs("Result = F\n", out); ++ else ++ fputs("Result = P\n", out); ++ ++ ret = 1; ++ ++ error: ++ if (rsa_pubkey) ++ FIPS_rsa_free(rsa_pubkey); ++ if (buf) ++ OPENSSL_free(buf); ++ ++ return ret; ++ } ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_shatest.c.fips openssl-1.0.1e/crypto/fips/cavs/fips_shatest.c +--- openssl-1.0.1e/crypto/fips/cavs/fips_shatest.c.fips 2013-10-04 11:48:04.182694181 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_shatest.c 2013-10-04 11:48:04.182694181 +0200 +@@ -0,0 +1,388 @@ ++/* fips_shatest.c */ ++/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL ++ * project 2005. ++ */ ++/* ==================================================================== ++ * Copyright (c) 2005 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * licensing@OpenSSL.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ==================================================================== ++ * ++ * This product includes cryptographic software written by Eric Young ++ * (eay@cryptsoft.com). This product includes software written by Tim ++ * Hudson (tjh@cryptsoft.com). ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef OPENSSL_FIPS ++ ++int main(int argc, char *argv[]) ++{ ++ printf("No FIPS SHAXXX support\n"); ++ return(0); ++} ++ ++#else ++ ++#include "fips_utl.h" ++ ++static int dgst_test(FILE *out, FILE *in); ++static int print_dgst(const EVP_MD *md, FILE *out, ++ unsigned char *Msg, int Msglen); ++static int print_monte(const EVP_MD *md, FILE *out, ++ unsigned char *Seed, int SeedLen); ++ ++int main(int argc, char **argv) ++ { ++ FILE *in = NULL, *out = NULL; ++ ++ int ret = 1; ++ ++ if(!FIPS_mode_set(1)) ++ { ++ do_print_errors(); ++ goto end; ++ } ++ ++ if (argc == 1) ++ in = stdin; ++ else ++ in = fopen(argv[1], "r"); ++ ++ if (argc < 2) ++ out = stdout; ++ else ++ out = fopen(argv[2], "w"); ++ ++ if (!in) ++ { ++ fprintf(stderr, "FATAL input initialization error\n"); ++ goto end; ++ } ++ ++ if (!out) ++ { ++ fprintf(stderr, "FATAL output initialization error\n"); ++ goto end; ++ } ++ ++ if (!dgst_test(out, in)) ++ { ++ fprintf(stderr, "FATAL digest file processing error\n"); ++ goto end; ++ } ++ else ++ ret = 0; ++ ++ end: ++ ++ if (ret) ++ do_print_errors(); ++ ++ if (in && (in != stdin)) ++ fclose(in); ++ if (out && (out != stdout)) ++ fclose(out); ++ ++ return ret; ++ ++ } ++ ++#define SHA_TEST_MAX_BITS 102400 ++#define SHA_TEST_MAXLINELEN (((SHA_TEST_MAX_BITS >> 3) * 2) + 100) ++ ++int dgst_test(FILE *out, FILE *in) ++ { ++ const EVP_MD *md = NULL; ++ char *linebuf, *olinebuf, *p, *q; ++ char *keyword, *value; ++ unsigned char *Msg = NULL, *Seed = NULL; ++ long MsgLen = -1, Len = -1, SeedLen = -1; ++ int ret = 0; ++ int lnum = 0; ++ ++ olinebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); ++ linebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN); ++ ++ if (!linebuf || !olinebuf) ++ goto error; ++ ++ ++ while (fgets(olinebuf, SHA_TEST_MAXLINELEN, in)) ++ { ++ lnum++; ++ strcpy(linebuf, olinebuf); ++ keyword = linebuf; ++ /* Skip leading space */ ++ while (isspace((unsigned char)*keyword)) ++ keyword++; ++ ++ /* Look for = sign */ ++ p = strchr(linebuf, '='); ++ ++ /* If no = or starts with [ (for [L=20] line) just copy */ ++ if (!p) ++ { ++ fputs(olinebuf, out); ++ continue; ++ } ++ ++ q = p - 1; ++ ++ /* Remove trailing space */ ++ while (isspace((unsigned char)*q)) ++ *q-- = 0; ++ ++ *p = 0; ++ value = p + 1; ++ ++ /* Remove leading space from value */ ++ while (isspace((unsigned char)*value)) ++ value++; ++ ++ /* Remove trailing space from value */ ++ p = value + strlen(value) - 1; ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ ++ if (!strcmp(keyword,"[L") && *p==']') ++ { ++ switch (atoi(value)) ++ { ++ case 20: md=EVP_sha1(); break; ++ case 28: md=EVP_sha224(); break; ++ case 32: md=EVP_sha256(); break; ++ case 48: md=EVP_sha384(); break; ++ case 64: md=EVP_sha512(); break; ++ default: goto parse_error; ++ } ++ } ++ else if (!strcmp(keyword, "Len")) ++ { ++ if (Len != -1) ++ goto parse_error; ++ Len = atoi(value); ++ if (Len < 0) ++ goto parse_error; ++ /* Only handle multiples of 8 bits */ ++ if (Len & 0x7) ++ goto parse_error; ++ if (Len > SHA_TEST_MAX_BITS) ++ goto parse_error; ++ MsgLen = Len >> 3; ++ } ++ ++ else if (!strcmp(keyword, "Msg")) ++ { ++ long tmplen; ++ if (strlen(value) & 1) ++ *(--value) = '0'; ++ if (Msg) ++ goto parse_error; ++ Msg = hex2bin_m(value, &tmplen); ++ if (!Msg) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "Seed")) ++ { ++ if (strlen(value) & 1) ++ *(--value) = '0'; ++ if (Seed) ++ goto parse_error; ++ Seed = hex2bin_m(value, &SeedLen); ++ if (!Seed) ++ goto parse_error; ++ } ++ else if (!strcmp(keyword, "MD")) ++ continue; ++ else ++ goto parse_error; ++ ++ fputs(olinebuf, out); ++ ++ if (md && Msg && (MsgLen >= 0)) ++ { ++ if (!print_dgst(md, out, Msg, MsgLen)) ++ goto error; ++ OPENSSL_free(Msg); ++ Msg = NULL; ++ MsgLen = -1; ++ Len = -1; ++ } ++ else if (md && Seed && (SeedLen > 0)) ++ { ++ if (!print_monte(md, out, Seed, SeedLen)) ++ goto error; ++ OPENSSL_free(Seed); ++ Seed = NULL; ++ SeedLen = -1; ++ } ++ ++ ++ } ++ ++ ++ ret = 1; ++ ++ ++ error: ++ ++ if (olinebuf) ++ OPENSSL_free(olinebuf); ++ if (linebuf) ++ OPENSSL_free(linebuf); ++ if (Msg) ++ OPENSSL_free(Msg); ++ if (Seed) ++ OPENSSL_free(Seed); ++ ++ return ret; ++ ++ parse_error: ++ ++ fprintf(stderr, "FATAL parse error processing line %d\n", lnum); ++ ++ goto error; ++ ++ } ++ ++static int print_dgst(const EVP_MD *emd, FILE *out, ++ unsigned char *Msg, int Msglen) ++ { ++ int i, mdlen; ++ unsigned char md[EVP_MAX_MD_SIZE]; ++ if (!EVP_Digest(Msg, Msglen, md, (unsigned int *)&mdlen, emd, NULL)) ++ { ++ fputs("Error calculating HASH\n", stderr); ++ return 0; ++ } ++ fputs("MD = ", out); ++ for (i = 0; i < mdlen; i++) ++ fprintf(out, "%02x", md[i]); ++ fputs("\n", out); ++ return 1; ++ } ++ ++static int print_monte(const EVP_MD *md, FILE *out, ++ unsigned char *Seed, int SeedLen) ++ { ++ unsigned int i, j, k; ++ int ret = 0; ++ EVP_MD_CTX ctx; ++ unsigned char *m1, *m2, *m3, *p; ++ unsigned int mlen, m1len, m2len, m3len; ++ ++ EVP_MD_CTX_init(&ctx); ++ ++ if (SeedLen > EVP_MAX_MD_SIZE) ++ mlen = SeedLen; ++ else ++ mlen = EVP_MAX_MD_SIZE; ++ ++ m1 = OPENSSL_malloc(mlen); ++ m2 = OPENSSL_malloc(mlen); ++ m3 = OPENSSL_malloc(mlen); ++ ++ if (!m1 || !m2 || !m3) ++ goto mc_error; ++ ++ m1len = m2len = m3len = SeedLen; ++ memcpy(m1, Seed, SeedLen); ++ memcpy(m2, Seed, SeedLen); ++ memcpy(m3, Seed, SeedLen); ++ ++ fputs("\n", out); ++ ++ for (j = 0; j < 100; j++) ++ { ++ for (i = 0; i < 1000; i++) ++ { ++ EVP_DigestInit_ex(&ctx, md, NULL); ++ EVP_DigestUpdate(&ctx, m1, m1len); ++ EVP_DigestUpdate(&ctx, m2, m2len); ++ EVP_DigestUpdate(&ctx, m3, m3len); ++ p = m1; ++ m1 = m2; ++ m1len = m2len; ++ m2 = m3; ++ m2len = m3len; ++ m3 = p; ++ EVP_DigestFinal_ex(&ctx, m3, &m3len); ++ } ++ fprintf(out, "COUNT = %d\n", j); ++ fputs("MD = ", out); ++ for (k = 0; k < m3len; k++) ++ fprintf(out, "%02x", m3[k]); ++ fputs("\n\n", out); ++ memcpy(m1, m3, m3len); ++ memcpy(m2, m3, m3len); ++ m1len = m2len = m3len; ++ } ++ ++ ret = 1; ++ ++ mc_error: ++ if (m1) ++ OPENSSL_free(m1); ++ if (m2) ++ OPENSSL_free(m2); ++ if (m3) ++ OPENSSL_free(m3); ++ ++ EVP_MD_CTX_cleanup(&ctx); ++ ++ return ret; ++ } ++ ++#endif +diff -up openssl-1.0.1e/crypto/fips/cavs/fips_utl.h.fips openssl-1.0.1e/crypto/fips/cavs/fips_utl.h +--- openssl-1.0.1e/crypto/fips/cavs/fips_utl.h.fips 2013-10-04 11:48:04.182694181 +0200 ++++ openssl-1.0.1e/crypto/fips/cavs/fips_utl.h 2013-10-04 11:48:04.182694181 +0200 +@@ -0,0 +1,343 @@ ++/* ==================================================================== ++ * Copyright (c) 2007 The OpenSSL Project. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. All advertising materials mentioning features or use of this ++ * software must display the following acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" ++ * ++ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. For written permission, please contact ++ * openssl-core@openssl.org. ++ * ++ * 5. Products derived from this software may not be called "OpenSSL" ++ * nor may "OpenSSL" appear in their names without prior written ++ * permission of the OpenSSL Project. ++ * ++ * 6. Redistributions of any form whatsoever must retain the following ++ * acknowledgment: ++ * "This product includes software developed by the OpenSSL Project ++ * for use in the OpenSSL Toolkit (http://www.openssl.org/)" ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY ++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR ++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ */ ++ ++void do_print_errors(void) ++ { ++ const char *file, *data; ++ int line, flags; ++ unsigned long l; ++ while ((l = ERR_get_error_line_data(&file, &line, &data, &flags))) ++ { ++ fprintf(stderr, "ERROR:%lx:lib=%d,func=%d,reason=%d" ++ ":file=%s:line=%d:%s\n", ++ l, ERR_GET_LIB(l), ERR_GET_FUNC(l), ERR_GET_REASON(l), ++ file, line, flags & ERR_TXT_STRING ? data : ""); ++ } ++ } ++ ++int hex2bin(const char *in, unsigned char *out) ++ { ++ int n1, n2; ++ unsigned char ch; ++ ++ for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; ) ++ { /* first byte */ ++ if ((in[n1] >= '0') && (in[n1] <= '9')) ++ ch = in[n1++] - '0'; ++ else if ((in[n1] >= 'A') && (in[n1] <= 'F')) ++ ch = in[n1++] - 'A' + 10; ++ else if ((in[n1] >= 'a') && (in[n1] <= 'f')) ++ ch = in[n1++] - 'a' + 10; ++ else ++ return -1; ++ if(!in[n1]) ++ { ++ out[n2++]=ch; ++ break; ++ } ++ out[n2] = ch << 4; ++ /* second byte */ ++ if ((in[n1] >= '0') && (in[n1] <= '9')) ++ ch = in[n1++] - '0'; ++ else if ((in[n1] >= 'A') && (in[n1] <= 'F')) ++ ch = in[n1++] - 'A' + 10; ++ else if ((in[n1] >= 'a') && (in[n1] <= 'f')) ++ ch = in[n1++] - 'a' + 10; ++ else ++ return -1; ++ out[n2++] |= ch; ++ } ++ return n2; ++ } ++ ++unsigned char *hex2bin_m(const char *in, long *plen) ++ { ++ unsigned char *p; ++ p = OPENSSL_malloc((strlen(in) + 1)/2); ++ *plen = hex2bin(in, p); ++ return p; ++ } ++ ++int do_hex2bn(BIGNUM **pr, const char *in) ++ { ++ unsigned char *p; ++ long plen; ++ int r = 0; ++ p = hex2bin_m(in, &plen); ++ if (!p) ++ return 0; ++ if (!*pr) ++ *pr = BN_new(); ++ if (!*pr) ++ return 0; ++ if (BN_bin2bn(p, plen, *pr)) ++ r = 1; ++ OPENSSL_free(p); ++ return r; ++ } ++ ++int do_bn_print(FILE *out, BIGNUM *bn) ++ { ++ int len, i; ++ unsigned char *tmp; ++ len = BN_num_bytes(bn); ++ if (len == 0) ++ { ++ fputs("00", out); ++ return 1; ++ } ++ ++ tmp = OPENSSL_malloc(len); ++ if (!tmp) ++ { ++ fprintf(stderr, "Memory allocation error\n"); ++ return 0; ++ } ++ BN_bn2bin(bn, tmp); ++ for (i = 0; i < len; i++) ++ fprintf(out, "%02x", tmp[i]); ++ OPENSSL_free(tmp); ++ return 1; ++ } ++ ++int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn) ++ { ++ int r; ++ fprintf(out, "%s = ", name); ++ r = do_bn_print(out, bn); ++ if (!r) ++ return 0; ++ fputs("\n", out); ++ return 1; ++ } ++ ++int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf) ++ { ++ char *keyword, *value, *p, *q; ++ strcpy(linebuf, olinebuf); ++ keyword = linebuf; ++ /* Skip leading space */ ++ while (isspace((unsigned char)*keyword)) ++ keyword++; ++ ++ /* Look for = sign */ ++ p = strchr(linebuf, '='); ++ ++ /* If no '=' exit */ ++ if (!p) ++ return 0; ++ ++ q = p - 1; ++ ++ /* Remove trailing space */ ++ while (isspace((unsigned char)*q)) ++ *q-- = 0; ++ ++ *p = 0; ++ value = p + 1; ++ ++ /* Remove leading space from value */ ++ while (isspace((unsigned char)*value)) ++ value++; ++ ++ /* Remove trailing space from value */ ++ p = value + strlen(value) - 1; ++ ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ ++ *pkw = keyword; ++ *pval = value; ++ return 1; ++ } ++ ++BIGNUM *hex2bn(const char *in) ++ { ++ BIGNUM *p=NULL; ++ ++ if (!do_hex2bn(&p, in)) ++ return NULL; ++ ++ return p; ++ } ++ ++int bin2hex(const unsigned char *in,int len,char *out) ++ { ++ int n1, n2; ++ unsigned char ch; ++ ++ for (n1=0,n2=0 ; n1 < len ; ++n1) ++ { ++ ch=in[n1] >> 4; ++ if (ch <= 0x09) ++ out[n2++]=ch+'0'; ++ else ++ out[n2++]=ch-10+'a'; ++ ch=in[n1] & 0x0f; ++ if(ch <= 0x09) ++ out[n2++]=ch+'0'; ++ else ++ out[n2++]=ch-10+'a'; ++ } ++ out[n2]='\0'; ++ return n2; ++ } ++ ++void pv(const char *tag,const unsigned char *val,int len) ++ { ++ char obuf[2048]; ++ ++ bin2hex(val,len,obuf); ++ printf("%s = %s\n",tag,obuf); ++ } ++ ++/* To avoid extensive changes to test program at this stage just convert ++ * the input line into an acceptable form. Keyword lines converted to form ++ * "keyword = value\n" no matter what white space present, all other lines ++ * just have leading and trailing space removed. ++ */ ++ ++int tidy_line(char *linebuf, char *olinebuf) ++ { ++ char *keyword, *value, *p, *q; ++ strcpy(linebuf, olinebuf); ++ keyword = linebuf; ++ /* Skip leading space */ ++ while (isspace((unsigned char)*keyword)) ++ keyword++; ++ /* Look for = sign */ ++ p = strchr(linebuf, '='); ++ ++ /* If no '=' just chop leading, trailing ws */ ++ if (!p) ++ { ++ p = keyword + strlen(keyword) - 1; ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ strcpy(olinebuf, keyword); ++ strcat(olinebuf, "\n"); ++ return 1; ++ } ++ ++ q = p - 1; ++ ++ /* Remove trailing space */ ++ while (isspace((unsigned char)*q)) ++ *q-- = 0; ++ ++ *p = 0; ++ value = p + 1; ++ ++ /* Remove leading space from value */ ++ while (isspace((unsigned char)*value)) ++ value++; ++ ++ /* Remove trailing space from value */ ++ p = value + strlen(value) - 1; ++ ++ while (*p == '\n' || isspace((unsigned char)*p)) ++ *p-- = 0; ++ ++ strcpy(olinebuf, keyword); ++ strcat(olinebuf, " = "); ++ strcat(olinebuf, value); ++ strcat(olinebuf, "\n"); ++ ++ return 1; ++ } ++ ++/* NB: this return the number of _bits_ read */ ++int bint2bin(const char *in, int len, unsigned char *out) ++ { ++ int n; ++ ++ memset(out,0,len); ++ for(n=0 ; n < len ; ++n) ++ if(in[n] == '1') ++ out[n/8]|=(0x80 >> (n%8)); ++ return len; ++ } ++ ++int bin2bint(const unsigned char *in,int len,char *out) ++ { ++ int n; ++ ++ for(n=0 ; n < len ; ++n) ++ out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0'; ++ return n; ++ } ++ ++/*-----------------------------------------------*/ ++ ++void PrintValue(char *tag, unsigned char *val, int len) ++{ ++#if VERBOSE ++ char obuf[2048]; ++ int olen; ++ olen = bin2hex(val, len, obuf); ++ printf("%s = %.*s\n", tag, olen, obuf); ++#endif ++} ++ ++void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode) ++ { ++ char obuf[2048]; ++ int olen; ++ ++ if(bitmode) ++ olen=bin2bint(val,len,obuf); ++ else ++ olen=bin2hex(val,len,obuf); ++ ++ fprintf(rfp, "%s = %.*s\n", tag, olen, obuf); ++#if VERBOSE ++ printf("%s = %.*s\n", tag, olen, obuf); ++#endif ++ } ++ +diff -up openssl-1.0.1e/crypto/fips/fips_aes_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_aes_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_aes_selftest.c.fips 2013-10-04 11:48:04.182694181 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_aes_selftest.c 2013-10-04 11:48:04.182694181 +0200 +@@ -0,0 +1,359 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips.c.fips openssl-1.0.1e/crypto/fips/fips.c +--- openssl-1.0.1e/crypto/fips/fips.c.fips 2013-10-04 11:48:04.182694181 +0200 ++++ openssl-1.0.1e/crypto/fips/fips.c 2013-10-04 11:48:04.182694181 +0200 +@@ -0,0 +1,491 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_cmac_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_cmac_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_cmac_selftest.c.fips 2013-10-04 11:48:04.183694204 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_cmac_selftest.c 2013-10-04 11:48:04.183694204 +0200 +@@ -0,0 +1,161 @@ ++/* ==================================================================== ++ * 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; nnid); ++ 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.1e/crypto/fips/fips_des_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_des_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_des_selftest.c.fips 2013-10-04 11:48:04.183694204 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_des_selftest.c 2013-10-04 11:48:04.183694204 +0200 +@@ -0,0 +1,147 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_drbg_ctr.c.fips openssl-1.0.1e/crypto/fips/fips_drbg_ctr.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_ctr.c.fips 2013-10-04 11:48:04.183694204 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_ctr.c 2013-10-04 11:48:04.183694204 +0200 +@@ -0,0 +1,436 @@ ++/* 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.1e/crypto/fips/fips_drbg_hash.c.fips openssl-1.0.1e/crypto/fips/fips_drbg_hash.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_hash.c.fips 2013-10-04 11:48:04.183694204 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_hash.c 2013-10-04 11:48:04.183694204 +0200 +@@ -0,0 +1,378 @@ ++/* 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.1e/crypto/fips/fips_drbg_hmac.c.fips openssl-1.0.1e/crypto/fips/fips_drbg_hmac.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_hmac.c.fips 2013-10-04 11:48:04.183694204 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_hmac.c 2013-10-04 11:48:04.183694204 +0200 +@@ -0,0 +1,281 @@ ++/* 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.1e/crypto/fips/fips_drbg_lib.c.fips openssl-1.0.1e/crypto/fips/fips_drbg_lib.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_lib.c.fips 2013-10-04 11:48:04.184694226 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_lib.c 2013-10-04 11:48:04.184694226 +0200 +@@ -0,0 +1,578 @@ ++/* 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.1e/crypto/fips/fips_drbg_rand.c.fips openssl-1.0.1e/crypto/fips/fips_drbg_rand.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_rand.c.fips 2013-10-04 11:48:04.184694226 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_rand.c 2013-10-04 11:48:04.184694226 +0200 +@@ -0,0 +1,172 @@ ++/* 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; ++ CRYPTO_r_lock(CRYPTO_LOCK_RAND); ++ rv = dctx->status == DRBG_STATUS_READY ? 1 : 0; ++ CRYPTO_r_unlock(CRYPTO_LOCK_RAND); ++ return rv; ++ } ++ ++static void fips_drbg_cleanup(void) ++ { ++ DRBG_CTX *dctx = &ossl_dctx; ++ CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ FIPS_drbg_uninstantiate(dctx); ++ CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ } ++ ++static int fips_drbg_seed(const void *seed, int seedlen) ++ { ++ DRBG_CTX *dctx = &ossl_dctx; ++ if (dctx->rand_seed_cb) ++ return dctx->rand_seed_cb(dctx, seed, seedlen); ++ return 1; ++ } ++ ++static int fips_drbg_add(const void *seed, int seedlen, ++ double add_entropy) ++ { ++ DRBG_CTX *dctx = &ossl_dctx; ++ if (dctx->rand_add_cb) ++ return dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); ++ return 1; ++ } ++ ++static const RAND_METHOD rand_drbg_meth = ++ { ++ fips_drbg_seed, ++ fips_drbg_bytes, ++ fips_drbg_cleanup, ++ fips_drbg_add, ++ fips_drbg_pseudo, ++ fips_drbg_status ++ }; ++ ++const RAND_METHOD *FIPS_drbg_method(void) ++ { ++ return &rand_drbg_meth; ++ } ++ +diff -up openssl-1.0.1e/crypto/fips/fips_drbg_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_drbg_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_selftest.c.fips 2013-10-04 11:48:04.184694226 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_selftest.c 2013-10-04 11:48:04.184694226 +0200 +@@ -0,0 +1,862 @@ ++/* 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.1e/crypto/fips/fips_drbg_selftest.h.fips openssl-1.0.1e/crypto/fips/fips_drbg_selftest.h +--- openssl-1.0.1e/crypto/fips/fips_drbg_selftest.h.fips 2013-10-04 11:48:04.185694249 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_selftest.h 2013-10-04 11:48:04.185694249 +0200 +@@ -0,0 +1,2335 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_dsa_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_dsa_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_dsa_selftest.c.fips 2013-10-04 11:48:04.185694249 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_dsa_selftest.c 2013-10-04 11:48:04.185694249 +0200 +@@ -0,0 +1,193 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_enc.c.fips openssl-1.0.1e/crypto/fips/fips_enc.c +--- openssl-1.0.1e/crypto/fips/fips_enc.c.fips 2013-10-04 11:48:04.185694249 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_enc.c 2013-10-04 11:48:04.185694249 +0200 +@@ -0,0 +1,191 @@ ++/* 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.1e/crypto/fips/fips.h.fips openssl-1.0.1e/crypto/fips/fips.h +--- openssl-1.0.1e/crypto/fips/fips.h.fips 2013-10-04 11:48:04.186694271 +0200 ++++ openssl-1.0.1e/crypto/fips/fips.h 2013-10-04 11:48:04.186694271 +0200 +@@ -0,0 +1,279 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_hmac_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_hmac_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_hmac_selftest.c.fips 2013-10-04 11:48:04.186694271 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_hmac_selftest.c 2013-10-04 11:48:04.186694271 +0200 +@@ -0,0 +1,137 @@ ++/* ==================================================================== ++ * 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; nalg)(); ++ HMAC(md,t->key,strlen(t->key), ++ (const unsigned char *)t->iv,strlen(t->iv), ++ out,&outlen); ++ ++ if(memcmp(out,t->kaval,outlen)) ++ { ++ FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED); ++ return 0; ++ } ++ } ++ return 1; ++ } ++#endif +diff -up openssl-1.0.1e/crypto/fips/fips_locl.h.fips openssl-1.0.1e/crypto/fips/fips_locl.h +--- openssl-1.0.1e/crypto/fips/fips_locl.h.fips 2013-10-04 11:48:04.186694271 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_locl.h 2013-10-04 11:48:04.186694271 +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.1e/crypto/fips/fips_md.c.fips openssl-1.0.1e/crypto/fips/fips_md.c +--- openssl-1.0.1e/crypto/fips/fips_md.c.fips 2013-10-04 11:48:04.186694271 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_md.c 2013-10-04 11:48:04.186694271 +0200 +@@ -0,0 +1,145 @@ ++/* 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.1e/crypto/fips/fips_post.c.fips openssl-1.0.1e/crypto/fips/fips_post.c +--- openssl-1.0.1e/crypto/fips/fips_post.c.fips 2013-10-04 11:48:04.186694271 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_post.c 2013-10-04 11:48:04.186694271 +0200 +@@ -0,0 +1,205 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_rand.c.fips openssl-1.0.1e/crypto/fips/fips_rand.c +--- openssl-1.0.1e/crypto/fips/fips_rand.c.fips 2013-10-04 11:48:04.187694294 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_rand.c 2013-10-04 11:48:04.187694294 +0200 +@@ -0,0 +1,457 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_rand.h.fips openssl-1.0.1e/crypto/fips/fips_rand.h +--- openssl-1.0.1e/crypto/fips/fips_rand.h.fips 2013-10-04 11:48:04.187694294 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_rand.h 2013-10-04 11:48:04.187694294 +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. ++ * ++ */ ++ ++#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.1e/crypto/fips/fips_rand_lcl.h.fips openssl-1.0.1e/crypto/fips/fips_rand_lcl.h +--- openssl-1.0.1e/crypto/fips/fips_rand_lcl.h.fips 2013-10-04 11:48:04.187694294 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_rand_lcl.h 2013-10-04 11:48:04.187694294 +0200 +@@ -0,0 +1,219 @@ ++/* 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.1e/crypto/fips/fips_rand_lib.c.fips openssl-1.0.1e/crypto/fips/fips_rand_lib.c +--- openssl-1.0.1e/crypto/fips/fips_rand_lib.c.fips 2013-10-04 11:48:04.187694294 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_rand_lib.c 2013-10-04 11:48:04.187694294 +0200 +@@ -0,0 +1,191 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_rand_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_rand_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_rand_selftest.c.fips 2013-10-04 11:48:04.187694294 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_rand_selftest.c 2013-10-04 11:48:04.187694294 +0200 +@@ -0,0 +1,183 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/fips_randtest.c.fips openssl-1.0.1e/crypto/fips/fips_randtest.c +--- openssl-1.0.1e/crypto/fips/fips_randtest.c.fips 2013-10-04 11:48:04.188694316 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_randtest.c 2013-10-04 11:48:04.187694294 +0200 +@@ -0,0 +1,250 @@ ++/* 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.1e/crypto/fips/fips_rsa_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c.fips 2013-10-04 11:48:04.188694316 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c 2013-10-04 11:48:04.188694316 +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.1e/crypto/fips/fips_rsa_x931g.c.fips openssl-1.0.1e/crypto/fips/fips_rsa_x931g.c +--- openssl-1.0.1e/crypto/fips/fips_rsa_x931g.c.fips 2013-10-04 11:48:04.188694316 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_rsa_x931g.c 2013-10-04 11:48:04.188694316 +0200 +@@ -0,0 +1,282 @@ ++/* 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.1e/crypto/fips/fips_sha_selftest.c.fips openssl-1.0.1e/crypto/fips/fips_sha_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_sha_selftest.c.fips 2013-10-04 11:48:04.188694316 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_sha_selftest.c 2013-10-04 11:48:04.188694316 +0200 +@@ -0,0 +1,140 @@ ++/* ==================================================================== ++ * 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 ++#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[2]; ++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; ++ 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(void); ++ 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()&~vec; ++ } ++ else ++ vec = OPENSSL_ia32_cpuid(); ++ ++ /* ++ * |(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); ++} ++#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.1e/crypto/fips/fips_test_suite.c.fips openssl-1.0.1e/crypto/fips/fips_test_suite.c +--- openssl-1.0.1e/crypto/fips/fips_test_suite.c.fips 2013-10-04 11:48:04.189694339 +0200 ++++ openssl-1.0.1e/crypto/fips/fips_test_suite.c 2013-10-04 11:48:04.189694339 +0200 +@@ -0,0 +1,588 @@ ++/* ==================================================================== ++ * 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.1e/crypto/fips/Makefile.fips openssl-1.0.1e/crypto/fips/Makefile +--- openssl-1.0.1e/crypto/fips/Makefile.fips 2013-10-04 11:48:04.189694339 +0200 ++++ openssl-1.0.1e/crypto/fips/Makefile 2013-10-04 11:48:04.189694339 +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.1e/crypto/hmac/hmac.c.fips openssl-1.0.1e/crypto/hmac/hmac.c +--- openssl-1.0.1e/crypto/hmac/hmac.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/hmac/hmac.c 2013-10-04 11:48:04.189694339 +0200 +@@ -81,11 +81,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 + +@@ -99,6 +94,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)); +@@ -155,10 +157,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 + return EVP_DigestUpdate(&ctx->md_ctx,data,len); + } + +@@ -166,10 +164,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 (!EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i)) + goto err; +@@ -209,13 +203,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.1e/crypto/mdc2/mdc2dgst.c.fips openssl-1.0.1e/crypto/mdc2/mdc2dgst.c +--- openssl-1.0.1e/crypto/mdc2/mdc2dgst.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/mdc2/mdc2dgst.c 2013-10-04 11:48:04.189694339 +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.1e/crypto/md2/md2_dgst.c.fips openssl-1.0.1e/crypto/md2/md2_dgst.c +--- openssl-1.0.1e/crypto/md2/md2_dgst.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/md2/md2_dgst.c 2013-10-04 11:48:04.189694339 +0200 +@@ -62,6 +62,11 @@ + #include + #include + #include ++#ifdef OPENSSL_FIPS ++#include ++#endif ++ ++#include + + const char MD2_version[]="MD2" OPENSSL_VERSION_PTEXT; + +@@ -116,7 +121,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.1e/crypto/md4/md4_dgst.c.fips openssl-1.0.1e/crypto/md4/md4_dgst.c +--- openssl-1.0.1e/crypto/md4/md4_dgst.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/md4/md4_dgst.c 2013-10-04 11:48:04.190694362 +0200 +@@ -71,7 +71,7 @@ const char MD4_version[]="MD4" OPENSSL_V + #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.1e/crypto/md5/md5_dgst.c.fips openssl-1.0.1e/crypto/md5/md5_dgst.c +--- openssl-1.0.1e/crypto/md5/md5_dgst.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/md5/md5_dgst.c 2013-10-04 11:48:04.190694362 +0200 +@@ -71,7 +71,7 @@ const char MD5_version[]="MD5" OPENSSL_V + #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.1e/crypto/o_fips.c.fips openssl-1.0.1e/crypto/o_fips.c +--- openssl-1.0.1e/crypto/o_fips.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/o_fips.c 2013-10-04 11:48:04.190694362 +0200 +@@ -79,6 +79,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.1e/crypto/o_init.c.fips openssl-1.0.1e/crypto/o_init.c +--- openssl-1.0.1e/crypto/o_init.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/o_init.c 2013-10-04 11:48:04.190694362 +0200 +@@ -55,28 +55,68 @@ + #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 + + /* Perform any essential OpenSSL initialization operations. + * Currently only sets FIPS callbacks + */ + +-void OPENSSL_init(void) ++void OPENSSL_init_library(void) + { + static int done = 0; + if (done) + return; + done = 1; + #ifdef OPENSSL_FIPS +- FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); +- FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); +- FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); + RAND_init_fips(); ++ init_fips_mode(); ++ if (!FIPS_mode()) ++ { ++ /* Clean up prematurely set default rand method */ ++ RAND_set_rand_method(NULL); ++ } + #endif + #if 0 + fprintf(stderr, "Called OPENSSL_init\n"); + #endif + } + ++void OPENSSL_init(void) ++ { ++ OPENSSL_init_library(); ++ } +diff -up openssl-1.0.1e/crypto/opensslconf.h.in.fips openssl-1.0.1e/crypto/opensslconf.h.in +--- openssl-1.0.1e/crypto/opensslconf.h.in.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/opensslconf.h.in 2013-10-04 11:48:04.190694362 +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.1e/crypto/pkcs12/p12_crt.c.fips openssl-1.0.1e/crypto/pkcs12/p12_crt.c +--- openssl-1.0.1e/crypto/pkcs12/p12_crt.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/pkcs12/p12_crt.c 2013-10-04 11:48:04.190694362 +0200 +@@ -59,6 +59,10 @@ + #include + #include "cryptlib.h" + #include ++#ifdef OPENSSL_FIPS ++#include ++#endif ++ + + + static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); +@@ -90,7 +94,14 @@ PKCS12 *PKCS12_create(char *pass, char * + + /* Set defaults */ + if (!nid_cert) ++ { ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode()) ++ nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; ++ else ++#endif + nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; ++ } + if (!nid_key) + nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + if (!iter) +diff -up openssl-1.0.1e/crypto/rand/md_rand.c.fips openssl-1.0.1e/crypto/rand/md_rand.c +--- openssl-1.0.1e/crypto/rand/md_rand.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rand/md_rand.c 2013-10-04 11:48:04.190694362 +0200 +@@ -389,7 +389,10 @@ static int ssleay_rand_bytes(unsigned ch + 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.1e/crypto/rand/rand.h.fips openssl-1.0.1e/crypto/rand/rand.h +--- openssl-1.0.1e/crypto/rand/rand.h.fips 2013-10-04 11:48:03.945688829 +0200 ++++ openssl-1.0.1e/crypto/rand/rand.h 2013-10-04 11:48:04.190694362 +0200 +@@ -133,15 +133,33 @@ 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_ERROR_INITIALISING_DRBG 102 +-#define RAND_R_ERROR_INSTANTIATING_DRBG 103 +-#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 ++#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.1e/crypto/ripemd/rmd_dgst.c.fips openssl-1.0.1e/crypto/ripemd/rmd_dgst.c +--- openssl-1.0.1e/crypto/ripemd/rmd_dgst.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/ripemd/rmd_dgst.c 2013-10-04 11:48:04.191694385 +0200 +@@ -70,7 +70,7 @@ const char RMD160_version[]="RIPE-MD160" + 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.1e/crypto/rsa/rsa_crpt.c.fips openssl-1.0.1e/crypto/rsa/rsa_crpt.c +--- openssl-1.0.1e/crypto/rsa/rsa_crpt.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_crpt.c 2013-10-04 11:48:04.191694385 +0200 +@@ -90,10 +90,9 @@ int RSA_private_encrypt(int flen, const + RSA *rsa, int padding) + { + #ifdef OPENSSL_FIPS +- if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) +- && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) ++ if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { +- RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); ++ RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } + #endif +@@ -118,10 +117,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)) ++ if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) + { +- RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); ++ RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } + #endif +diff -up openssl-1.0.1e/crypto/rsa/rsa_eay.c.fips openssl-1.0.1e/crypto/rsa/rsa_eay.c +--- openssl-1.0.1e/crypto/rsa/rsa_eay.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_eay.c 2013-10-04 11:48:04.191694385 +0200 +@@ -114,6 +114,10 @@ + #include + #include + #include ++#include ++#ifdef OPENSSL_FIPS ++#include ++#endif + + #ifndef RSA_NULL + +@@ -138,7 +142,7 @@ static RSA_METHOD rsa_pkcs1_eay_meth={ + BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */ + RSA_eay_init, + RSA_eay_finish, +- 0, /* flags */ ++ RSA_FLAG_FIPS_METHOD, /* flags */ + NULL, + 0, /* rsa_sign */ + 0, /* rsa_verify */ +@@ -158,6 +162,24 @@ 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); +@@ -361,6 +383,24 @@ 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); + f = BN_CTX_get(ctx); +@@ -504,6 +544,24 @@ 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); + f = BN_CTX_get(ctx); +@@ -639,6 +697,24 @@ 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); +@@ -897,6 +973,9 @@ err: + + 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.1e/crypto/rsa/rsa_err.c.fips openssl-1.0.1e/crypto/rsa/rsa_err.c +--- openssl-1.0.1e/crypto/rsa/rsa_err.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_err.c 2013-10-04 11:48:04.191694385 +0200 +@@ -121,6 +121,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"}, + {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, +diff -up openssl-1.0.1e/crypto/rsa/rsa_gen.c.fips openssl-1.0.1e/crypto/rsa/rsa_gen.c +--- openssl-1.0.1e/crypto/rsa/rsa_gen.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_gen.c 2013-10-04 11:48:04.191694385 +0200 +@@ -69,6 +69,78 @@ + #include + #ifdef OPENSSL_FIPS + #include ++#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, BN_GENCB *cb); +@@ -81,7 +153,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); +@@ -90,10 +162,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_generate_key_ex(rsa, bits, e_value, cb); +-#endif + return rsa_builtin_keygen(rsa, bits, e_value, cb); + } + +@@ -105,6 +173,23 @@ 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; + BN_CTX_start(ctx); +@@ -216,6 +301,17 @@ static int rsa_builtin_keygen(RSA *rsa, + p = rsa->p; + 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.1e/crypto/rsa/rsa.h.fips openssl-1.0.1e/crypto/rsa/rsa.h +--- openssl-1.0.1e/crypto/rsa/rsa.h.fips 2013-10-04 11:48:04.075691765 +0200 ++++ openssl-1.0.1e/crypto/rsa/rsa.h 2013-10-04 11:48:04.192694407 +0200 +@@ -164,6 +164,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 +@@ -290,6 +292,11 @@ RSA * RSA_generate_key(int bits, unsigne + + /* 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 */ +@@ -487,7 +494,7 @@ void ERR_load_RSA_strings(void); + #define RSA_F_RSA_PADDING_ADD_NONE 107 + #define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 + #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 +@@ -500,20 +507,22 @@ 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_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 +@@ -542,21 +551,22 @@ void ERR_load_RSA_strings(void); + #define RSA_R_INVALID_MGF1_MD 156 + #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_P_NOT_PRIME 128 +diff -up openssl-1.0.1e/crypto/rsa/rsa_lib.c.fips openssl-1.0.1e/crypto/rsa/rsa_lib.c +--- openssl-1.0.1e/crypto/rsa/rsa_lib.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_lib.c 2013-10-04 11:48:04.192694407 +0200 +@@ -84,6 +84,13 @@ 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; + } + +@@ -91,18 +98,11 @@ const RSA_METHOD *RSA_get_default_method + { + 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 + default_RSA_meth=RSA_null_method(); + #else + default_RSA_meth=RSA_PKCS1_SSLeay(); + #endif +-#endif + } + + return default_RSA_meth; +@@ -118,6 +118,13 @@ int RSA_set_method(RSA *rsa, const RSA_M + /* NB: The caller is specifically setting a method, so it's not up to us + * 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); + #ifndef OPENSSL_NO_ENGINE +@@ -170,6 +177,18 @@ 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; +@@ -188,7 +207,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 +diff -up openssl-1.0.1e/crypto/rsa/rsa_pmeth.c.fips openssl-1.0.1e/crypto/rsa/rsa_pmeth.c +--- openssl-1.0.1e/crypto/rsa/rsa_pmeth.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_pmeth.c 2013-10-04 11:48:04.192694407 +0200 +@@ -206,22 +206,6 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *c + 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) + { +@@ -354,19 +338,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.1e/crypto/rsa/rsa_sign.c.fips openssl-1.0.1e/crypto/rsa/rsa_sign.c +--- openssl-1.0.1e/crypto/rsa/rsa_sign.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_sign.c 2013-10-04 11:48:04.192694407 +0200 +@@ -138,7 +138,8 @@ 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 +@@ -178,8 +179,8 @@ 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; +@@ -196,7 +197,8 @@ 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; + /* Oddball MDC2 case: signature can be OCTET STRING. +diff -up openssl-1.0.1e/crypto/sha/sha.h.fips openssl-1.0.1e/crypto/sha/sha.h +--- openssl-1.0.1e/crypto/sha/sha.h.fips 2013-10-04 11:48:03.867687068 +0200 ++++ openssl-1.0.1e/crypto/sha/sha.h 2013-10-04 11:48:04.192694407 +0200 +@@ -116,9 +116,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); +@@ -141,10 +138,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 +185,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.1e/crypto/sha/sha_locl.h.fips openssl-1.0.1e/crypto/sha/sha_locl.h +--- openssl-1.0.1e/crypto/sha/sha_locl.h.fips 2013-10-04 11:48:03.870687135 +0200 ++++ openssl-1.0.1e/crypto/sha/sha_locl.h 2013-10-04 11:48:04.192694407 +0200 +@@ -123,11 +123,14 @@ void sha1_block_data_order (SHA_CTX *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.1e/crypto/sha/sha256.c.fips openssl-1.0.1e/crypto/sha/sha256.c +--- openssl-1.0.1e/crypto/sha/sha256.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/sha/sha256.c 2013-10-04 11:48:04.193694429 +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; + c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; +@@ -29,6 +36,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; + c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; +diff -up openssl-1.0.1e/crypto/sha/sha512.c.fips openssl-1.0.1e/crypto/sha/sha512.c +--- openssl-1.0.1e/crypto/sha/sha512.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/sha/sha512.c 2013-10-04 11:48:04.193694429 +0200 +@@ -5,6 +5,10 @@ + * ==================================================================== + */ + #include ++#ifdef OPENSSL_FIPS ++#include ++#endif ++ + #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) + /* + * IMPLEMENTATION NOTES. +@@ -61,6 +65,9 @@ const char SHA512_version[]="SHA-512" OP + + 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); +@@ -77,6 +84,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.1e/crypto/whrlpool/wp_dgst.c.fips openssl-1.0.1e/crypto/whrlpool/wp_dgst.c +--- openssl-1.0.1e/crypto/whrlpool/wp_dgst.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/whrlpool/wp_dgst.c 2013-10-04 11:48:04.193694429 +0200 +@@ -55,7 +55,7 @@ + #include + #include + +-fips_md_init(WHIRLPOOL) ++nonfips_md_init(WHIRLPOOL) + { + memset (c,0,sizeof(*c)); + return(1); +diff -up openssl-1.0.1e/Makefile.org.fips openssl-1.0.1e/Makefile.org +--- openssl-1.0.1e/Makefile.org.fips 2013-10-04 11:48:04.157693616 +0200 ++++ openssl-1.0.1e/Makefile.org 2013-10-04 11:48:04.193694429 +0200 +@@ -136,6 +136,9 @@ FIPSCANLIB= + + BASEADDR= + ++# Non-empty if FIPS enabled ++FIPS= ++ + DIRS= crypto ssl engines apps test tools + ENGDIRS= ccgost + SHLIBDIRS= crypto ssl +@@ -148,7 +151,7 @@ SDIRS= \ + bn ec rsa dsa ecdsa dh ecdh dso engine \ + buffer bio stack lhash rand err \ + evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \ +- cms pqueue ts jpake srp store cmac ++ cms pqueue ts jpake srp store cmac fips + # keep in mind that the above list is adjusted by ./Configure + # according to no-xxx arguments... + +@@ -237,6 +240,7 @@ BUILDENV= PLATFORM='$(PLATFORM)' PROCESS + 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.1e/ssl/d1_srvr.c.fips openssl-1.0.1e/ssl/d1_srvr.c +--- openssl-1.0.1e/ssl/d1_srvr.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/d1_srvr.c 2013-10-04 11:48:04.193694429 +0200 +@@ -1372,6 +1372,8 @@ int dtls1_send_server_key_exchange(SSL * + j=0; + for (num=2; num > 0; num--) + { ++ EVP_MD_CTX_set_flags(&md_ctx, ++ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_DigestInit_ex(&md_ctx,(num == 2) + ?s->ctx->md5:s->ctx->sha1, NULL); + EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); +diff -up openssl-1.0.1e/ssl/ssl_algs.c.fips openssl-1.0.1e/ssl/ssl_algs.c +--- openssl-1.0.1e/ssl/ssl_algs.c.fips 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/ssl_algs.c 2013-10-04 11:48:04.193694429 +0200 +@@ -64,6 +64,12 @@ + 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()); +@@ -137,6 +143,50 @@ 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 returned is a STACK_OF(SSL_COMP), but that can diff --git a/SOURCES/openssl-1.0.1e-issuer-hash.patch b/SOURCES/openssl-1.0.1e-issuer-hash.patch new file mode 100755 index 00000000..0f3bfdb4 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-issuer-hash.patch @@ -0,0 +1,11 @@ +diff -up openssl-1.0.1e/crypto/x509/x509_cmp.c.issuer-hash openssl-1.0.1e/crypto/x509/x509_cmp.c +--- openssl-1.0.1e/crypto/x509/x509_cmp.c.issuer-hash 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/x509/x509_cmp.c 2013-02-19 12:46:11.315788592 +0100 +@@ -85,6 +85,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.1e-manfix.patch b/SOURCES/openssl-1.0.1e-manfix.patch new file mode 100755 index 00000000..4ba2abbf --- /dev/null +++ b/SOURCES/openssl-1.0.1e-manfix.patch @@ -0,0 +1,555 @@ +diff -up openssl-1.0.1e/doc/apps/cms.pod.manfix openssl-1.0.1e/doc/apps/cms.pod +--- openssl-1.0.1e/doc/apps/cms.pod.manfix 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/cms.pod 2013-09-12 11:17:42.147092310 +0200 +@@ -450,28 +450,28 @@ remains DER. + + =over 4 + +-=item 0 ++=item C<0> + + the operation was completely successfully. + +-=item 1 ++=item C<1> + + an error occurred parsing the command options. + +-=item 2 ++=item C<2> + + one of the input files could not be read. + +-=item 3 ++=item C<3> + + an error occurred creating the CMS file or when reading the MIME + message. + +-=item 4 ++=item C<4> + + an error occurred decrypting or verifying the message. + +-=item 5 ++=item C<5> + + the message was verified correctly but an error occurred writing out + the signers certificates. +diff -up openssl-1.0.1e/doc/apps/ec.pod.manfix openssl-1.0.1e/doc/apps/ec.pod +--- openssl-1.0.1e/doc/apps/ec.pod.manfix 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/ec.pod 2013-09-12 11:17:42.147092310 +0200 +@@ -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.1e/doc/apps/openssl.pod.manfix openssl-1.0.1e/doc/apps/openssl.pod +--- openssl-1.0.1e/doc/apps/openssl.pod.manfix 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/openssl.pod 2013-09-12 11:17:42.148092331 +0200 +@@ -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.1e/doc/apps/s_client.pod.manfix openssl-1.0.1e/doc/apps/s_client.pod +--- openssl-1.0.1e/doc/apps/s_client.pod.manfix 2013-09-12 11:17:41.517078502 +0200 ++++ openssl-1.0.1e/doc/apps/s_client.pod 2013-09-12 11:17:42.149092353 +0200 +@@ -32,9 +32,14 @@ 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>] ++[B<-no_tls1_1>] ++[B<-no_tls1_2>] + [B<-bugs>] + [B<-cipher cipherlist>] + [B<-starttls protocol>] +@@ -44,6 +49,7 @@ B B + [B<-sess_out filename>] + [B<-sess_in filename>] + [B<-rand file(s)>] ++[B<-nextprotoneg protocols>] + + =head1 DESCRIPTION + +@@ -182,7 +188,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<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> ++=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 disable the use of certain SSL or TLS protocols. By default + the initial handshake uses a method which should be compatible with all +@@ -243,6 +249,17 @@ Multiple files can be specified separate + The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for + all others. + ++=item B<-nextprotoneg protocols> ++ ++enable Next Protocol Negotiation TLS extension and provide a list of ++comma-separated protocol names that the client should advertise ++support for. The list should contain most wanted protocols first. ++Protocol names are printable ASCII strings, for example "http/1.1" or ++"spdy/3". ++Empty list of protocols is treated specially and will cause the client to ++advertise support for the TLS extension but disconnect just after ++reciving ServerHello with a list of server supported protocols. ++ + =back + + =head1 CONNECTED COMMANDS +diff -up openssl-1.0.1e/doc/apps/smime.pod.manfix openssl-1.0.1e/doc/apps/smime.pod +--- openssl-1.0.1e/doc/apps/smime.pod.manfix 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/smime.pod 2013-09-12 11:17:42.150092375 +0200 +@@ -308,28 +308,28 @@ remains DER. + + =over 4 + +-=item 0 ++=item C<0> + + the operation was completely successfully. + +-=item 1 ++=item C<1> + + an error occurred parsing the command options. + +-=item 2 ++=item C<2> + + one of the input files could not be read. + +-=item 3 ++=item C<3> + + an error occurred creating the PKCS#7 file or when reading the MIME + message. + +-=item 4 ++=item C<4> + + an error occurred decrypting or verifying the message. + +-=item 5 ++=item C<5> + + the message was verified correctly but an error occurred writing out + the signers certificates. +diff -up openssl-1.0.1e/doc/apps/s_server.pod.manfix openssl-1.0.1e/doc/apps/s_server.pod +--- openssl-1.0.1e/doc/apps/s_server.pod.manfix 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/s_server.pod 2013-09-12 11:17:42.150092375 +0200 +@@ -40,10 +40,16 @@ 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>] ++[B<-no_tls1_1>] ++[B<-no_tls1_2>] + [B<-no_dhe>] ++[B<-no_ecdhe>] + [B<-bugs>] + [B<-hack>] + [B<-www>] +@@ -54,6 +60,7 @@ B B + [B<-no_ticket>] + [B<-id_prefix arg>] + [B<-rand file(s)>] ++[B<-nextprotoneg protocols>] + + =head1 DESCRIPTION + +@@ -131,6 +138,10 @@ a static set of parameters hard coded in + if this option is set then no DH parameters will be loaded effectively + disabling the ephemeral DH cipher suites. + ++=item B<-no_ecdhe> ++ ++if this option is set then ephemeral ECDH cipher suites will be disabled. ++ + =item B<-no_tmp_rsa> + + certain export cipher suites sometimes use a temporary RSA key, this option +@@ -201,7 +212,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<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> ++=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 disable the use of certain SSL or TLS protocols. By default + the initial handshake uses a method which should be compatible with all +@@ -276,6 +287,14 @@ Multiple files can be specified separate + The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for + all others. + ++=item B<-nextprotoneg protocols> ++ ++enable Next Protocol Negotiation TLS extension and provide a ++comma-separated list of supported protocol names. ++The list should contain most wanted protocols first. ++Protocol names are printable ASCII strings, for example "http/1.1" or ++"spdy/3". ++ + =back + + =head1 CONNECTED COMMANDS +diff -up openssl-1.0.1e/doc/apps/verify.pod.manfix openssl-1.0.1e/doc/apps/verify.pod +--- openssl-1.0.1e/doc/apps/verify.pod.manfix 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/verify.pod 2013-09-12 11:25:13.994994992 +0200 +@@ -25,6 +25,7 @@ B B + [B<-untrusted file>] + [B<-help>] + [B<-issuer_checks>] ++[B<-attime timestamp>] + [B<-verbose>] + [B<->] + [certificates] +@@ -80,6 +81,12 @@ rejected. The presence of rejection mess + anything is wrong; during the normal verification process, several + rejections may take place. + ++=item B<-attime timestamp> ++ ++Perform validation checks using the time specified by B and not ++the current system time. B is the number of seconds since ++01.01.1970 (UNIX time). ++ + =item B<-policy arg> + + Enable policy processing and add B to the user-initial-policy-set (see +diff -up openssl-1.0.1e/doc/ssl/SSL_accept.pod.manfix openssl-1.0.1e/doc/ssl/SSL_accept.pod +--- openssl-1.0.1e/doc/ssl/SSL_accept.pod.manfix 2013-09-12 11:17:42.129091915 +0200 ++++ openssl-1.0.1e/doc/ssl/SSL_accept.pod 2013-09-12 11:17:42.156092507 +0200 +@@ -44,13 +44,13 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the + return value B to find out the reason. + +-=item 1 ++=item C<1> + + The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been + established. +diff -up openssl-1.0.1e/doc/ssl/SSL_clear.pod.manfix openssl-1.0.1e/doc/ssl/SSL_clear.pod +--- openssl-1.0.1e/doc/ssl/SSL_clear.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_clear.pod 2013-09-12 11:17:42.158092551 +0200 +@@ -56,12 +56,12 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The SSL_clear() operation could not be performed. Check the error stack to + find out the reason. + +-=item 1 ++=item C<1> + + The SSL_clear() operation was successful. + +diff -up openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod.manfix openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod +--- openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod.manfix 2013-09-12 11:17:42.049090162 +0200 ++++ openssl-1.0.1e/doc/ssl/SSL_COMP_add_compression_method.pod 2013-09-12 11:17:42.159092573 +0200 +@@ -60,11 +60,11 @@ SSL_COMP_add_compression_method() may re + + =over 4 + +-=item 0 ++=item C<0> + + The operation succeeded. + +-=item 1 ++=item C<1> + + The operation failed. Check the error queue to find out the reason. + +diff -up openssl-1.0.1e/doc/ssl/SSL_connect.pod.manfix openssl-1.0.1e/doc/ssl/SSL_connect.pod +--- openssl-1.0.1e/doc/ssl/SSL_connect.pod.manfix 2013-09-12 11:17:42.130091937 +0200 ++++ openssl-1.0.1e/doc/ssl/SSL_connect.pod 2013-09-12 11:17:42.161092616 +0200 +@@ -41,13 +41,13 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the + return value B to find out the reason. + +-=item 1 ++=item C<1> + + The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been + established. +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_add_session.pod.manfix openssl-1.0.1e/doc/ssl/SSL_CTX_add_session.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_add_session.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_add_session.pod 2013-09-12 11:17:42.162092638 +0200 +@@ -52,13 +52,13 @@ The following values are returned by all + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed. In case of the add operation, it was tried to add + the same (identical) session twice. In case of the remove operation, the + session was not found in the cache. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_load_verify_locations.pod.manfix openssl-1.0.1e/doc/ssl/SSL_CTX_load_verify_locations.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_load_verify_locations.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_load_verify_locations.pod 2013-09-12 11:17:42.163092660 +0200 +@@ -100,13 +100,13 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed because B and B are NULL or the + processing at one of the locations specified failed. Check the error + stack to find out the reason. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod.manfix openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod.manfix 2013-09-12 11:17:42.132091981 +0200 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_client_CA_list.pod 2013-09-12 11:17:42.164092682 +0200 +@@ -66,13 +66,13 @@ values: + + =over 4 + +-=item 0 ++=item C<0> + + A failure while manipulating the STACK_OF(X509_NAME) object occurred or + the X509_NAME could not be extracted from B. Check the error stack + to find out the reason. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_session_id_context.pod.manfix openssl-1.0.1e/doc/ssl/SSL_CTX_set_session_id_context.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_session_id_context.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_session_id_context.pod 2013-09-12 11:17:42.166092726 +0200 +@@ -64,13 +64,13 @@ return the following values: + + =over 4 + +-=item 0 ++=item C<0> + + The length B of the session id context B exceeded + the maximum allowed length of B. The error + is logged to the error stack. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_set_ssl_version.pod.manfix openssl-1.0.1e/doc/ssl/SSL_CTX_set_ssl_version.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_set_ssl_version.pod.manfix 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_set_ssl_version.pod 2013-09-12 11:17:42.167092748 +0200 +@@ -42,11 +42,11 @@ and SSL_set_ssl_method(): + + =over 4 + +-=item 0 ++=item C<0> + + The new choice failed, check the error stack to find out the reason. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod.manfix openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod +--- openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod.manfix 2013-09-12 11:17:42.133092003 +0200 ++++ openssl-1.0.1e/doc/ssl/SSL_CTX_use_psk_identity_hint.pod 2013-09-12 11:17:42.168092770 +0200 +@@ -96,7 +96,7 @@ data to B and return the length of + connection will fail with decryption_error before it will be finished + completely. + +-=item 0 ++=item C<0> + + PSK identity was not found. An "unknown_psk_identity" alert message + will be sent and the connection setup fails. +diff -up openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod.manfix openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod +--- openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod.manfix 2013-09-12 11:17:42.135092047 +0200 ++++ openssl-1.0.1e/doc/ssl/SSL_do_handshake.pod 2013-09-12 11:17:42.170092814 +0200 +@@ -45,13 +45,13 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The TLS/SSL handshake was not successful but was shut down controlled and + by the specifications of the TLS/SSL protocol. Call SSL_get_error() with the + return value B to find out the reason. + +-=item 1 ++=item C<1> + + The TLS/SSL handshake was successfully completed, a TLS/SSL connection has been + established. +diff -up openssl-1.0.1e/doc/ssl/SSL_read.pod.manfix openssl-1.0.1e/doc/ssl/SSL_read.pod +--- openssl-1.0.1e/doc/ssl/SSL_read.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_read.pod 2013-09-12 11:17:42.171092836 +0200 +@@ -86,7 +86,7 @@ The following return values can occur: + The read operation was successful; the return value is the number of + bytes actually read from the TLS/SSL connection. + +-=item 0 ++=item C<0> + + The read operation was not successful. The reason may either be a clean + shutdown due to a "close notify" alert sent by the peer (in which case +diff -up openssl-1.0.1e/doc/ssl/SSL_session_reused.pod.manfix openssl-1.0.1e/doc/ssl/SSL_session_reused.pod +--- openssl-1.0.1e/doc/ssl/SSL_session_reused.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_session_reused.pod 2013-09-12 11:17:42.172092857 +0200 +@@ -27,11 +27,11 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + A new session was negotiated. + +-=item 1 ++=item C<1> + + A session was reused. + +diff -up openssl-1.0.1e/doc/ssl/SSL_set_fd.pod.manfix openssl-1.0.1e/doc/ssl/SSL_set_fd.pod +--- openssl-1.0.1e/doc/ssl/SSL_set_fd.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_set_fd.pod 2013-09-12 11:17:42.174092901 +0200 +@@ -35,11 +35,11 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed. Check the error stack to find out why. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-1.0.1e/doc/ssl/SSL_set_session.pod.manfix openssl-1.0.1e/doc/ssl/SSL_set_session.pod +--- openssl-1.0.1e/doc/ssl/SSL_set_session.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_set_session.pod 2013-09-12 11:17:42.175092923 +0200 +@@ -37,11 +37,11 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The operation failed; check the error stack to find out the reason. + +-=item 1 ++=item C<1> + + The operation succeeded. + +diff -up openssl-1.0.1e/doc/ssl/SSL_shutdown.pod.manfix openssl-1.0.1e/doc/ssl/SSL_shutdown.pod +--- openssl-1.0.1e/doc/ssl/SSL_shutdown.pod.manfix 2013-09-12 11:17:42.137092090 +0200 ++++ openssl-1.0.1e/doc/ssl/SSL_shutdown.pod 2013-09-12 11:17:42.177092967 +0200 +@@ -92,14 +92,14 @@ The following return values can occur: + + =over 4 + +-=item 0 ++=item C<0> + + The shutdown is not yet finished. Call SSL_shutdown() for a second time, + if a bidirectional shutdown shall be performed. + The output of L may be misleading, as an + erroneous SSL_ERROR_SYSCALL may be flagged even though no error occurred. + +-=item 1 ++=item C<1> + + The shutdown was successfully completed. The "close notify" alert was sent + and the peer's "close notify" alert was received. +diff -up openssl-1.0.1e/doc/ssl/SSL_write.pod.manfix openssl-1.0.1e/doc/ssl/SSL_write.pod +--- openssl-1.0.1e/doc/ssl/SSL_write.pod.manfix 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/ssl/SSL_write.pod 2013-09-12 11:17:42.177092967 +0200 +@@ -79,7 +79,7 @@ The following return values can occur: + The write operation was successful, the return value is the number of + bytes actually written to the TLS/SSL connection. + +-=item 0 ++=item C<0> + + The write operation was not successful. Probably the underlying connection + was closed. Call SSL_get_error() with the return value B to find out, diff --git a/SOURCES/openssl-1.0.1e-new-fips-reqs.patch b/SOURCES/openssl-1.0.1e-new-fips-reqs.patch new file mode 100755 index 00000000..80e51621 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-new-fips-reqs.patch @@ -0,0 +1,1695 @@ +diff -up openssl-1.0.1e/crypto/bn/bn_rand.c.fips-reqs openssl-1.0.1e/crypto/bn/bn_rand.c +--- openssl-1.0.1e/crypto/bn/bn_rand.c.fips-reqs 2013-02-11 16:02:47.000000000 +0100 ++++ openssl-1.0.1e/crypto/bn/bn_rand.c 2014-02-13 16:50:34.280893285 +0100 +@@ -138,9 +138,12 @@ static int bnrand(int pseudorand, BIGNUM + goto err; + } + +- /* 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 */ ++ { ++ /* make a random number and set the top and bottom bits */ ++ time(&tim); ++ RAND_add(&tim,sizeof(tim),0.0); ++ } + + if (pseudorand) + { +diff -up openssl-1.0.1e/crypto/dh/dh_gen.c.fips-reqs openssl-1.0.1e/crypto/dh/dh_gen.c +--- openssl-1.0.1e/crypto/dh/dh_gen.c.fips-reqs 2013-12-18 12:17:09.748636614 +0100 ++++ openssl-1.0.1e/crypto/dh/dh_gen.c 2013-12-18 12:17:09.798637687 +0100 +@@ -125,7 +125,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.1e/crypto/dh/dh.h.fips-reqs openssl-1.0.1e/crypto/dh/dh.h +--- openssl-1.0.1e/crypto/dh/dh.h.fips-reqs 2013-12-18 12:17:09.748636614 +0100 ++++ openssl-1.0.1e/crypto/dh/dh.h 2013-12-18 12:17:09.798637687 +0100 +@@ -78,6 +78,7 @@ + #endif + + #define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 ++#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS_GEN (getenv("OPENSSL_ENFORCE_MODULUS_BITS")?2048:1024) + + #define DH_FLAG_CACHE_MONT_P 0x01 + #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH +diff -up openssl-1.0.1e/crypto/dh/dh_check.c.fips-reqs openssl-1.0.1e/crypto/dh/dh_check.c +--- openssl-1.0.1e/crypto/dh/dh_check.c.fips-reqs 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/dh/dh_check.c 2013-12-18 12:17:09.799637708 +0100 +@@ -134,7 +134,33 @@ int DH_check_pub_key(const DH *dh, const + BN_sub_word(q,1); + if (BN_cmp(pub_key,q)>=0) + *ret|=DH_CHECK_PUBKEY_TOO_LARGE; ++#ifdef OPENSSL_FIPS ++ if (FIPS_mode() && dh->q != NULL) ++ { ++ BN_CTX *ctx = NULL; + ++ ctx = BN_CTX_new(); ++ if (ctx == NULL) ++ goto err; ++ ++ if (BN_mod_exp_mont(q, pub_key, dh->q, dh->p, ctx, NULL) <= 0) ++ { ++ BN_CTX_free(ctx); ++ goto err; ++ } ++ if (!BN_is_one(q)) ++ { ++ /* it would be more correct to add new return flag ++ * for this test, but we do not want to do it ++ * so just error out ++ */ ++ BN_CTX_free(ctx); ++ goto err; ++ } ++ ++ BN_CTX_free(ctx); ++ } ++#endif + ok = 1; + err: + if (q != NULL) BN_free(q); +diff -up openssl-1.0.1e/crypto/dsa/dsa_gen.c.fips-reqs openssl-1.0.1e/crypto/dsa/dsa_gen.c +--- openssl-1.0.1e/crypto/dsa/dsa_gen.c.fips-reqs 2013-12-18 12:17:09.749636636 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_gen.c 2013-12-18 12:17:09.799637708 +0100 +@@ -159,7 +159,7 @@ int dsa_builtin_paramgen(DSA *ret, size_ + } + + if (FIPS_module_mode() && +- (bits != 1024 || qbits != 160) && ++ (getenv("OPENSSL_ENFORCE_MODULUS_BITS") || bits != 1024 || qbits != 160) && + (bits != 2048 || qbits != 224) && + (bits != 2048 || qbits != 256) && + (bits != 3072 || qbits != 256)) +diff -up openssl-1.0.1e/crypto/dsa/dsa.h.fips-reqs openssl-1.0.1e/crypto/dsa/dsa.h +--- openssl-1.0.1e/crypto/dsa/dsa.h.fips-reqs 2013-12-18 12:17:09.749636636 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa.h 2013-12-18 12:17:09.799637708 +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 + #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA +@@ -254,9 +255,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 +-/* Primality test according to FIPS PUB 186[-1], Appendix 2.1: +- * 50 rounds of Rabin-Miller */ ++#define DSS_prime_checks 64 ++/* Primality test according to FIPS PUB 186[-4], Appendix 2.1: ++ * 64 rounds of Rabin-Miller */ + #define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +diff -up openssl-1.0.1e/crypto/dsa/dsa_key.c.fips-reqs openssl-1.0.1e/crypto/dsa/dsa_key.c +--- openssl-1.0.1e/crypto/dsa/dsa_key.c.fips-reqs 2013-12-18 12:17:09.797637665 +0100 ++++ openssl-1.0.1e/crypto/dsa/dsa_key.c 2013-12-18 12:17:09.799637708 +0100 +@@ -127,7 +127,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.1e/crypto/fips/fips.c.fips-reqs openssl-1.0.1e/crypto/fips/fips.c +--- openssl-1.0.1e/crypto/fips/fips.c.fips-reqs 2014-09-24 16:38:43.000000000 +0200 ++++ openssl-1.0.1e/crypto/fips/fips.c 2014-09-24 16:37:28.000000000 +0200 +@@ -427,27 +427,25 @@ 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()) ++ if(!FIPS_selftest()) + { +- 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 ++ 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.1e/crypto/fips/fips_dh_selftest.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_dh_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_dh_selftest.c.fips-reqs 2013-12-18 17:06:36.575114314 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_dh_selftest.c 2013-12-18 17:26:14.409036334 +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.1e/crypto/fips/fips_drbg_rand.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_drbg_rand.c +--- openssl-1.0.1e/crypto/fips/fips_drbg_rand.c.fips-reqs 2013-12-18 12:17:09.757636808 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_drbg_rand.c 2013-12-18 18:53:33.263711297 +0100 +@@ -77,7 +77,8 @@ static int fips_drbg_bytes(unsigned char + int rv = 0; + unsigned char *adin = NULL; + size_t adinlen = 0; +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ int locked; ++ locked = private_RAND_lock(1); + do + { + size_t rcnt; +@@ -109,7 +110,8 @@ static int fips_drbg_bytes(unsigned char + while (count); + rv = 1; + err: +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + return rv; + } + +@@ -124,35 +126,51 @@ static int fips_drbg_status(void) + { + DRBG_CTX *dctx = &ossl_dctx; + int rv; +- CRYPTO_r_lock(CRYPTO_LOCK_RAND); ++ int locked; ++ locked = private_RAND_lock(1); + rv = dctx->status == DRBG_STATUS_READY ? 1 : 0; +- CRYPTO_r_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + return rv; + } + + static void fips_drbg_cleanup(void) + { + DRBG_CTX *dctx = &ossl_dctx; +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ int locked; ++ locked = private_RAND_lock(1); + FIPS_drbg_uninstantiate(dctx); +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + } + + static int fips_drbg_seed(const void *seed, int seedlen) + { + DRBG_CTX *dctx = &ossl_dctx; ++ int locked; ++ int ret = 1; ++ ++ locked = private_RAND_lock(1); + if (dctx->rand_seed_cb) +- return dctx->rand_seed_cb(dctx, seed, seedlen); +- return 1; ++ ret = dctx->rand_seed_cb(dctx, seed, seedlen); ++ if (locked) ++ private_RAND_lock(0); ++ return ret; + } + + static int fips_drbg_add(const void *seed, int seedlen, + double add_entropy) + { + DRBG_CTX *dctx = &ossl_dctx; ++ int locked; ++ int ret = 1; ++ ++ locked = private_RAND_lock(1); + if (dctx->rand_add_cb) +- return dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); +- return 1; ++ ret = dctx->rand_add_cb(dctx, seed, seedlen, add_entropy); ++ if (locked) ++ private_RAND_lock(0); ++ return ret; + } + + static const RAND_METHOD rand_drbg_meth = +diff -up openssl-1.0.1e/crypto/fips/fips.h.fips-reqs openssl-1.0.1e/crypto/fips/fips.h +--- openssl-1.0.1e/crypto/fips/fips.h.fips-reqs 2013-12-18 12:17:09.000000000 +0100 ++++ openssl-1.0.1e/crypto/fips/fips.h 2013-12-18 17:13:00.928586689 +0100 +@@ -96,6 +96,7 @@ void FIPS_corrupt_dsa_keygen(void); + 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.1e/crypto/fips/fips_post.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_post.c +--- openssl-1.0.1e/crypto/fips/fips_post.c.fips-reqs 2013-12-18 12:17:09.000000000 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_post.c 2013-12-18 17:12:26.721832716 +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.1e/crypto/fips/fips_rsa_selftest.c.fips-reqs openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c +--- openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c.fips-reqs 2014-03-14 14:47:18.809259727 +0100 ++++ openssl-1.0.1e/crypto/fips/fips_rsa_selftest.c 2014-03-14 15:37:26.295687852 +0100 +@@ -60,69 +60,113 @@ + #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,201 +189,291 @@ void FIPS_corrupt_rsa() + 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() + { +@@ -353,7 +487,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), +@@ -407,36 +541,15 @@ int FIPS_selftest_rsa() + "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; + + err: + if (pk) + EVP_PKEY_free(pk); +- else if (key) ++ if (key) + RSA_free(key); + return ret; + } +diff -up openssl-1.0.1e/crypto/fips/Makefile.fips-reqs openssl-1.0.1e/crypto/fips/Makefile +--- openssl-1.0.1e/crypto/fips/Makefile.fips-reqs 2013-12-18 12:17:20.000000000 +0100 ++++ openssl-1.0.1e/crypto/fips/Makefile 2013-12-18 17:14:20.348337362 +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.1e/crypto/rand/md_rand.c.fips-reqs openssl-1.0.1e/crypto/rand/md_rand.c +--- openssl-1.0.1e/crypto/rand/md_rand.c.fips-reqs 2013-12-18 12:17:09.763636936 +0100 ++++ openssl-1.0.1e/crypto/rand/md_rand.c 2013-12-18 12:17:09.800637730 +0100 +@@ -143,12 +143,6 @@ static long md_count[2]={0,0}; + static double entropy=0; + static int initialized=0; + +-static unsigned int crypto_lock_rand = 0; /* may be set only when a thread +- * holds CRYPTO_LOCK_RAND +- * (to prevent double locking) */ +-/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ +-static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */ +- + + #ifdef PREDICT + int rand_predictable=0; +@@ -196,7 +190,7 @@ static void ssleay_rand_add(const void * + long md_c[2]; + unsigned char local_md[MD_DIGEST_LENGTH]; + EVP_MD_CTX m; +- int do_not_lock; ++ int locked; + + /* + * (Based on the rand(3) manpage) +@@ -213,19 +207,8 @@ static void ssleay_rand_add(const void * + * hash function. + */ + +- /* check if we already have the lock */ +- if (crypto_lock_rand) +- { +- CRYPTO_THREADID cur; +- CRYPTO_THREADID_current(&cur); +- CRYPTO_r_lock(CRYPTO_LOCK_RAND2); +- do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); +- CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); +- } +- else +- do_not_lock = 0; ++ locked = private_RAND_lock(1); + +- if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); + st_idx=state_index; + + /* use our own copies of the counters so that even +@@ -257,7 +240,8 @@ static void ssleay_rand_add(const void * + + md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); + +- if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + + EVP_MD_CTX_init(&m); + for (i=0; i 0) + { +@@ -515,10 +494,11 @@ static int ssleay_rand_bytes(unsigned ch + MD_Init(&m); + MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); + MD_Update(&m,local_md,MD_DIGEST_LENGTH); +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ locked = private_RAND_lock(1); + MD_Update(&m,md,MD_DIGEST_LENGTH); + MD_Final(&m,md); +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ if (locked) ++ private_RAND_lock(0); + + EVP_MD_CTX_cleanup(&m); + if (ok) +@@ -548,32 +528,10 @@ static int ssleay_rand_pseudo_bytes(unsi + + static int ssleay_rand_status(void) + { +- CRYPTO_THREADID cur; + int ret; +- int do_not_lock; ++ int locked; + +- CRYPTO_THREADID_current(&cur); +- /* check if we already have the lock +- * (could happen if a RAND_poll() implementation calls RAND_status()) */ +- if (crypto_lock_rand) +- { +- CRYPTO_r_lock(CRYPTO_LOCK_RAND2); +- do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); +- CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); +- } +- else +- do_not_lock = 0; +- +- if (!do_not_lock) +- { +- CRYPTO_w_lock(CRYPTO_LOCK_RAND); +- +- /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ +- CRYPTO_w_lock(CRYPTO_LOCK_RAND2); +- CRYPTO_THREADID_cpy(&locking_threadid, &cur); +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); +- crypto_lock_rand = 1; +- } ++ locked = private_RAND_lock(1); + + if (!initialized) + { +@@ -583,13 +541,8 @@ static int ssleay_rand_status(void) + + ret = entropy >= ENTROPY_NEEDED; + +- if (!do_not_lock) +- { +- /* before unlocking, we must clear 'crypto_lock_rand' */ +- crypto_lock_rand = 0; +- +- CRYPTO_w_unlock(CRYPTO_LOCK_RAND); +- } ++ if (locked) ++ private_RAND_lock(0); + + return ret; + } +diff -up openssl-1.0.1e/crypto/rand/rand.h.fips-reqs openssl-1.0.1e/crypto/rand/rand.h +--- openssl-1.0.1e/crypto/rand/rand.h.fips-reqs 2013-12-18 12:17:09.764636958 +0100 ++++ openssl-1.0.1e/crypto/rand/rand.h 2013-12-18 12:17:09.800637730 +0100 +@@ -124,6 +124,8 @@ void RAND_set_fips_drbg_type(int type, i + int RAND_init_fips(void); + #endif + ++int private_RAND_lock(int lock); ++ + /* 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. +diff -up openssl-1.0.1e/crypto/rand/rand_lcl.h.fips-reqs openssl-1.0.1e/crypto/rand/rand_lcl.h +--- openssl-1.0.1e/crypto/rand/rand_lcl.h.fips-reqs 2013-12-18 12:17:09.507631447 +0100 ++++ openssl-1.0.1e/crypto/rand/rand_lcl.h 2013-12-18 12:17:09.800637730 +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) +diff -up openssl-1.0.1e/crypto/rand/rand_lib.c.fips-reqs openssl-1.0.1e/crypto/rand/rand_lib.c +--- openssl-1.0.1e/crypto/rand/rand_lib.c.fips-reqs 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rand/rand_lib.c 2013-12-18 18:16:45.625850730 +0100 +@@ -181,6 +181,41 @@ int RAND_status(void) + return 0; + } + ++int private_RAND_lock(int lock) ++ { ++ static int crypto_lock_rand; ++ static CRYPTO_THREADID locking_threadid; ++ int do_lock; ++ ++ if (!lock) ++ { ++ crypto_lock_rand = 0; ++ CRYPTO_w_unlock(CRYPTO_LOCK_RAND); ++ return 0; ++ } ++ ++ /* check if we already have the lock */ ++ if (crypto_lock_rand) ++ { ++ CRYPTO_THREADID cur; ++ CRYPTO_THREADID_current(&cur); ++ CRYPTO_r_lock(CRYPTO_LOCK_RAND2); ++ do_lock = !!CRYPTO_THREADID_cmp(&locking_threadid, &cur); ++ CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); ++ } ++ else ++ do_lock = 1; ++ if (do_lock) ++ { ++ CRYPTO_w_lock(CRYPTO_LOCK_RAND); ++ CRYPTO_w_lock(CRYPTO_LOCK_RAND2); ++ CRYPTO_THREADID_current(&locking_threadid); ++ CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); ++ crypto_lock_rand = 1; ++ } ++ return do_lock; ++ } ++ + #ifdef OPENSSL_FIPS + + /* FIPS DRBG initialisation code. This sets up the DRBG for use by the +@@ -239,12 +274,16 @@ static int drbg_rand_add(DRBG_CTX *ctx, + double entropy) + { + RAND_SSLeay()->add(in, inlen, entropy); ++ if (FIPS_rand_status()) ++ FIPS_drbg_reseed(ctx, NULL, 0); + return 1; + } + + static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) + { + RAND_SSLeay()->seed(in, inlen); ++ if (FIPS_rand_status()) ++ FIPS_drbg_reseed(ctx, NULL, 0); + return 1; + } + +diff -up openssl-1.0.1e/crypto/rsa/rsa_gen.c.fips-reqs openssl-1.0.1e/crypto/rsa/rsa_gen.c +--- openssl-1.0.1e/crypto/rsa/rsa_gen.c.fips-reqs 2013-12-18 12:17:09.764636958 +0100 ++++ openssl-1.0.1e/crypto/rsa/rsa_gen.c 2013-12-19 17:40:58.483154314 +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 +@@ -165,6 +166,236 @@ 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) + { + BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp; +@@ -176,17 +407,12 @@ 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 + +@@ -301,17 +527,6 @@ static int rsa_builtin_keygen(RSA *rsa, + p = rsa->p; + 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.1e/ssl/t1_enc.c.fips-reqs openssl-1.0.1e/ssl/t1_enc.c +--- openssl-1.0.1e/ssl/t1_enc.c.fips-reqs 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/t1_enc.c 2013-12-18 12:17:09.801637751 +0100 +@@ -291,6 +291,27 @@ static int tls1_PRF(long digest_mask, + err: + 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.1e-no-md5-verify.patch b/SOURCES/openssl-1.0.1e-no-md5-verify.patch new file mode 100755 index 00000000..f3797357 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-no-md5-verify.patch @@ -0,0 +1,25 @@ +diff -up openssl-1.0.1e/crypto/asn1/a_verify.c.no-md5-verify openssl-1.0.1e/crypto/asn1/a_verify.c +--- openssl-1.0.1e/crypto/asn1/a_verify.c.no-md5-verify 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/asn1/a_verify.c 2013-11-13 16:30:04.628791616 +0100 +@@ -56,6 +56,9 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE ++ + #include + #include + +@@ -171,6 +174,11 @@ int ASN1_item_verify(const ASN1_ITEM *it + goto err; + ret = -1; + } ++ else if (mdnid == NID_md5 && secure_getenv("OPENSSL_ENABLE_MD5_VERIFY") == NULL) ++ { ++ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); ++ goto err; ++ } + else + { + const EVP_MD *type; diff --git a/SOURCES/openssl-1.0.1e-ppc-asm-update.patch b/SOURCES/openssl-1.0.1e-ppc-asm-update.patch new file mode 100755 index 00000000..91efede0 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-ppc-asm-update.patch @@ -0,0 +1,6677 @@ +diff --git a/Configure b/Configure +index 9c803dc..5a5c2d8 100755 +--- a/Configure ++++ b/Configure +@@ -139,8 +139,8 @@ my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o s390x-gf2m.o::aes + my $armv4_asm="armcap.o armv4cpuid.o:bn_asm.o armv4-mont.o armv4-gf2m.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::ghash-armv4.o::void"; + my $parisc11_asm="pariscid.o:bn_asm.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::32"; + my $parisc20_asm="pariscid.o:pa-risc2W.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::64"; +-my $ppc32_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::::"; +-my $ppc64_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o::::::::"; ++my $ppc64_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o vpaes-ppc.o aesp8-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o sha256p8-ppc.o sha512p8-ppc.o:::::::ghashp8-ppc.o:"; ++my $ppc32_asm=$ppc64_asm; + my $no_asm=":::::::::::::::void"; + + # As for $BSDthreads. Idea is to maintain "collective" set of flags, +@@ -357,6 +357,7 @@ my %table=( + #### + "linux-generic64","gcc:-DTERMIO -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 -DTERMIO -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 -DTERMIO -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-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", + "linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +@@ -462,8 +463,8 @@ my %table=( + + #### IBM's AIX. + "aix3-cc", "cc:-O -DB_ENDIAN -qmaxmem=16384::(unknown):AIX::BN_LLONG RC4_CHAR:::", +-"aix-gcc", "gcc:-O -DB_ENDIAN::-pthread:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X32", +-"aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64", ++"aix-gcc", "gcc:-O -DB_ENDIAN::-pthread:AIX::BN_LLONG RC4_CHAR:$ppc32_asm:aix32:dlfcn:aix-shared::-shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X32", ++"aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:$ppc64_asm:aix64:dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64", + # Below targets assume AIX 5. Idea is to effectively disregard $OBJECT_MODE + # at build time. $OBJECT_MODE is respected at ./config stage! + "aix-cc", "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32", +@@ -1525,7 +1526,7 @@ else { + $wp_obj="wp_block.o"; + } + $cmll_obj=$cmll_enc unless ($cmll_obj =~ /.o$/); +-if ($modes_obj =~ /ghash/) ++if ($modes_obj =~ /ghash\-/) + { + $cflags.=" -DGHASH_ASM"; + } +diff --git a/config b/config +index 88b9bc6..8b80802 100755 +--- a/config ++++ b/config +@@ -587,13 +587,20 @@ case "$GUESSOS" in + fi + ;; + ppc64-*-linux2) +- echo "WARNING! If you wish to build 64-bit library, then you have to" +- echo " invoke './Configure linux-ppc64' *manually*." +- if [ "$TEST" = "false" -a -t 1 ]; then +- echo " You have about 5 seconds to press Ctrl-C to abort." +- (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1 ++ if [ -z "$KERNEL_BITS" ]; then ++ echo "WARNING! If you wish to build 64-bit library, then you have to" ++ echo " invoke './Configure linux-ppc64' *manually*." ++ if [ "$TEST" = "false" -a -t 1 ]; then ++ echo " You have about 5 seconds to press Ctrl-C to abort." ++ (trap "stty `stty -g`" 2 0; stty -icanon min 0 time 50; read waste) <&1 ++ fi ++ fi ++ if [ "$KERNEL_BITS" = "64" ]; then ++ OUT="linux-ppc64" ++ else ++ OUT="linux-ppc" ++ (echo "__LP64__" | gcc -E -x c - 2>/dev/null | grep "^__LP64__" 2>&1 > /dev/null) || options="$options -m32" + fi +- OUT="linux-ppc" + ;; + ppc-*-linux2) OUT="linux-ppc" ;; + ppc60x-*-vxworks*) OUT="vxworks-ppc60x" ;; +diff --git a/crypto/aes/Makefile b/crypto/aes/Makefile +index 45ede0a..847f4ee 100644 +--- a/crypto/aes/Makefile ++++ b/crypto/aes/Makefile +@@ -71,6 +71,10 @@ aes-sparcv9.s: asm/aes-sparcv9.pl + + aes-ppc.s: asm/aes-ppc.pl + $(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@ ++vpaes-ppc.s: asm/vpaes-ppc.pl ++ $(PERL) asm/vpaes-ppc.pl $(PERLASM_SCHEME) $@ ++aesp8-ppc.s: asm/aesp8-ppc.pl ++ $(PERL) asm/aesp8-ppc.pl $(PERLASM_SCHEME) $@ + + aes-parisc.s: asm/aes-parisc.pl + $(PERL) asm/aes-parisc.pl $(PERLASM_SCHEME) $@ +diff --git a/crypto/aes/asm/aes-ppc.pl b/crypto/aes/asm/aes-ppc.pl +index 7c52cbe..7a99fc3 100644 +--- a/crypto/aes/asm/aes-ppc.pl ++++ b/crypto/aes/asm/aes-ppc.pl +@@ -45,6 +45,8 @@ if ($flavour =~ /64/) { + $PUSH ="stw"; + } else { die "nonsense $flavour"; } + ++$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0; ++ + $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; + ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or + ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +@@ -68,7 +70,7 @@ $key="r5"; + $Tbl0="r3"; + $Tbl1="r6"; + $Tbl2="r7"; +-$Tbl3="r2"; ++$Tbl3=$out; # stay away from "r2"; $out is offloaded to stack + + $s0="r8"; + $s1="r9"; +@@ -76,7 +78,7 @@ $s2="r10"; + $s3="r11"; + + $t0="r12"; +-$t1="r13"; ++$t1="r0"; # stay away from "r13"; + $t2="r14"; + $t3="r15"; + +@@ -100,9 +102,6 @@ $acc13="r29"; + $acc14="r30"; + $acc15="r31"; + +-# stay away from TLS pointer +-if ($SIZE_T==8) { die if ($t1 ne "r13"); $t1="r0"; } +-else { die if ($Tbl3 ne "r2"); $Tbl3=$t0; $t0="r0"; } + $mask80=$Tbl2; + $mask1b=$Tbl3; + +@@ -337,8 +336,7 @@ $code.=<<___; + $STU $sp,-$FRAME($sp) + mflr r0 + +- $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) +- $PUSH r13,`$FRAME-$SIZE_T*19`($sp) ++ $PUSH $out,`$FRAME-$SIZE_T*19`($sp) + $PUSH r14,`$FRAME-$SIZE_T*18`($sp) + $PUSH r15,`$FRAME-$SIZE_T*17`($sp) + $PUSH r16,`$FRAME-$SIZE_T*16`($sp) +@@ -365,16 +363,61 @@ $code.=<<___; + bne Lenc_unaligned + + Lenc_unaligned_ok: ++___ ++$code.=<<___ if (!$LITTLE_ENDIAN); + lwz $s0,0($inp) + lwz $s1,4($inp) + lwz $s2,8($inp) + lwz $s3,12($inp) ++___ ++$code.=<<___ if ($LITTLE_ENDIAN); ++ lwz $t0,0($inp) ++ lwz $t1,4($inp) ++ lwz $t2,8($inp) ++ lwz $t3,12($inp) ++ rotlwi $s0,$t0,8 ++ rotlwi $s1,$t1,8 ++ rotlwi $s2,$t2,8 ++ rotlwi $s3,$t3,8 ++ rlwimi $s0,$t0,24,0,7 ++ rlwimi $s1,$t1,24,0,7 ++ rlwimi $s2,$t2,24,0,7 ++ rlwimi $s3,$t3,24,0,7 ++ rlwimi $s0,$t0,24,16,23 ++ rlwimi $s1,$t1,24,16,23 ++ rlwimi $s2,$t2,24,16,23 ++ rlwimi $s3,$t3,24,16,23 ++___ ++$code.=<<___; + bl LAES_Te + bl Lppc_AES_encrypt_compact ++ $POP $out,`$FRAME-$SIZE_T*19`($sp) ++___ ++$code.=<<___ if ($LITTLE_ENDIAN); ++ rotlwi $t0,$s0,8 ++ rotlwi $t1,$s1,8 ++ rotlwi $t2,$s2,8 ++ rotlwi $t3,$s3,8 ++ rlwimi $t0,$s0,24,0,7 ++ rlwimi $t1,$s1,24,0,7 ++ rlwimi $t2,$s2,24,0,7 ++ rlwimi $t3,$s3,24,0,7 ++ rlwimi $t0,$s0,24,16,23 ++ rlwimi $t1,$s1,24,16,23 ++ rlwimi $t2,$s2,24,16,23 ++ rlwimi $t3,$s3,24,16,23 ++ stw $t0,0($out) ++ stw $t1,4($out) ++ stw $t2,8($out) ++ stw $t3,12($out) ++___ ++$code.=<<___ if (!$LITTLE_ENDIAN); + stw $s0,0($out) + stw $s1,4($out) + stw $s2,8($out) + stw $s3,12($out) ++___ ++$code.=<<___; + b Lenc_done + + Lenc_unaligned: +@@ -417,6 +460,7 @@ Lenc_xpage: + + bl LAES_Te + bl Lppc_AES_encrypt_compact ++ $POP $out,`$FRAME-$SIZE_T*19`($sp) + + extrwi $acc00,$s0,8,0 + extrwi $acc01,$s0,8,8 +@@ -449,8 +493,6 @@ Lenc_xpage: + + Lenc_done: + $POP r0,`$FRAME+$LRSAVE`($sp) +- $POP $toc,`$FRAME-$SIZE_T*20`($sp) +- $POP r13,`$FRAME-$SIZE_T*19`($sp) + $POP r14,`$FRAME-$SIZE_T*18`($sp) + $POP r15,`$FRAME-$SIZE_T*17`($sp) + $POP r16,`$FRAME-$SIZE_T*16`($sp) +@@ -764,6 +806,7 @@ Lenc_compact_done: + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size .AES_encrypt,.-.AES_encrypt + + .globl .AES_decrypt + .align 7 +@@ -771,8 +814,7 @@ Lenc_compact_done: + $STU $sp,-$FRAME($sp) + mflr r0 + +- $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) +- $PUSH r13,`$FRAME-$SIZE_T*19`($sp) ++ $PUSH $out,`$FRAME-$SIZE_T*19`($sp) + $PUSH r14,`$FRAME-$SIZE_T*18`($sp) + $PUSH r15,`$FRAME-$SIZE_T*17`($sp) + $PUSH r16,`$FRAME-$SIZE_T*16`($sp) +@@ -799,16 +841,61 @@ Lenc_compact_done: + bne Ldec_unaligned + + Ldec_unaligned_ok: ++___ ++$code.=<<___ if (!$LITTLE_ENDIAN); + lwz $s0,0($inp) + lwz $s1,4($inp) + lwz $s2,8($inp) + lwz $s3,12($inp) ++___ ++$code.=<<___ if ($LITTLE_ENDIAN); ++ lwz $t0,0($inp) ++ lwz $t1,4($inp) ++ lwz $t2,8($inp) ++ lwz $t3,12($inp) ++ rotlwi $s0,$t0,8 ++ rotlwi $s1,$t1,8 ++ rotlwi $s2,$t2,8 ++ rotlwi $s3,$t3,8 ++ rlwimi $s0,$t0,24,0,7 ++ rlwimi $s1,$t1,24,0,7 ++ rlwimi $s2,$t2,24,0,7 ++ rlwimi $s3,$t3,24,0,7 ++ rlwimi $s0,$t0,24,16,23 ++ rlwimi $s1,$t1,24,16,23 ++ rlwimi $s2,$t2,24,16,23 ++ rlwimi $s3,$t3,24,16,23 ++___ ++$code.=<<___; + bl LAES_Td + bl Lppc_AES_decrypt_compact ++ $POP $out,`$FRAME-$SIZE_T*19`($sp) ++___ ++$code.=<<___ if ($LITTLE_ENDIAN); ++ rotlwi $t0,$s0,8 ++ rotlwi $t1,$s1,8 ++ rotlwi $t2,$s2,8 ++ rotlwi $t3,$s3,8 ++ rlwimi $t0,$s0,24,0,7 ++ rlwimi $t1,$s1,24,0,7 ++ rlwimi $t2,$s2,24,0,7 ++ rlwimi $t3,$s3,24,0,7 ++ rlwimi $t0,$s0,24,16,23 ++ rlwimi $t1,$s1,24,16,23 ++ rlwimi $t2,$s2,24,16,23 ++ rlwimi $t3,$s3,24,16,23 ++ stw $t0,0($out) ++ stw $t1,4($out) ++ stw $t2,8($out) ++ stw $t3,12($out) ++___ ++$code.=<<___ if (!$LITTLE_ENDIAN); + stw $s0,0($out) + stw $s1,4($out) + stw $s2,8($out) + stw $s3,12($out) ++___ ++$code.=<<___; + b Ldec_done + + Ldec_unaligned: +@@ -851,6 +938,7 @@ Ldec_xpage: + + bl LAES_Td + bl Lppc_AES_decrypt_compact ++ $POP $out,`$FRAME-$SIZE_T*19`($sp) + + extrwi $acc00,$s0,8,0 + extrwi $acc01,$s0,8,8 +@@ -883,8 +971,6 @@ Ldec_xpage: + + Ldec_done: + $POP r0,`$FRAME+$LRSAVE`($sp) +- $POP $toc,`$FRAME-$SIZE_T*20`($sp) +- $POP r13,`$FRAME-$SIZE_T*19`($sp) + $POP r14,`$FRAME-$SIZE_T*18`($sp) + $POP r15,`$FRAME-$SIZE_T*17`($sp) + $POP r16,`$FRAME-$SIZE_T*16`($sp) +@@ -1355,6 +1441,7 @@ Ldec_compact_done: + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size .AES_decrypt,.-.AES_decrypt + + .asciz "AES for PPC, CRYPTOGAMS by " + .align 7 +diff --git a/crypto/aes/asm/aesp8-ppc.pl b/crypto/aes/asm/aesp8-ppc.pl +new file mode 100755 +index 0000000..3ee8979 +--- /dev/null ++++ b/crypto/aes/asm/aesp8-ppc.pl +@@ -0,0 +1,1940 @@ ++#!/usr/bin/env perl ++# ++# ==================================================================== ++# Written by Andy Polyakov for the OpenSSL ++# project. The module is, however, dual licensed under OpenSSL and ++# CRYPTOGAMS licenses depending on where you obtain it. For further ++# details see http://www.openssl.org/~appro/cryptogams/. ++# ==================================================================== ++# ++# This module implements support for AES instructions as per PowerISA ++# specification version 2.07, first implemented by POWER8 processor. ++# The module is endian-agnostic in sense that it supports both big- ++# and little-endian cases. Data alignment in parallelizable modes is ++# handled with VSX loads and stores, which implies MSR.VSX flag being ++# set. It should also be noted that ISA specification doesn't prohibit ++# alignment exceptions for these instructions on page boundaries. ++# Initially alignment was handled in pure AltiVec/VMX way [when data ++# is aligned programmatically, which in turn guarantees exception- ++# free execution], but it turned to hamper performance when vcipher ++# instructions are interleaved. It's reckoned that eventual ++# misalignment penalties at page boundaries are in average lower ++# than additional overhead in pure AltiVec approach. ++ ++$flavour = shift; ++ ++if ($flavour =~ /64/) { ++ $SIZE_T =8; ++ $LRSAVE =2*$SIZE_T; ++ $STU ="stdu"; ++ $POP ="ld"; ++ $PUSH ="std"; ++ $UCMP ="cmpld"; ++ $SHL ="sldi"; ++} elsif ($flavour =~ /32/) { ++ $SIZE_T =4; ++ $LRSAVE =$SIZE_T; ++ $STU ="stwu"; ++ $POP ="lwz"; ++ $PUSH ="stw"; ++ $UCMP ="cmplw"; ++ $SHL ="slwi"; ++} else { die "nonsense $flavour"; } ++ ++$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0; ++ ++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ++( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ++( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or ++die "can't locate ppc-xlate.pl"; ++ ++open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; ++ ++$FRAME=8*$SIZE_T; ++$prefix="aes_p8"; ++ ++$sp="r1"; ++$vrsave="r12"; ++ ++######################################################################### ++{{{ # Key setup procedures # ++my ($inp,$bits,$out,$ptr,$cnt,$rounds)=map("r$_",(3..8)); ++my ($zero,$in0,$in1,$key,$rcon,$mask,$tmp)=map("v$_",(0..6)); ++my ($stage,$outperm,$outmask,$outhead,$outtail)=map("v$_",(7..11)); ++ ++$code.=<<___; ++.machine "any" ++ ++.text ++ ++.align 7 ++rcon: ++.long 0x01000000, 0x01000000, 0x01000000, 0x01000000 ?rev ++.long 0x1b000000, 0x1b000000, 0x1b000000, 0x1b000000 ?rev ++.long 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c ?rev ++.long 0,0,0,0 ?asis ++Lconsts: ++ mflr r0 ++ bcl 20,31,\$+4 ++ mflr $ptr #vvvvv "distance between . and rcon ++ addi $ptr,$ptr,-0x48 ++ mtlr r0 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++.asciz "AES for PowerISA 2.07, CRYPTOGAMS by " ++ ++.globl .${prefix}_set_encrypt_key ++.align 5 ++.${prefix}_set_encrypt_key: ++Lset_encrypt_key: ++ mflr r11 ++ $PUSH r11,$LRSAVE($sp) ++ ++ li $ptr,-1 ++ ${UCMP}i $inp,0 ++ beq- Lenc_key_abort # if ($inp==0) return -1; ++ ${UCMP}i $out,0 ++ beq- Lenc_key_abort # if ($out==0) return -1; ++ li $ptr,-2 ++ cmpwi $bits,128 ++ blt- Lenc_key_abort ++ cmpwi $bits,256 ++ bgt- Lenc_key_abort ++ andi. r0,$bits,0x3f ++ bne- Lenc_key_abort ++ ++ lis r0,0xfff0 ++ mfspr $vrsave,256 ++ mtspr 256,r0 ++ ++ bl Lconsts ++ mtlr r11 ++ ++ neg r9,$inp ++ lvx $in0,0,$inp ++ addi $inp,$inp,15 # 15 is not typo ++ lvsr $key,0,r9 # borrow $key ++ li r8,0x20 ++ cmpwi $bits,192 ++ lvx $in1,0,$inp ++ le?vspltisb $mask,0x0f # borrow $mask ++ lvx $rcon,0,$ptr ++ le?vxor $key,$key,$mask # adjust for byte swap ++ lvx $mask,r8,$ptr ++ addi $ptr,$ptr,0x10 ++ vperm $in0,$in0,$in1,$key # align [and byte swap in LE] ++ li $cnt,8 ++ vxor $zero,$zero,$zero ++ mtctr $cnt ++ ++ ?lvsr $outperm,0,$out ++ vspltisb $outmask,-1 ++ lvx $outhead,0,$out ++ ?vperm $outmask,$zero,$outmask,$outperm ++ ++ blt Loop128 ++ addi $inp,$inp,8 ++ beq L192 ++ addi $inp,$inp,8 ++ b L256 ++ ++.align 4 ++Loop128: ++ vperm $key,$in0,$in0,$mask # rotate-n-splat ++ vsldoi $tmp,$zero,$in0,12 # >>32 ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ vcipherlast $key,$key,$rcon ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vadduwm $rcon,$rcon,$rcon ++ vxor $in0,$in0,$key ++ bdnz Loop128 ++ ++ lvx $rcon,0,$ptr # last two round keys ++ ++ vperm $key,$in0,$in0,$mask # rotate-n-splat ++ vsldoi $tmp,$zero,$in0,12 # >>32 ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ vcipherlast $key,$key,$rcon ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vadduwm $rcon,$rcon,$rcon ++ vxor $in0,$in0,$key ++ ++ vperm $key,$in0,$in0,$mask # rotate-n-splat ++ vsldoi $tmp,$zero,$in0,12 # >>32 ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ vcipherlast $key,$key,$rcon ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vxor $in0,$in0,$key ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ stvx $stage,0,$out ++ ++ addi $inp,$out,15 # 15 is not typo ++ addi $out,$out,0x50 ++ ++ li $rounds,10 ++ b Ldone ++ ++.align 4 ++L192: ++ lvx $tmp,0,$inp ++ li $cnt,4 ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ vperm $in1,$in1,$tmp,$key # align [and byte swap in LE] ++ vspltisb $key,8 # borrow $key ++ mtctr $cnt ++ vsububm $mask,$mask,$key # adjust the mask ++ ++Loop192: ++ vperm $key,$in1,$in1,$mask # roate-n-splat ++ vsldoi $tmp,$zero,$in0,12 # >>32 ++ vcipherlast $key,$key,$rcon ++ ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ ++ vsldoi $stage,$zero,$in1,8 ++ vspltw $tmp,$in0,3 ++ vxor $tmp,$tmp,$in1 ++ vsldoi $in1,$zero,$in1,12 # >>32 ++ vadduwm $rcon,$rcon,$rcon ++ vxor $in1,$in1,$tmp ++ vxor $in0,$in0,$key ++ vxor $in1,$in1,$key ++ vsldoi $stage,$stage,$in0,8 ++ ++ vperm $key,$in1,$in1,$mask # rotate-n-splat ++ vsldoi $tmp,$zero,$in0,12 # >>32 ++ vperm $outtail,$stage,$stage,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ vcipherlast $key,$key,$rcon ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ ++ vsldoi $stage,$in0,$in1,8 ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vperm $outtail,$stage,$stage,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ ++ vspltw $tmp,$in0,3 ++ vxor $tmp,$tmp,$in1 ++ vsldoi $in1,$zero,$in1,12 # >>32 ++ vadduwm $rcon,$rcon,$rcon ++ vxor $in1,$in1,$tmp ++ vxor $in0,$in0,$key ++ vxor $in1,$in1,$key ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ stvx $stage,0,$out ++ addi $inp,$out,15 # 15 is not typo ++ addi $out,$out,16 ++ bdnz Loop192 ++ ++ li $rounds,12 ++ addi $out,$out,0x20 ++ b Ldone ++ ++.align 4 ++L256: ++ lvx $tmp,0,$inp ++ li $cnt,7 ++ li $rounds,14 ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ vperm $in1,$in1,$tmp,$key # align [and byte swap in LE] ++ mtctr $cnt ++ ++Loop256: ++ vperm $key,$in1,$in1,$mask # rotate-n-splat ++ vsldoi $tmp,$zero,$in0,12 # >>32 ++ vperm $outtail,$in1,$in1,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ vcipherlast $key,$key,$rcon ++ stvx $stage,0,$out ++ addi $out,$out,16 ++ ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in0,$in0,$tmp ++ vadduwm $rcon,$rcon,$rcon ++ vxor $in0,$in0,$key ++ vperm $outtail,$in0,$in0,$outperm # rotate ++ vsel $stage,$outhead,$outtail,$outmask ++ vmr $outhead,$outtail ++ stvx $stage,0,$out ++ addi $inp,$out,15 # 15 is not typo ++ addi $out,$out,16 ++ bdz Ldone ++ ++ vspltw $key,$in0,3 # just splat ++ vsldoi $tmp,$zero,$in1,12 # >>32 ++ vsbox $key,$key ++ ++ vxor $in1,$in1,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in1,$in1,$tmp ++ vsldoi $tmp,$zero,$tmp,12 # >>32 ++ vxor $in1,$in1,$tmp ++ ++ vxor $in1,$in1,$key ++ b Loop256 ++ ++.align 4 ++Ldone: ++ lvx $in1,0,$inp # redundant in aligned case ++ vsel $in1,$outhead,$in1,$outmask ++ stvx $in1,0,$inp ++ li $ptr,0 ++ mtspr 256,$vrsave ++ stw $rounds,0($out) ++ ++Lenc_key_abort: ++ mr r3,$ptr ++ blr ++ .long 0 ++ .byte 0,12,0x14,1,0,0,3,0 ++ .long 0 ++.size .${prefix}_set_encrypt_key,.-.${prefix}_set_encrypt_key ++ ++.globl .${prefix}_set_decrypt_key ++.align 5 ++.${prefix}_set_decrypt_key: ++ $STU $sp,-$FRAME($sp) ++ mflr r10 ++ $PUSH r10,$FRAME+$LRSAVE($sp) ++ bl Lset_encrypt_key ++ mtlr r10 ++ ++ cmpwi r3,0 ++ bne- Ldec_key_abort ++ ++ slwi $cnt,$rounds,4 ++ subi $inp,$out,240 # first round key ++ srwi $rounds,$rounds,1 ++ add $out,$inp,$cnt # last round key ++ mtctr $rounds ++ ++Ldeckey: ++ lwz r0, 0($inp) ++ lwz r6, 4($inp) ++ lwz r7, 8($inp) ++ lwz r8, 12($inp) ++ addi $inp,$inp,16 ++ lwz r9, 0($out) ++ lwz r10,4($out) ++ lwz r11,8($out) ++ lwz r12,12($out) ++ stw r0, 0($out) ++ stw r6, 4($out) ++ stw r7, 8($out) ++ stw r8, 12($out) ++ subi $out,$out,16 ++ stw r9, -16($inp) ++ stw r10,-12($inp) ++ stw r11,-8($inp) ++ stw r12,-4($inp) ++ bdnz Ldeckey ++ ++ xor r3,r3,r3 # return value ++Ldec_key_abort: ++ addi $sp,$sp,$FRAME ++ blr ++ .long 0 ++ .byte 0,12,4,1,0x80,0,3,0 ++ .long 0 ++.size .${prefix}_set_decrypt_key,.-.${prefix}_set_decrypt_key ++___ ++}}} ++######################################################################### ++{{{ # Single block en- and decrypt procedures # ++sub gen_block () { ++my $dir = shift; ++my $n = $dir eq "de" ? "n" : ""; ++my ($inp,$out,$key,$rounds,$idx)=map("r$_",(3..7)); ++ ++$code.=<<___; ++.globl .${prefix}_${dir}crypt ++.align 5 ++.${prefix}_${dir}crypt: ++ lwz $rounds,240($key) ++ lis r0,0xfc00 ++ mfspr $vrsave,256 ++ li $idx,15 # 15 is not typo ++ mtspr 256,r0 ++ ++ lvx v0,0,$inp ++ neg r11,$out ++ lvx v1,$idx,$inp ++ lvsl v2,0,$inp # inpperm ++ le?vspltisb v4,0x0f ++ ?lvsl v3,0,r11 # outperm ++ le?vxor v2,v2,v4 ++ li $idx,16 ++ vperm v0,v0,v1,v2 # align [and byte swap in LE] ++ lvx v1,0,$key ++ ?lvsl v5,0,$key # keyperm ++ srwi $rounds,$rounds,1 ++ lvx v2,$idx,$key ++ addi $idx,$idx,16 ++ subi $rounds,$rounds,1 ++ ?vperm v1,v1,v2,v5 # align round key ++ ++ vxor v0,v0,v1 ++ lvx v1,$idx,$key ++ addi $idx,$idx,16 ++ mtctr $rounds ++ ++Loop_${dir}c: ++ ?vperm v2,v2,v1,v5 ++ v${n}cipher v0,v0,v2 ++ lvx v2,$idx,$key ++ addi $idx,$idx,16 ++ ?vperm v1,v1,v2,v5 ++ v${n}cipher v0,v0,v1 ++ lvx v1,$idx,$key ++ addi $idx,$idx,16 ++ bdnz Loop_${dir}c ++ ++ ?vperm v2,v2,v1,v5 ++ v${n}cipher v0,v0,v2 ++ lvx v2,$idx,$key ++ ?vperm v1,v1,v2,v5 ++ v${n}cipherlast v0,v0,v1 ++ ++ vspltisb v2,-1 ++ vxor v1,v1,v1 ++ li $idx,15 # 15 is not typo ++ ?vperm v2,v1,v2,v3 # outmask ++ le?vxor v3,v3,v4 ++ lvx v1,0,$out # outhead ++ vperm v0,v0,v0,v3 # rotate [and byte swap in LE] ++ vsel v1,v1,v0,v2 ++ lvx v4,$idx,$out ++ stvx v1,0,$out ++ vsel v0,v0,v4,v2 ++ stvx v0,$idx,$out ++ ++ mtspr 256,$vrsave ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,3,0 ++ .long 0 ++.size .${prefix}_${dir}crypt,.-.${prefix}_${dir}crypt ++___ ++} ++&gen_block("en"); ++&gen_block("de"); ++}}} ++######################################################################### ++{{{ # CBC en- and decrypt procedures # ++my ($inp,$out,$len,$key,$ivp,$enc,$rounds,$idx)=map("r$_",(3..10)); ++my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3)); ++my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm)= ++ map("v$_",(4..10)); ++$code.=<<___; ++.globl .${prefix}_cbc_encrypt ++.align 5 ++.${prefix}_cbc_encrypt: ++ ${UCMP}i $len,16 ++ bltlr- ++ ++ cmpwi $enc,0 # test direction ++ lis r0,0xffe0 ++ mfspr $vrsave,256 ++ mtspr 256,r0 ++ ++ li $idx,15 ++ vxor $rndkey0,$rndkey0,$rndkey0 ++ le?vspltisb $tmp,0x0f ++ ++ lvx $ivec,0,$ivp # load [unaligned] iv ++ lvsl $inpperm,0,$ivp ++ lvx $inptail,$idx,$ivp ++ le?vxor $inpperm,$inpperm,$tmp ++ vperm $ivec,$ivec,$inptail,$inpperm ++ ++ neg r11,$inp ++ ?lvsl $keyperm,0,$key # prepare for unaligned key ++ lwz $rounds,240($key) ++ ++ lvsr $inpperm,0,r11 # prepare for unaligned load ++ lvx $inptail,0,$inp ++ addi $inp,$inp,15 # 15 is not typo ++ le?vxor $inpperm,$inpperm,$tmp ++ ++ ?lvsr $outperm,0,$out # prepare for unaligned store ++ vspltisb $outmask,-1 ++ lvx $outhead,0,$out ++ ?vperm $outmask,$rndkey0,$outmask,$outperm ++ le?vxor $outperm,$outperm,$tmp ++ ++ srwi $rounds,$rounds,1 ++ li $idx,16 ++ subi $rounds,$rounds,1 ++ beq Lcbc_dec ++ ++Lcbc_enc: ++ vmr $inout,$inptail ++ lvx $inptail,0,$inp ++ addi $inp,$inp,16 ++ mtctr $rounds ++ subi $len,$len,16 # len-=16 ++ ++ lvx $rndkey0,0,$key ++ vperm $inout,$inout,$inptail,$inpperm ++ lvx $rndkey1,$idx,$key ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key ++ addi $idx,$idx,16 ++ vxor $inout,$inout,$ivec ++ ++Loop_cbc_enc: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipher $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key ++ addi $idx,$idx,16 ++ bdnz Loop_cbc_enc ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key ++ li $idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipherlast $ivec,$inout,$rndkey0 ++ ${UCMP}i $len,16 ++ ++ vperm $tmp,$ivec,$ivec,$outperm ++ vsel $inout,$outhead,$tmp,$outmask ++ vmr $outhead,$tmp ++ stvx $inout,0,$out ++ addi $out,$out,16 ++ bge Lcbc_enc ++ ++ b Lcbc_done ++ ++.align 4 ++Lcbc_dec: ++ ${UCMP}i $len,128 ++ bge _aesp8_cbc_decrypt8x ++ vmr $tmp,$inptail ++ lvx $inptail,0,$inp ++ addi $inp,$inp,16 ++ mtctr $rounds ++ subi $len,$len,16 # len-=16 ++ ++ lvx $rndkey0,0,$key ++ vperm $tmp,$tmp,$inptail,$inpperm ++ lvx $rndkey1,$idx,$key ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $inout,$tmp,$rndkey0 ++ lvx $rndkey0,$idx,$key ++ addi $idx,$idx,16 ++ ++Loop_cbc_dec: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vncipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vncipher $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key ++ addi $idx,$idx,16 ++ bdnz Loop_cbc_dec ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vncipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key ++ li $idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vncipherlast $inout,$inout,$rndkey0 ++ ${UCMP}i $len,16 ++ ++ vxor $inout,$inout,$ivec ++ vmr $ivec,$tmp ++ vperm $tmp,$inout,$inout,$outperm ++ vsel $inout,$outhead,$tmp,$outmask ++ vmr $outhead,$tmp ++ stvx $inout,0,$out ++ addi $out,$out,16 ++ bge Lcbc_dec ++ ++Lcbc_done: ++ addi $out,$out,-1 ++ lvx $inout,0,$out # redundant in aligned case ++ vsel $inout,$outhead,$inout,$outmask ++ stvx $inout,0,$out ++ ++ neg $enc,$ivp # write [unaligned] iv ++ li $idx,15 # 15 is not typo ++ vxor $rndkey0,$rndkey0,$rndkey0 ++ vspltisb $outmask,-1 ++ le?vspltisb $tmp,0x0f ++ ?lvsl $outperm,0,$enc ++ ?vperm $outmask,$rndkey0,$outmask,$outperm ++ le?vxor $outperm,$outperm,$tmp ++ lvx $outhead,0,$ivp ++ vperm $ivec,$ivec,$ivec,$outperm ++ vsel $inout,$outhead,$ivec,$outmask ++ lvx $inptail,$idx,$ivp ++ stvx $inout,0,$ivp ++ vsel $inout,$ivec,$inptail,$outmask ++ stvx $inout,$idx,$ivp ++ ++ mtspr 256,$vrsave ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,6,0 ++ .long 0 ++___ ++######################################################################### ++{{ # Optimized CBC decrypt procedure # ++my $key_="r11"; ++my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31)); ++my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10..13)); ++my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(14..21)); ++my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys ++ # v26-v31 last 6 round keys ++my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment ++ ++$code.=<<___; ++.align 5 ++_aesp8_cbc_decrypt8x: ++ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) ++ li r10,`$FRAME+8*16+15` ++ li r11,`$FRAME+8*16+31` ++ stvx v20,r10,$sp # ABI says so ++ addi r10,r10,32 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$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 ++ subi $len,$len,128 # bias ++ ++ lvx $rndkey0,$x00,$key # load key schedule ++ lvx v30,$x10,$key ++ addi $key,$key,0x20 ++ lvx v31,$x00,$key ++ ?vperm $rndkey0,$rndkey0,v30,$keyperm ++ addi $key_,$sp,$FRAME+15 ++ mtctr $rounds ++ ++Load_cbc_dec_key: ++ ?vperm v24,v30,v31,$keyperm ++ lvx v30,$x10,$key ++ addi $key,$key,0x20 ++ stvx v24,$x00,$key_ # off-load round[1] ++ ?vperm v25,v31,v30,$keyperm ++ lvx v31,$x00,$key ++ stvx v25,$x10,$key_ # off-load round[2] ++ addi $key_,$key_,0x20 ++ bdnz Load_cbc_dec_key ++ ++ lvx v26,$x10,$key ++ ?vperm v24,v30,v31,$keyperm ++ lvx v27,$x20,$key ++ stvx v24,$x00,$key_ # off-load round[3] ++ ?vperm v25,v31,v26,$keyperm ++ lvx v28,$x30,$key ++ stvx v25,$x10,$key_ # off-load round[4] ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ ?vperm v26,v26,v27,$keyperm ++ lvx v29,$x40,$key ++ ?vperm v27,v27,v28,$keyperm ++ lvx v30,$x50,$key ++ ?vperm v28,v28,v29,$keyperm ++ lvx v31,$x60,$key ++ ?vperm v29,v29,v30,$keyperm ++ lvx $out0,$x70,$key # borrow $out0 ++ ?vperm v30,v30,v31,$keyperm ++ lvx v24,$x00,$key_ # pre-load round[1] ++ ?vperm v31,v31,$out0,$keyperm ++ lvx v25,$x10,$key_ # pre-load round[2] ++ ++ #lvx $inptail,0,$inp # "caller" already did this ++ #addi $inp,$inp,15 # 15 is not typo ++ subi $inp,$inp,15 # undo "caller" ++ ++ le?li $idx,8 ++ lvx_u $in0,$x00,$inp # load first 8 "words" ++ le?lvsl $inpperm,0,$idx ++ le?vspltisb $tmp,0x0f ++ lvx_u $in1,$x10,$inp ++ le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u ++ lvx_u $in2,$x20,$inp ++ le?vperm $in0,$in0,$in0,$inpperm ++ lvx_u $in3,$x30,$inp ++ le?vperm $in1,$in1,$in1,$inpperm ++ lvx_u $in4,$x40,$inp ++ le?vperm $in2,$in2,$in2,$inpperm ++ vxor $out0,$in0,$rndkey0 ++ lvx_u $in5,$x50,$inp ++ le?vperm $in3,$in3,$in3,$inpperm ++ vxor $out1,$in1,$rndkey0 ++ lvx_u $in6,$x60,$inp ++ le?vperm $in4,$in4,$in4,$inpperm ++ vxor $out2,$in2,$rndkey0 ++ lvx_u $in7,$x70,$inp ++ addi $inp,$inp,0x80 ++ le?vperm $in5,$in5,$in5,$inpperm ++ vxor $out3,$in3,$rndkey0 ++ le?vperm $in6,$in6,$in6,$inpperm ++ vxor $out4,$in4,$rndkey0 ++ le?vperm $in7,$in7,$in7,$inpperm ++ vxor $out5,$in5,$rndkey0 ++ vxor $out6,$in6,$rndkey0 ++ vxor $out7,$in7,$rndkey0 ++ ++ mtctr $rounds ++ b Loop_cbc_dec8x ++.align 5 ++Loop_cbc_dec8x: ++ vncipher $out0,$out0,v24 ++ vncipher $out1,$out1,v24 ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vncipher $out4,$out4,v24 ++ vncipher $out5,$out5,v24 ++ vncipher $out6,$out6,v24 ++ vncipher $out7,$out7,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 ++ vncipher $out6,$out6,v25 ++ vncipher $out7,$out7,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Loop_cbc_dec8x ++ ++ subic $len,$len,128 # $len-=128 ++ vncipher $out0,$out0,v24 ++ vncipher $out1,$out1,v24 ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vncipher $out4,$out4,v24 ++ vncipher $out5,$out5,v24 ++ vncipher $out6,$out6,v24 ++ vncipher $out7,$out7,v24 ++ ++ subfe. r0,r0,r0 # borrow?-1:0 ++ vncipher $out0,$out0,v25 ++ vncipher $out1,$out1,v25 ++ vncipher $out2,$out2,v25 ++ vncipher $out3,$out3,v25 ++ vncipher $out4,$out4,v25 ++ vncipher $out5,$out5,v25 ++ vncipher $out6,$out6,v25 ++ vncipher $out7,$out7,v25 ++ ++ and r0,r0,$len ++ vncipher $out0,$out0,v26 ++ vncipher $out1,$out1,v26 ++ vncipher $out2,$out2,v26 ++ vncipher $out3,$out3,v26 ++ vncipher $out4,$out4,v26 ++ vncipher $out5,$out5,v26 ++ vncipher $out6,$out6,v26 ++ vncipher $out7,$out7,v26 ++ ++ add $inp,$inp,r0 # $inp is adjusted in such ++ # way that at exit from the ++ # loop inX-in7 are loaded ++ # with last "words" ++ vncipher $out0,$out0,v27 ++ vncipher $out1,$out1,v27 ++ vncipher $out2,$out2,v27 ++ vncipher $out3,$out3,v27 ++ vncipher $out4,$out4,v27 ++ vncipher $out5,$out5,v27 ++ vncipher $out6,$out6,v27 ++ vncipher $out7,$out7,v27 ++ ++ 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 ++ vncipher $out5,$out5,v28 ++ vncipher $out6,$out6,v28 ++ vncipher $out7,$out7,v28 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ ++ vncipher $out0,$out0,v29 ++ vncipher $out1,$out1,v29 ++ vncipher $out2,$out2,v29 ++ vncipher $out3,$out3,v29 ++ vncipher $out4,$out4,v29 ++ vncipher $out5,$out5,v29 ++ vncipher $out6,$out6,v29 ++ vncipher $out7,$out7,v29 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ ++ vncipher $out0,$out0,v30 ++ vxor $ivec,$ivec,v31 # xor with last round key ++ vncipher $out1,$out1,v30 ++ vxor $in0,$in0,v31 ++ vncipher $out2,$out2,v30 ++ vxor $in1,$in1,v31 ++ vncipher $out3,$out3,v30 ++ vxor $in2,$in2,v31 ++ vncipher $out4,$out4,v30 ++ vxor $in3,$in3,v31 ++ vncipher $out5,$out5,v30 ++ vxor $in4,$in4,v31 ++ vncipher $out6,$out6,v30 ++ vxor $in5,$in5,v31 ++ vncipher $out7,$out7,v30 ++ vxor $in6,$in6,v31 ++ ++ vncipherlast $out0,$out0,$ivec ++ vncipherlast $out1,$out1,$in0 ++ lvx_u $in0,$x00,$inp # load next input block ++ vncipherlast $out2,$out2,$in1 ++ lvx_u $in1,$x10,$inp ++ vncipherlast $out3,$out3,$in2 ++ le?vperm $in0,$in0,$in0,$inpperm ++ lvx_u $in2,$x20,$inp ++ vncipherlast $out4,$out4,$in3 ++ le?vperm $in1,$in1,$in1,$inpperm ++ lvx_u $in3,$x30,$inp ++ vncipherlast $out5,$out5,$in4 ++ le?vperm $in2,$in2,$in2,$inpperm ++ lvx_u $in4,$x40,$inp ++ vncipherlast $out6,$out6,$in5 ++ le?vperm $in3,$in3,$in3,$inpperm ++ lvx_u $in5,$x50,$inp ++ vncipherlast $out7,$out7,$in6 ++ le?vperm $in4,$in4,$in4,$inpperm ++ lvx_u $in6,$x60,$inp ++ vmr $ivec,$in7 ++ le?vperm $in5,$in5,$in5,$inpperm ++ lvx_u $in7,$x70,$inp ++ addi $inp,$inp,0x80 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ le?vperm $in6,$in6,$in6,$inpperm ++ vxor $out0,$in0,$rndkey0 ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x10,$out ++ le?vperm $in7,$in7,$in7,$inpperm ++ vxor $out1,$in1,$rndkey0 ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x20,$out ++ vxor $out2,$in2,$rndkey0 ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x30,$out ++ vxor $out3,$in3,$rndkey0 ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x40,$out ++ vxor $out4,$in4,$rndkey0 ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x50,$out ++ vxor $out5,$in5,$rndkey0 ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x60,$out ++ vxor $out6,$in6,$rndkey0 ++ stvx_u $out7,$x70,$out ++ addi $out,$out,0x80 ++ vxor $out7,$in7,$rndkey0 ++ ++ mtctr $rounds ++ beq Loop_cbc_dec8x # did $len-=128 borrow? ++ ++ addic. $len,$len,128 ++ beq Lcbc_dec8x_done ++ nop ++ nop ++ ++Loop_cbc_dec8x_tail: # up to 7 "words" tail... ++ vncipher $out1,$out1,v24 ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vncipher $out4,$out4,v24 ++ vncipher $out5,$out5,v24 ++ vncipher $out6,$out6,v24 ++ vncipher $out7,$out7,v24 ++ lvx v24,$x20,$key_ # round[3] ++ addi $key_,$key_,0x20 ++ ++ vncipher $out1,$out1,v25 ++ vncipher $out2,$out2,v25 ++ vncipher $out3,$out3,v25 ++ vncipher $out4,$out4,v25 ++ vncipher $out5,$out5,v25 ++ vncipher $out6,$out6,v25 ++ vncipher $out7,$out7,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Loop_cbc_dec8x_tail ++ ++ vncipher $out1,$out1,v24 ++ vncipher $out2,$out2,v24 ++ vncipher $out3,$out3,v24 ++ vncipher $out4,$out4,v24 ++ vncipher $out5,$out5,v24 ++ vncipher $out6,$out6,v24 ++ vncipher $out7,$out7,v24 ++ ++ vncipher $out1,$out1,v25 ++ vncipher $out2,$out2,v25 ++ vncipher $out3,$out3,v25 ++ vncipher $out4,$out4,v25 ++ vncipher $out5,$out5,v25 ++ vncipher $out6,$out6,v25 ++ vncipher $out7,$out7,v25 ++ ++ vncipher $out1,$out1,v26 ++ vncipher $out2,$out2,v26 ++ vncipher $out3,$out3,v26 ++ vncipher $out4,$out4,v26 ++ vncipher $out5,$out5,v26 ++ vncipher $out6,$out6,v26 ++ vncipher $out7,$out7,v26 ++ ++ vncipher $out1,$out1,v27 ++ vncipher $out2,$out2,v27 ++ vncipher $out3,$out3,v27 ++ vncipher $out4,$out4,v27 ++ vncipher $out5,$out5,v27 ++ vncipher $out6,$out6,v27 ++ vncipher $out7,$out7,v27 ++ ++ vncipher $out1,$out1,v28 ++ vncipher $out2,$out2,v28 ++ vncipher $out3,$out3,v28 ++ vncipher $out4,$out4,v28 ++ vncipher $out5,$out5,v28 ++ vncipher $out6,$out6,v28 ++ vncipher $out7,$out7,v28 ++ ++ vncipher $out1,$out1,v29 ++ vncipher $out2,$out2,v29 ++ vncipher $out3,$out3,v29 ++ vncipher $out4,$out4,v29 ++ vncipher $out5,$out5,v29 ++ vncipher $out6,$out6,v29 ++ vncipher $out7,$out7,v29 ++ ++ vncipher $out1,$out1,v30 ++ vxor $ivec,$ivec,v31 # last round key ++ vncipher $out2,$out2,v30 ++ vxor $in1,$in1,v31 ++ vncipher $out3,$out3,v30 ++ vxor $in2,$in2,v31 ++ vncipher $out4,$out4,v30 ++ vxor $in3,$in3,v31 ++ vncipher $out5,$out5,v30 ++ vxor $in4,$in4,v31 ++ vncipher $out6,$out6,v30 ++ vxor $in5,$in5,v31 ++ vncipher $out7,$out7,v30 ++ vxor $in6,$in6,v31 ++ ++ cmplwi $len,32 # switch($len) ++ blt Lcbc_dec8x_one ++ nop ++ beq Lcbc_dec8x_two ++ cmplwi $len,64 ++ blt Lcbc_dec8x_three ++ nop ++ beq Lcbc_dec8x_four ++ cmplwi $len,96 ++ blt Lcbc_dec8x_five ++ nop ++ beq Lcbc_dec8x_six ++ ++Lcbc_dec8x_seven: ++ vncipherlast $out1,$out1,$ivec ++ vncipherlast $out2,$out2,$in1 ++ vncipherlast $out3,$out3,$in2 ++ vncipherlast $out4,$out4,$in3 ++ vncipherlast $out5,$out5,$in4 ++ vncipherlast $out6,$out6,$in5 ++ vncipherlast $out7,$out7,$in6 ++ vmr $ivec,$in7 ++ ++ le?vperm $out1,$out1,$out1,$inpperm ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x00,$out ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x10,$out ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x20,$out ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x30,$out ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x40,$out ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x50,$out ++ stvx_u $out7,$x60,$out ++ addi $out,$out,0x70 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lcbc_dec8x_six: ++ vncipherlast $out2,$out2,$ivec ++ vncipherlast $out3,$out3,$in2 ++ vncipherlast $out4,$out4,$in3 ++ vncipherlast $out5,$out5,$in4 ++ vncipherlast $out6,$out6,$in5 ++ vncipherlast $out7,$out7,$in6 ++ vmr $ivec,$in7 ++ ++ le?vperm $out2,$out2,$out2,$inpperm ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x00,$out ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x10,$out ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x20,$out ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x30,$out ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x40,$out ++ stvx_u $out7,$x50,$out ++ addi $out,$out,0x60 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lcbc_dec8x_five: ++ vncipherlast $out3,$out3,$ivec ++ vncipherlast $out4,$out4,$in3 ++ vncipherlast $out5,$out5,$in4 ++ vncipherlast $out6,$out6,$in5 ++ vncipherlast $out7,$out7,$in6 ++ vmr $ivec,$in7 ++ ++ le?vperm $out3,$out3,$out3,$inpperm ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x00,$out ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x10,$out ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x20,$out ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x30,$out ++ stvx_u $out7,$x40,$out ++ addi $out,$out,0x50 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lcbc_dec8x_four: ++ vncipherlast $out4,$out4,$ivec ++ vncipherlast $out5,$out5,$in4 ++ vncipherlast $out6,$out6,$in5 ++ vncipherlast $out7,$out7,$in6 ++ vmr $ivec,$in7 ++ ++ le?vperm $out4,$out4,$out4,$inpperm ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x00,$out ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x10,$out ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x20,$out ++ stvx_u $out7,$x30,$out ++ addi $out,$out,0x40 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lcbc_dec8x_three: ++ vncipherlast $out5,$out5,$ivec ++ vncipherlast $out6,$out6,$in5 ++ vncipherlast $out7,$out7,$in6 ++ vmr $ivec,$in7 ++ ++ le?vperm $out5,$out5,$out5,$inpperm ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x00,$out ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x10,$out ++ stvx_u $out7,$x20,$out ++ addi $out,$out,0x30 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lcbc_dec8x_two: ++ vncipherlast $out6,$out6,$ivec ++ vncipherlast $out7,$out7,$in6 ++ vmr $ivec,$in7 ++ ++ le?vperm $out6,$out6,$out6,$inpperm ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x00,$out ++ stvx_u $out7,$x10,$out ++ addi $out,$out,0x20 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lcbc_dec8x_one: ++ vncipherlast $out7,$out7,$ivec ++ vmr $ivec,$in7 ++ ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out7,0,$out ++ addi $out,$out,0x10 ++ ++Lcbc_dec8x_done: ++ le?vperm $ivec,$ivec,$ivec,$inpperm ++ stvx_u $ivec,0,$ivp # write [unaligned] iv ++ ++ li r10,`$FRAME+15` ++ li r11,`$FRAME+31` ++ stvx $inpperm,r10,$sp # wipe copies of round keys ++ addi r10,r10,32 ++ stvx $inpperm,r11,$sp ++ addi r11,r11,32 ++ stvx $inpperm,r10,$sp ++ addi r10,r10,32 ++ stvx $inpperm,r11,$sp ++ addi r11,r11,32 ++ stvx $inpperm,r10,$sp ++ addi r10,r10,32 ++ stvx $inpperm,r11,$sp ++ addi r11,r11,32 ++ stvx $inpperm,r10,$sp ++ addi r10,r10,32 ++ stvx $inpperm,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,0x14,0,0x80,6,6,0 ++ .long 0 ++.size .${prefix}_cbc_encrypt,.-.${prefix}_cbc_encrypt ++___ ++}} }}} ++ ++######################################################################### ++{{{ # CTR procedure[s] # ++my ($inp,$out,$len,$key,$ivp,$x10,$rounds,$idx)=map("r$_",(3..10)); ++my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3)); ++my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm,$one)= ++ map("v$_",(4..11)); ++my $dat=$tmp; ++ ++$code.=<<___; ++.globl .${prefix}_ctr32_encrypt_blocks ++.align 5 ++.${prefix}_ctr32_encrypt_blocks: ++ ${UCMP}i $len,1 ++ bltlr- ++ ++ lis r0,0xfff0 ++ mfspr $vrsave,256 ++ mtspr 256,r0 ++ ++ li $idx,15 ++ vxor $rndkey0,$rndkey0,$rndkey0 ++ le?vspltisb $tmp,0x0f ++ ++ lvx $ivec,0,$ivp # load [unaligned] iv ++ lvsl $inpperm,0,$ivp ++ lvx $inptail,$idx,$ivp ++ vspltisb $one,1 ++ le?vxor $inpperm,$inpperm,$tmp ++ vperm $ivec,$ivec,$inptail,$inpperm ++ vsldoi $one,$rndkey0,$one,1 ++ ++ neg r11,$inp ++ ?lvsl $keyperm,0,$key # prepare for unaligned key ++ lwz $rounds,240($key) ++ ++ lvsr $inpperm,0,r11 # prepare for unaligned load ++ lvx $inptail,0,$inp ++ addi $inp,$inp,15 # 15 is not typo ++ le?vxor $inpperm,$inpperm,$tmp ++ ++ srwi $rounds,$rounds,1 ++ li $idx,16 ++ subi $rounds,$rounds,1 ++ ++ ${UCMP}i $len,8 ++ bge _aesp8_ctr32_encrypt8x ++ ++ ?lvsr $outperm,0,$out # prepare for unaligned store ++ vspltisb $outmask,-1 ++ lvx $outhead,0,$out ++ ?vperm $outmask,$rndkey0,$outmask,$outperm ++ le?vxor $outperm,$outperm,$tmp ++ ++ lvx $rndkey0,0,$key ++ mtctr $rounds ++ lvx $rndkey1,$idx,$key ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vxor $inout,$ivec,$rndkey0 ++ lvx $rndkey0,$idx,$key ++ addi $idx,$idx,16 ++ b Loop_ctr32_enc ++ ++.align 5 ++Loop_ctr32_enc: ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key ++ addi $idx,$idx,16 ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vcipher $inout,$inout,$rndkey0 ++ lvx $rndkey0,$idx,$key ++ addi $idx,$idx,16 ++ bdnz Loop_ctr32_enc ++ ++ vadduwm $ivec,$ivec,$one ++ vmr $dat,$inptail ++ lvx $inptail,0,$inp ++ addi $inp,$inp,16 ++ subic. $len,$len,1 # blocks-- ++ ++ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm ++ vcipher $inout,$inout,$rndkey1 ++ lvx $rndkey1,$idx,$key ++ vperm $dat,$dat,$inptail,$inpperm ++ li $idx,16 ++ ?vperm $rndkey1,$rndkey0,$rndkey1,$keyperm ++ lvx $rndkey0,0,$key ++ vxor $dat,$dat,$rndkey1 # last round key ++ vcipherlast $inout,$inout,$dat ++ ++ lvx $rndkey1,$idx,$key ++ addi $idx,$idx,16 ++ vperm $inout,$inout,$inout,$outperm ++ vsel $dat,$outhead,$inout,$outmask ++ mtctr $rounds ++ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm ++ vmr $outhead,$inout ++ vxor $inout,$ivec,$rndkey0 ++ lvx $rndkey0,$idx,$key ++ addi $idx,$idx,16 ++ stvx $dat,0,$out ++ addi $out,$out,16 ++ bne Loop_ctr32_enc ++ ++ addi $out,$out,-1 ++ lvx $inout,0,$out # redundant in aligned case ++ vsel $inout,$outhead,$inout,$outmask ++ stvx $inout,0,$out ++ ++ mtspr 256,$vrsave ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,6,0 ++ .long 0 ++___ ++######################################################################### ++{{ # Optimized CTR procedure # ++my $key_="r11"; ++my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31)); ++my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10,12..14)); ++my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(15..22)); ++my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys ++ # v26-v31 last 6 round keys ++my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment ++my ($two,$three,$four)=($outhead,$outperm,$outmask); ++ ++$code.=<<___; ++.align 5 ++_aesp8_ctr32_encrypt8x: ++ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) ++ li r10,`$FRAME+8*16+15` ++ li r11,`$FRAME+8*16+31` ++ stvx v20,r10,$sp # ABI says so ++ addi r10,r10,32 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$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,$key # load key schedule ++ lvx v30,$x10,$key ++ addi $key,$key,0x20 ++ lvx v31,$x00,$key ++ ?vperm $rndkey0,$rndkey0,v30,$keyperm ++ addi $key_,$sp,$FRAME+15 ++ mtctr $rounds ++ ++Load_ctr32_enc_key: ++ ?vperm v24,v30,v31,$keyperm ++ lvx v30,$x10,$key ++ addi $key,$key,0x20 ++ stvx v24,$x00,$key_ # off-load round[1] ++ ?vperm v25,v31,v30,$keyperm ++ lvx v31,$x00,$key ++ stvx v25,$x10,$key_ # off-load round[2] ++ addi $key_,$key_,0x20 ++ bdnz Load_ctr32_enc_key ++ ++ lvx v26,$x10,$key ++ ?vperm v24,v30,v31,$keyperm ++ lvx v27,$x20,$key ++ stvx v24,$x00,$key_ # off-load round[3] ++ ?vperm v25,v31,v26,$keyperm ++ lvx v28,$x30,$key ++ stvx v25,$x10,$key_ # off-load round[4] ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ ?vperm v26,v26,v27,$keyperm ++ lvx v29,$x40,$key ++ ?vperm v27,v27,v28,$keyperm ++ lvx v30,$x50,$key ++ ?vperm v28,v28,v29,$keyperm ++ lvx v31,$x60,$key ++ ?vperm v29,v29,v30,$keyperm ++ lvx $out0,$x70,$key # borrow $out0 ++ ?vperm v30,v30,v31,$keyperm ++ lvx v24,$x00,$key_ # pre-load round[1] ++ ?vperm v31,v31,$out0,$keyperm ++ lvx v25,$x10,$key_ # pre-load round[2] ++ ++ vadduwm $two,$one,$one ++ subi $inp,$inp,15 # undo "caller" ++ $SHL $len,$len,4 ++ ++ vadduwm $out1,$ivec,$one # counter values ... ++ vadduwm $out2,$ivec,$two ++ vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0] ++ le?li $idx,8 ++ vadduwm $out3,$out1,$two ++ vxor $out1,$out1,$rndkey0 ++ le?lvsl $inpperm,0,$idx ++ vadduwm $out4,$out2,$two ++ vxor $out2,$out2,$rndkey0 ++ le?vspltisb $tmp,0x0f ++ vadduwm $out5,$out3,$two ++ vxor $out3,$out3,$rndkey0 ++ le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u ++ vadduwm $out6,$out4,$two ++ vxor $out4,$out4,$rndkey0 ++ vadduwm $out7,$out5,$two ++ vxor $out5,$out5,$rndkey0 ++ vadduwm $ivec,$out6,$two # next counter value ++ vxor $out6,$out6,$rndkey0 ++ vxor $out7,$out7,$rndkey0 ++ ++ mtctr $rounds ++ b Loop_ctr32_enc8x ++.align 5 ++Loop_ctr32_enc8x: ++ vcipher $out0,$out0,v24 ++ vcipher $out1,$out1,v24 ++ vcipher $out2,$out2,v24 ++ vcipher $out3,$out3,v24 ++ vcipher $out4,$out4,v24 ++ vcipher $out5,$out5,v24 ++ vcipher $out6,$out6,v24 ++ vcipher $out7,$out7,v24 ++Loop_ctr32_enc8x_middle: ++ 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 ++ vcipher $out6,$out6,v25 ++ vcipher $out7,$out7,v25 ++ lvx v25,$x10,$key_ # round[4] ++ bdnz Loop_ctr32_enc8x ++ ++ subic r11,$len,256 # $len-256, borrow $key_ ++ vcipher $out0,$out0,v24 ++ vcipher $out1,$out1,v24 ++ vcipher $out2,$out2,v24 ++ vcipher $out3,$out3,v24 ++ vcipher $out4,$out4,v24 ++ vcipher $out5,$out5,v24 ++ vcipher $out6,$out6,v24 ++ vcipher $out7,$out7,v24 ++ ++ subfe r0,r0,r0 # borrow?-1:0 ++ vcipher $out0,$out0,v25 ++ vcipher $out1,$out1,v25 ++ vcipher $out2,$out2,v25 ++ vcipher $out3,$out3,v25 ++ vcipher $out4,$out4,v25 ++ vcipher $out5,$out5,v25 ++ vcipher $out6,$out6,v25 ++ vcipher $out7,$out7,v25 ++ ++ and r0,r0,r11 ++ addi $key_,$sp,$FRAME+15 # rewind $key_ ++ vcipher $out0,$out0,v26 ++ vcipher $out1,$out1,v26 ++ vcipher $out2,$out2,v26 ++ vcipher $out3,$out3,v26 ++ vcipher $out4,$out4,v26 ++ vcipher $out5,$out5,v26 ++ vcipher $out6,$out6,v26 ++ vcipher $out7,$out7,v26 ++ lvx v24,$x00,$key_ # re-pre-load round[1] ++ ++ subic $len,$len,129 # $len-=129 ++ vcipher $out0,$out0,v27 ++ addi $len,$len,1 # $len-=128 really ++ vcipher $out1,$out1,v27 ++ vcipher $out2,$out2,v27 ++ vcipher $out3,$out3,v27 ++ vcipher $out4,$out4,v27 ++ vcipher $out5,$out5,v27 ++ vcipher $out6,$out6,v27 ++ vcipher $out7,$out7,v27 ++ lvx v25,$x10,$key_ # re-pre-load round[2] ++ ++ vcipher $out0,$out0,v28 ++ lvx_u $in0,$x00,$inp # load input ++ vcipher $out1,$out1,v28 ++ lvx_u $in1,$x10,$inp ++ vcipher $out2,$out2,v28 ++ lvx_u $in2,$x20,$inp ++ vcipher $out3,$out3,v28 ++ lvx_u $in3,$x30,$inp ++ vcipher $out4,$out4,v28 ++ lvx_u $in4,$x40,$inp ++ vcipher $out5,$out5,v28 ++ lvx_u $in5,$x50,$inp ++ vcipher $out6,$out6,v28 ++ lvx_u $in6,$x60,$inp ++ vcipher $out7,$out7,v28 ++ lvx_u $in7,$x70,$inp ++ addi $inp,$inp,0x80 ++ ++ vcipher $out0,$out0,v29 ++ le?vperm $in0,$in0,$in0,$inpperm ++ vcipher $out1,$out1,v29 ++ le?vperm $in1,$in1,$in1,$inpperm ++ vcipher $out2,$out2,v29 ++ le?vperm $in2,$in2,$in2,$inpperm ++ vcipher $out3,$out3,v29 ++ le?vperm $in3,$in3,$in3,$inpperm ++ vcipher $out4,$out4,v29 ++ le?vperm $in4,$in4,$in4,$inpperm ++ vcipher $out5,$out5,v29 ++ le?vperm $in5,$in5,$in5,$inpperm ++ vcipher $out6,$out6,v29 ++ le?vperm $in6,$in6,$in6,$inpperm ++ vcipher $out7,$out7,v29 ++ le?vperm $in7,$in7,$in7,$inpperm ++ ++ add $inp,$inp,r0 # $inp is adjusted in such ++ # way that at exit from the ++ # loop inX-in7 are loaded ++ # with last "words" ++ subfe. r0,r0,r0 # borrow?-1:0 ++ vcipher $out0,$out0,v30 ++ vxor $in0,$in0,v31 # xor with last round key ++ vcipher $out1,$out1,v30 ++ vxor $in1,$in1,v31 ++ vcipher $out2,$out2,v30 ++ vxor $in2,$in2,v31 ++ vcipher $out3,$out3,v30 ++ vxor $in3,$in3,v31 ++ vcipher $out4,$out4,v30 ++ vxor $in4,$in4,v31 ++ vcipher $out5,$out5,v30 ++ vxor $in5,$in5,v31 ++ vcipher $out6,$out6,v30 ++ vxor $in6,$in6,v31 ++ vcipher $out7,$out7,v30 ++ vxor $in7,$in7,v31 ++ ++ bne Lctr32_enc8x_break # did $len-129 borrow? ++ ++ vcipherlast $in0,$out0,$in0 ++ vcipherlast $in1,$out1,$in1 ++ vadduwm $out1,$ivec,$one # counter values ... ++ vcipherlast $in2,$out2,$in2 ++ vadduwm $out2,$ivec,$two ++ vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0] ++ vcipherlast $in3,$out3,$in3 ++ vadduwm $out3,$out1,$two ++ vxor $out1,$out1,$rndkey0 ++ vcipherlast $in4,$out4,$in4 ++ vadduwm $out4,$out2,$two ++ vxor $out2,$out2,$rndkey0 ++ vcipherlast $in5,$out5,$in5 ++ vadduwm $out5,$out3,$two ++ vxor $out3,$out3,$rndkey0 ++ vcipherlast $in6,$out6,$in6 ++ vadduwm $out6,$out4,$two ++ vxor $out4,$out4,$rndkey0 ++ vcipherlast $in7,$out7,$in7 ++ vadduwm $out7,$out5,$two ++ vxor $out5,$out5,$rndkey0 ++ le?vperm $in0,$in0,$in0,$inpperm ++ vadduwm $ivec,$out6,$two # next counter value ++ vxor $out6,$out6,$rndkey0 ++ le?vperm $in1,$in1,$in1,$inpperm ++ vxor $out7,$out7,$rndkey0 ++ mtctr $rounds ++ ++ vcipher $out0,$out0,v24 ++ stvx_u $in0,$x00,$out ++ le?vperm $in2,$in2,$in2,$inpperm ++ vcipher $out1,$out1,v24 ++ stvx_u $in1,$x10,$out ++ le?vperm $in3,$in3,$in3,$inpperm ++ vcipher $out2,$out2,v24 ++ stvx_u $in2,$x20,$out ++ le?vperm $in4,$in4,$in4,$inpperm ++ vcipher $out3,$out3,v24 ++ stvx_u $in3,$x30,$out ++ le?vperm $in5,$in5,$in5,$inpperm ++ vcipher $out4,$out4,v24 ++ stvx_u $in4,$x40,$out ++ le?vperm $in6,$in6,$in6,$inpperm ++ vcipher $out5,$out5,v24 ++ stvx_u $in5,$x50,$out ++ le?vperm $in7,$in7,$in7,$inpperm ++ vcipher $out6,$out6,v24 ++ stvx_u $in6,$x60,$out ++ vcipher $out7,$out7,v24 ++ stvx_u $in7,$x70,$out ++ addi $out,$out,0x80 ++ ++ b Loop_ctr32_enc8x_middle ++ ++.align 5 ++Lctr32_enc8x_break: ++ cmpwi $len,-0x60 ++ blt Lctr32_enc8x_one ++ nop ++ beq Lctr32_enc8x_two ++ cmpwi $len,-0x40 ++ blt Lctr32_enc8x_three ++ nop ++ beq Lctr32_enc8x_four ++ cmpwi $len,-0x20 ++ blt Lctr32_enc8x_five ++ nop ++ beq Lctr32_enc8x_six ++ cmpwi $len,0x00 ++ blt Lctr32_enc8x_seven ++ ++Lctr32_enc8x_eight: ++ vcipherlast $out0,$out0,$in0 ++ vcipherlast $out1,$out1,$in1 ++ vcipherlast $out2,$out2,$in2 ++ vcipherlast $out3,$out3,$in3 ++ vcipherlast $out4,$out4,$in4 ++ vcipherlast $out5,$out5,$in5 ++ vcipherlast $out6,$out6,$in6 ++ vcipherlast $out7,$out7,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x20,$out ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x30,$out ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x40,$out ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x50,$out ++ le?vperm $out7,$out7,$out7,$inpperm ++ stvx_u $out6,$x60,$out ++ stvx_u $out7,$x70,$out ++ addi $out,$out,0x80 ++ b Lctr32_enc8x_done ++ ++.align 5 ++Lctr32_enc8x_seven: ++ vcipherlast $out0,$out0,$in1 ++ vcipherlast $out1,$out1,$in2 ++ vcipherlast $out2,$out2,$in3 ++ vcipherlast $out3,$out3,$in4 ++ vcipherlast $out4,$out4,$in5 ++ vcipherlast $out5,$out5,$in6 ++ vcipherlast $out6,$out6,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x20,$out ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x30,$out ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x40,$out ++ le?vperm $out6,$out6,$out6,$inpperm ++ stvx_u $out5,$x50,$out ++ stvx_u $out6,$x60,$out ++ addi $out,$out,0x70 ++ b Lctr32_enc8x_done ++ ++.align 5 ++Lctr32_enc8x_six: ++ vcipherlast $out0,$out0,$in2 ++ vcipherlast $out1,$out1,$in3 ++ vcipherlast $out2,$out2,$in4 ++ vcipherlast $out3,$out3,$in5 ++ vcipherlast $out4,$out4,$in6 ++ vcipherlast $out5,$out5,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x20,$out ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x30,$out ++ le?vperm $out5,$out5,$out5,$inpperm ++ stvx_u $out4,$x40,$out ++ stvx_u $out5,$x50,$out ++ addi $out,$out,0x60 ++ b Lctr32_enc8x_done ++ ++.align 5 ++Lctr32_enc8x_five: ++ vcipherlast $out0,$out0,$in3 ++ vcipherlast $out1,$out1,$in4 ++ vcipherlast $out2,$out2,$in5 ++ vcipherlast $out3,$out3,$in6 ++ vcipherlast $out4,$out4,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x20,$out ++ le?vperm $out4,$out4,$out4,$inpperm ++ stvx_u $out3,$x30,$out ++ stvx_u $out4,$x40,$out ++ addi $out,$out,0x50 ++ b Lctr32_enc8x_done ++ ++.align 5 ++Lctr32_enc8x_four: ++ vcipherlast $out0,$out0,$in4 ++ vcipherlast $out1,$out1,$in5 ++ vcipherlast $out2,$out2,$in6 ++ vcipherlast $out3,$out3,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x10,$out ++ le?vperm $out3,$out3,$out3,$inpperm ++ stvx_u $out2,$x20,$out ++ stvx_u $out3,$x30,$out ++ addi $out,$out,0x40 ++ b Lctr32_enc8x_done ++ ++.align 5 ++Lctr32_enc8x_three: ++ vcipherlast $out0,$out0,$in5 ++ vcipherlast $out1,$out1,$in6 ++ vcipherlast $out2,$out2,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ le?vperm $out2,$out2,$out2,$inpperm ++ stvx_u $out1,$x10,$out ++ stvx_u $out2,$x20,$out ++ addi $out,$out,0x30 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lctr32_enc8x_two: ++ vcipherlast $out0,$out0,$in6 ++ vcipherlast $out1,$out1,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ le?vperm $out1,$out1,$out1,$inpperm ++ stvx_u $out0,$x00,$out ++ stvx_u $out1,$x10,$out ++ addi $out,$out,0x20 ++ b Lcbc_dec8x_done ++ ++.align 5 ++Lctr32_enc8x_one: ++ vcipherlast $out0,$out0,$in7 ++ ++ le?vperm $out0,$out0,$out0,$inpperm ++ stvx_u $out0,0,$out ++ addi $out,$out,0x10 ++ ++Lctr32_enc8x_done: ++ li r10,`$FRAME+15` ++ li r11,`$FRAME+31` ++ stvx $inpperm,r10,$sp # wipe copies of round keys ++ addi r10,r10,32 ++ stvx $inpperm,r11,$sp ++ addi r11,r11,32 ++ stvx $inpperm,r10,$sp ++ addi r10,r10,32 ++ stvx $inpperm,r11,$sp ++ addi r11,r11,32 ++ stvx $inpperm,r10,$sp ++ addi r10,r10,32 ++ stvx $inpperm,r11,$sp ++ addi r11,r11,32 ++ stvx $inpperm,r10,$sp ++ addi r10,r10,32 ++ stvx $inpperm,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,0x14,0,0x80,6,6,0 ++ .long 0 ++.size .${prefix}_ctr32_encrypt_blocks,.-.${prefix}_ctr32_encrypt_blocks ++___ ++}} }}} ++ ++my $consts=1; ++foreach(split("\n",$code)) { ++ s/\`([^\`]*)\`/eval($1)/geo; ++ ++ # constants table endian-specific conversion ++ if ($consts && m/\.(long|byte)\s+(.+)\s+(\?[a-z]*)$/o) { ++ my $conv=$3; ++ my @bytes=(); ++ ++ # convert to endian-agnostic format ++ if ($1 eq "long") { ++ foreach (split(/,\s*/,$2)) { ++ my $l = /^0/?oct:int; ++ push @bytes,($l>>24)&0xff,($l>>16)&0xff,($l>>8)&0xff,$l&0xff; ++ } ++ } else { ++ @bytes = map(/^0/?oct:int,split(/,\s*/,$2)); ++ } ++ ++ # little-endian conversion ++ if ($flavour =~ /le$/o) { ++ SWITCH: for($conv) { ++ /\?inv/ && do { @bytes=map($_^0xf,@bytes); last; }; ++ /\?rev/ && do { @bytes=reverse(@bytes); last; }; ++ } ++ } ++ ++ #emit ++ print ".byte\t",join(',',map (sprintf("0x%02x",$_),@bytes)),"\n"; ++ next; ++ } ++ $consts=0 if (m/Lconsts:/o); # end of table ++ ++ # instructions prefixed with '?' are endian-specific and need ++ # to be adjusted accordingly... ++ if ($flavour =~ /le$/o) { # little-endian ++ s/le\?//o or ++ s/be\?/#be#/o or ++ s/\?lvsr/lvsl/o or ++ s/\?lvsl/lvsr/o or ++ s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/o or ++ s/\?(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/o or ++ s/\?(vspltw\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9])/$1$2 3-$3/o; ++ } else { # big-endian ++ s/le\?/#le#/o or ++ s/be\?//o or ++ s/\?([a-z]+)/$1/o; ++ } ++ ++ print $_,"\n"; ++} ++ ++close STDOUT; +diff --git a/crypto/aes/asm/vpaes-ppc.pl b/crypto/aes/asm/vpaes-ppc.pl +new file mode 100644 +index 0000000..7fda60e +--- /dev/null ++++ b/crypto/aes/asm/vpaes-ppc.pl +@@ -0,0 +1,1512 @@ ++#!/usr/bin/env perl ++ ++###################################################################### ++## Constant-time SSSE3 AES core implementation. ++## version 0.1 ++## ++## By Mike Hamburg (Stanford University), 2009 ++## Public domain. ++## ++## For details see http://shiftleft.org/papers/vector_aes/ and ++## http://crypto.stanford.edu/vpaes/. ++ ++# CBC encrypt/decrypt performance in cycles per byte processed with ++# 128-bit key. ++# ++# aes-ppc.pl this ++# G4e 35.5/52.1/(23.8) 11.9(*)/15.4 ++# POWER6 42.7/54.3/(28.2) 63.0/92.8(**) ++# POWER7 32.3/42.9/(18.4) 18.5/23.3 ++# ++# (*) This is ~10% worse than reported in paper. The reason is ++# twofold. This module doesn't make any assumption about ++# key schedule (or data for that matter) alignment and handles ++# it in-line. Secondly it, being transliterated from ++# vpaes-x86_64.pl, relies on "nested inversion" better suited ++# for Intel CPUs. ++# (**) Inadequate POWER6 performance is due to astronomic AltiVec ++# latency, 9 cycles per simple logical operation. ++ ++$flavour = shift; ++ ++if ($flavour =~ /64/) { ++ $SIZE_T =8; ++ $LRSAVE =2*$SIZE_T; ++ $STU ="stdu"; ++ $POP ="ld"; ++ $PUSH ="std"; ++ $UCMP ="cmpld"; ++} elsif ($flavour =~ /32/) { ++ $SIZE_T =4; ++ $LRSAVE =$SIZE_T; ++ $STU ="stwu"; ++ $POP ="lwz"; ++ $PUSH ="stw"; ++ $UCMP ="cmplw"; ++} else { die "nonsense $flavour"; } ++ ++$sp="r1"; ++$FRAME=6*$SIZE_T+13*16; # 13*16 is for v20-v31 offload ++ ++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ++( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ++( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or ++die "can't locate ppc-xlate.pl"; ++ ++open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; ++ ++$code.=<<___; ++.machine "any" ++ ++.text ++ ++.align 7 # totally strategic alignment ++_vpaes_consts: ++Lk_mc_forward: # mc_forward ++ .long 0x01020300, 0x05060704, 0x090a0b08, 0x0d0e0f0c ?inv ++ .long 0x05060704, 0x090a0b08, 0x0d0e0f0c, 0x01020300 ?inv ++ .long 0x090a0b08, 0x0d0e0f0c, 0x01020300, 0x05060704 ?inv ++ .long 0x0d0e0f0c, 0x01020300, 0x05060704, 0x090a0b08 ?inv ++Lk_mc_backward: # mc_backward ++ .long 0x03000102, 0x07040506, 0x0b08090a, 0x0f0c0d0e ?inv ++ .long 0x0f0c0d0e, 0x03000102, 0x07040506, 0x0b08090a ?inv ++ .long 0x0b08090a, 0x0f0c0d0e, 0x03000102, 0x07040506 ?inv ++ .long 0x07040506, 0x0b08090a, 0x0f0c0d0e, 0x03000102 ?inv ++Lk_sr: # sr ++ .long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f ?inv ++ .long 0x00050a0f, 0x04090e03, 0x080d0207, 0x0c01060b ?inv ++ .long 0x0009020b, 0x040d060f, 0x08010a03, 0x0c050e07 ?inv ++ .long 0x000d0a07, 0x04010e0b, 0x0805020f, 0x0c090603 ?inv ++ ++## ++## "Hot" constants ++## ++Lk_inv: # inv, inva ++ .long 0xf001080d, 0x0f06050e, 0x020c0b0a, 0x09030704 ?rev ++ .long 0xf0070b0f, 0x060a0401, 0x09080502, 0x0c0e0d03 ?rev ++Lk_ipt: # input transform (lo, hi) ++ .long 0x00702a5a, 0x98e8b2c2, 0x08782252, 0x90e0baca ?rev ++ .long 0x004d7c31, 0x7d30014c, 0x81ccfdb0, 0xfcb180cd ?rev ++Lk_sbo: # sbou, sbot ++ .long 0x00c7bd6f, 0x176dd2d0, 0x78a802c5, 0x7abfaa15 ?rev ++ .long 0x006abb5f, 0xa574e4cf, 0xfa352b41, 0xd1901e8e ?rev ++Lk_sb1: # sb1u, sb1t ++ .long 0x0023e2fa, 0x15d41836, 0xefd92e0d, 0xc1ccf73b ?rev ++ .long 0x003e50cb, 0x8fe19bb1, 0x44f52a14, 0x6e7adfa5 ?rev ++Lk_sb2: # sb2u, sb2t ++ .long 0x0029e10a, 0x4088eb69, 0x4a2382ab, 0xc863a1c2 ?rev ++ .long 0x0024710b, 0xc6937ae2, 0xcd2f98bc, 0x55e9b75e ?rev ++ ++## ++## Decryption stuff ++## ++Lk_dipt: # decryption input transform ++ .long 0x005f540b, 0x045b500f, 0x1a454e11, 0x1e414a15 ?rev ++ .long 0x00650560, 0xe683e386, 0x94f191f4, 0x72177712 ?rev ++Lk_dsbo: # decryption sbox final output ++ .long 0x0040f97e, 0x53ea8713, 0x2d3e94d4, 0xb96daac7 ?rev ++ .long 0x001d4493, 0x0f56d712, 0x9c8ec5d8, 0x59814bca ?rev ++Lk_dsb9: # decryption sbox output *9*u, *9*t ++ .long 0x00d6869a, 0x53031c85, 0xc94c994f, 0x501fd5ca ?rev ++ .long 0x0049d7ec, 0x89173bc0, 0x65a5fbb2, 0x9e2c5e72 ?rev ++Lk_dsbd: # decryption sbox output *D*u, *D*t ++ .long 0x00a2b1e6, 0xdfcc577d, 0x39442a88, 0x139b6ef5 ?rev ++ .long 0x00cbc624, 0xf7fae23c, 0xd3efde15, 0x0d183129 ?rev ++Lk_dsbb: # decryption sbox output *B*u, *B*t ++ .long 0x0042b496, 0x926422d0, 0x04d4f2b0, 0xf6462660 ?rev ++ .long 0x006759cd, 0xa69894c1, 0x6baa5532, 0x3e0cfff3 ?rev ++Lk_dsbe: # decryption sbox output *E*u, *E*t ++ .long 0x00d0d426, 0x9692f246, 0xb0f6b464, 0x04604222 ?rev ++ .long 0x00c1aaff, 0xcda6550c, 0x323e5998, 0x6bf36794 ?rev ++ ++## ++## Key schedule constants ++## ++Lk_dksd: # decryption key schedule: invskew x*D ++ .long 0x0047e4a3, 0x5d1ab9fe, 0xf9be1d5a, 0xa4e34007 ?rev ++ .long 0x008336b5, 0xf477c241, 0x1e9d28ab, 0xea69dc5f ?rev ++Lk_dksb: # decryption key schedule: invskew x*B ++ .long 0x00d55085, 0x1fca4f9a, 0x994cc91c, 0x8653d603 ?rev ++ .long 0x004afcb6, 0xa7ed5b11, 0xc882347e, 0x6f2593d9 ?rev ++Lk_dkse: # decryption key schedule: invskew x*E + 0x63 ++ .long 0x00d6c91f, 0xca1c03d5, 0x86504f99, 0x4c9a8553 ?rev ++ .long 0xe87bdc4f, 0x059631a2, 0x8714b320, 0x6af95ecd ?rev ++Lk_dks9: # decryption key schedule: invskew x*9 ++ .long 0x00a7d97e, 0xc86f11b6, 0xfc5b2582, 0x3493ed4a ?rev ++ .long 0x00331427, 0x62517645, 0xcefddae9, 0xac9fb88b ?rev ++ ++Lk_rcon: # rcon ++ .long 0xb6ee9daf, 0xb991831f, 0x817d7c4d, 0x08982a70 ?asis ++Lk_s63: ++ .long 0x5b5b5b5b, 0x5b5b5b5b, 0x5b5b5b5b, 0x5b5b5b5b ?asis ++ ++Lk_opt: # output transform ++ .long 0x0060b6d6, 0x29499fff, 0x0868bede, 0x214197f7 ?rev ++ .long 0x00ecbc50, 0x51bded01, 0xe00c5cb0, 0xb15d0de1 ?rev ++Lk_deskew: # deskew tables: inverts the sbox's "skew" ++ .long 0x00e3a447, 0x40a3e407, 0x1af9be5d, 0x5ab9fe1d ?rev ++ .long 0x0069ea83, 0xdcb5365f, 0x771e9df4, 0xabc24128 ?rev ++.align 5 ++Lconsts: ++ mflr r0 ++ bcl 20,31,\$+4 ++ mflr r12 #vvvvv "distance between . and _vpaes_consts ++ addi r12,r12,-0x308 ++ mtlr r0 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++.asciz "Vector Permutation AES for AltiVec, Mike Hamburg (Stanford University)" ++.align 6 ++___ ++ ++my ($inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm) = map("v$_",(26..31)); ++{ ++my ($inp,$out,$key) = map("r$_",(3..5)); ++ ++my ($invlo,$invhi,$iptlo,$ipthi,$sbou,$sbot) = map("v$_",(10..15)); ++my ($sb1u,$sb1t,$sb2u,$sb2t) = map("v$_",(16..19)); ++my ($sb9u,$sb9t,$sbdu,$sbdt,$sbbu,$sbbt,$sbeu,$sbet)=map("v$_",(16..23)); ++ ++$code.=<<___; ++## ++## _aes_preheat ++## ++## Fills register %r10 -> .aes_consts (so you can -fPIC) ++## and %xmm9-%xmm15 as specified below. ++## ++.align 4 ++_vpaes_encrypt_preheat: ++ mflr r8 ++ bl Lconsts ++ mtlr r8 ++ li r11, 0xc0 # Lk_inv ++ li r10, 0xd0 ++ li r9, 0xe0 # Lk_ipt ++ li r8, 0xf0 ++ vxor v7, v7, v7 # 0x00..00 ++ vspltisb v8,4 # 0x04..04 ++ vspltisb v9,0x0f # 0x0f..0f ++ lvx $invlo, r12, r11 ++ li r11, 0x100 ++ lvx $invhi, r12, r10 ++ li r10, 0x110 ++ lvx $iptlo, r12, r9 ++ li r9, 0x120 ++ lvx $ipthi, r12, r8 ++ li r8, 0x130 ++ lvx $sbou, r12, r11 ++ li r11, 0x140 ++ lvx $sbot, r12, r10 ++ li r10, 0x150 ++ lvx $sb1u, r12, r9 ++ lvx $sb1t, r12, r8 ++ lvx $sb2u, r12, r11 ++ lvx $sb2t, r12, r10 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++## ++## _aes_encrypt_core ++## ++## AES-encrypt %xmm0. ++## ++## Inputs: ++## %xmm0 = input ++## %xmm9-%xmm15 as in _vpaes_preheat ++## (%rdx) = scheduled keys ++## ++## Output in %xmm0 ++## Clobbers %xmm1-%xmm6, %r9, %r10, %r11, %rax ++## ++## ++.align 5 ++_vpaes_encrypt_core: ++ lwz r8, 240($key) # pull rounds ++ li r9, 16 ++ lvx v5, 0, $key # vmovdqu (%r9), %xmm5 # round0 key ++ li r11, 0x10 ++ lvx v6, r9, $key ++ addi r9, r9, 16 ++ ?vperm v5, v5, v6, $keyperm # align round key ++ addi r10, r11, 0x40 ++ vsrb v1, v0, v8 # vpsrlb \$4, %xmm0, %xmm0 ++ vperm v0, $iptlo, $iptlo, v0 # vpshufb %xmm1, %xmm2, %xmm1 ++ vperm v1, $ipthi, $ipthi, v1 # vpshufb %xmm0, %xmm3, %xmm2 ++ vxor v0, v0, v5 # vpxor %xmm5, %xmm1, %xmm0 ++ vxor v0, v0, v1 # vpxor %xmm2, %xmm0, %xmm0 ++ mtctr r8 ++ b Lenc_entry ++ ++.align 4 ++Lenc_loop: ++ # middle of middle round ++ vperm v4, $sb1t, v7, v2 # vpshufb %xmm2, %xmm13, %xmm4 # 4 = sb1u ++ lvx v1, r12, r11 # vmovdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] ++ addi r11, r11, 16 ++ vperm v0, $sb1u, v7, v3 # vpshufb %xmm3, %xmm12, %xmm0 # 0 = sb1t ++ vxor v4, v4, v5 # vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k ++ andi. r11, r11, 0x30 # and \$0x30, %r11 # ... mod 4 ++ vperm v5, $sb2t, v7, v2 # vpshufb %xmm2, %xmm15, %xmm5 # 4 = sb2u ++ vxor v0, v0, v4 # vpxor %xmm4, %xmm0, %xmm0 # 0 = A ++ vperm v2, $sb2u, v7, v3 # vpshufb %xmm3, %xmm14, %xmm2 # 2 = sb2t ++ lvx v4, r12, r10 # vmovdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] ++ addi r10, r11, 0x40 ++ vperm v3, v0, v7, v1 # vpshufb %xmm1, %xmm0, %xmm3 # 0 = B ++ vxor v2, v2, v5 # vpxor %xmm5, %xmm2, %xmm2 # 2 = 2A ++ vperm v0, v0, v7, v4 # vpshufb %xmm4, %xmm0, %xmm0 # 3 = D ++ vxor v3, v3, v2 # vpxor %xmm2, %xmm3, %xmm3 # 0 = 2A+B ++ vperm v4, v3, v7, v1 # vpshufb %xmm1, %xmm3, %xmm4 # 0 = 2B+C ++ vxor v0, v0, v3 # vpxor %xmm3, %xmm0, %xmm0 # 3 = 2A+B+D ++ vxor v0, v0, v4 # vpxor %xmm4, %xmm0, %xmm0 # 0 = 2A+3B+C+D ++ ++Lenc_entry: ++ # top of round ++ vsrb v1, v0, v8 # vpsrlb \$4, %xmm0, %xmm0 # 1 = i ++ vperm v5, $invhi, $invhi, v0 # vpshufb %xmm1, %xmm11, %xmm5 # 2 = a/k ++ vxor v0, v0, v1 # vpxor %xmm0, %xmm1, %xmm1 # 0 = j ++ vperm v3, $invlo, $invlo, v1 # vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i ++ vperm v4, $invlo, $invlo, v0 # vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j ++ vand v0, v0, v9 ++ vxor v3, v3, v5 # vpxor %xmm5, %xmm3, %xmm3 # 3 = iak = 1/i + a/k ++ vxor v4, v4, v5 # vpxor %xmm5, %xmm4, %xmm4 # 4 = jak = 1/j + a/k ++ vperm v2, $invlo, v7, v3 # vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak ++ vmr v5, v6 ++ lvx v6, r9, $key # vmovdqu (%r9), %xmm5 ++ vperm v3, $invlo, v7, v4 # vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak ++ addi r9, r9, 16 ++ vxor v2, v2, v0 # vpxor %xmm1, %xmm2, %xmm2 # 2 = io ++ ?vperm v5, v5, v6, $keyperm # align round key ++ vxor v3, v3, v1 # vpxor %xmm0, %xmm3, %xmm3 # 3 = jo ++ bdnz Lenc_loop ++ ++ # middle of last round ++ addi r10, r11, 0x80 ++ # vmovdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo ++ # vmovdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 ++ vperm v4, $sbou, v7, v2 # vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou ++ lvx v1, r12, r10 # vmovdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] ++ vperm v0, $sbot, v7, v3 # vpshufb %xmm3, %xmm0, %xmm0 # 0 = sb1t ++ vxor v4, v4, v5 # vpxor %xmm5, %xmm4, %xmm4 # 4 = sb1u + k ++ vxor v0, v0, v4 # vpxor %xmm4, %xmm0, %xmm0 # 0 = A ++ vperm v0, v0, v7, v1 # vpshufb %xmm1, %xmm0, %xmm0 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++.globl .vpaes_encrypt ++.align 5 ++.vpaes_encrypt: ++ $STU $sp,-$FRAME($sp) ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mflr r6 ++ mfspr r7, 256 # save vrsave ++ stvx v20,r10,$sp ++ addi r10,r10,32 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$sp ++ stw r7,`$FRAME-4`($sp) # save vrsave ++ li r0, -1 ++ $PUSH r6,`$FRAME+$LRSAVE`($sp) ++ mtspr 256, r0 # preserve all AltiVec registers ++ ++ bl _vpaes_encrypt_preheat ++ ++ ?lvsl $inpperm, 0, $inp # prepare for unaligned access ++ lvx v0, 0, $inp ++ addi $inp, $inp, 15 # 15 is not a typo ++ ?lvsr $outperm, 0, $out ++ ?lvsl $keyperm, 0, $key # prepare for unaligned access ++ vnor $outmask, v7, v7 # 0xff..ff ++ lvx $inptail, 0, $inp # redundant in aligned case ++ ?vperm $outmask, v7, $outmask, $outperm ++ lvx $outhead, 0, $out ++ ?vperm v0, v0, $inptail, $inpperm ++ ++ bl _vpaes_encrypt_core ++ ++ vperm v0, v0, v0, $outperm # rotate right/left ++ vsel v1, $outhead, v0, $outmask ++ vmr $outhead, v0 ++ stvx v1, 0, $out ++ addi $out, $out, 15 # 15 is not a typo ++ ######## ++ ++ lvx v1, 0, $out # redundant in aligned case ++ vsel v1, $outhead, v1, $outmask ++ stvx v1, 0, $out ++ ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mtlr r6 ++ mtspr 256, r7 # restore vrsave ++ lvx v20,r10,$sp ++ 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 ++ addi $sp,$sp,$FRAME ++ blr ++ .long 0 ++ .byte 0,12,0x04,1,0x80,0,3,0 ++ .long 0 ++.size .vpaes_encrypt,.-.vpaes_encrypt ++ ++.align 4 ++_vpaes_decrypt_preheat: ++ mflr r8 ++ bl Lconsts ++ mtlr r8 ++ li r11, 0xc0 # Lk_inv ++ li r10, 0xd0 ++ li r9, 0x160 # Ldipt ++ li r8, 0x170 ++ vxor v7, v7, v7 # 0x00..00 ++ vspltisb v8,4 # 0x04..04 ++ vspltisb v9,0x0f # 0x0f..0f ++ lvx $invlo, r12, r11 ++ li r11, 0x180 ++ lvx $invhi, r12, r10 ++ li r10, 0x190 ++ lvx $iptlo, r12, r9 ++ li r9, 0x1a0 ++ lvx $ipthi, r12, r8 ++ li r8, 0x1b0 ++ lvx $sbou, r12, r11 ++ li r11, 0x1c0 ++ lvx $sbot, r12, r10 ++ li r10, 0x1d0 ++ lvx $sb9u, r12, r9 ++ li r9, 0x1e0 ++ lvx $sb9t, r12, r8 ++ li r8, 0x1f0 ++ lvx $sbdu, r12, r11 ++ li r11, 0x200 ++ lvx $sbdt, r12, r10 ++ li r10, 0x210 ++ lvx $sbbu, r12, r9 ++ lvx $sbbt, r12, r8 ++ lvx $sbeu, r12, r11 ++ lvx $sbet, r12, r10 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++## ++## Decryption core ++## ++## Same API as encryption core. ++## ++.align 4 ++_vpaes_decrypt_core: ++ lwz r8, 240($key) # pull rounds ++ li r9, 16 ++ lvx v5, 0, $key # vmovdqu (%r9), %xmm4 # round0 key ++ li r11, 0x30 ++ lvx v6, r9, $key ++ addi r9, r9, 16 ++ ?vperm v5, v5, v6, $keyperm # align round key ++ vsrb v1, v0, v8 # vpsrlb \$4, %xmm0, %xmm0 ++ vperm v0, $iptlo, $iptlo, v0 # vpshufb %xmm1, %xmm2, %xmm2 ++ vperm v1, $ipthi, $ipthi, v1 # vpshufb %xmm0, %xmm1, %xmm0 ++ vxor v0, v0, v5 # vpxor %xmm4, %xmm2, %xmm2 ++ vxor v0, v0, v1 # vpxor %xmm2, %xmm0, %xmm0 ++ mtctr r8 ++ b Ldec_entry ++ ++.align 4 ++Ldec_loop: ++# ++# Inverse mix columns ++# ++ lvx v0, r12, r11 # v5 and v0 are flipped ++ # vmovdqa -0x20(%r10),%xmm4 # 4 : sb9u ++ # vmovdqa -0x10(%r10),%xmm1 # 0 : sb9t ++ vperm v4, $sb9u, v7, v2 # vpshufb %xmm2, %xmm4, %xmm4 # 4 = sb9u ++ subi r11, r11, 16 ++ vperm v1, $sb9t, v7, v3 # vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb9t ++ andi. r11, r11, 0x30 ++ vxor v5, v5, v4 # vpxor %xmm4, %xmm0, %xmm0 ++ # vmovdqa 0x00(%r10),%xmm4 # 4 : sbdu ++ vxor v5, v5, v1 # vpxor %xmm1, %xmm0, %xmm0 # 0 = ch ++ # vmovdqa 0x10(%r10),%xmm1 # 0 : sbdt ++ ++ vperm v4, $sbdu, v7, v2 # vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbdu ++ vperm v5, v5, v7, v0 # vpshufb %xmm5, %xmm0, %xmm0 # MC ch ++ vperm v1, $sbdt, v7, v3 # vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbdt ++ vxor v5, v5, v4 # vpxor %xmm4, %xmm0, %xmm0 # 4 = ch ++ # vmovdqa 0x20(%r10), %xmm4 # 4 : sbbu ++ vxor v5, v5, v1 # vpxor %xmm1, %xmm0, %xmm0 # 0 = ch ++ # vmovdqa 0x30(%r10), %xmm1 # 0 : sbbt ++ ++ vperm v4, $sbbu, v7, v2 # vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbbu ++ vperm v5, v5, v7, v0 # vpshufb %xmm5, %xmm0, %xmm0 # MC ch ++ vperm v1, $sbbt, v7, v3 # vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbbt ++ vxor v5, v5, v4 # vpxor %xmm4, %xmm0, %xmm0 # 4 = ch ++ # vmovdqa 0x40(%r10), %xmm4 # 4 : sbeu ++ vxor v5, v5, v1 # vpxor %xmm1, %xmm0, %xmm0 # 0 = ch ++ # vmovdqa 0x50(%r10), %xmm1 # 0 : sbet ++ ++ vperm v4, $sbeu, v7, v2 # vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbeu ++ vperm v5, v5, v7, v0 # vpshufb %xmm5, %xmm0, %xmm0 # MC ch ++ vperm v1, $sbet, v7, v3 # vpshufb %xmm3, %xmm1, %xmm1 # 0 = sbet ++ vxor v0, v5, v4 # vpxor %xmm4, %xmm0, %xmm0 # 4 = ch ++ vxor v0, v0, v1 # vpxor %xmm1, %xmm0, %xmm0 # 0 = ch ++ ++Ldec_entry: ++ # top of round ++ vsrb v1, v0, v8 # vpsrlb \$4, %xmm0, %xmm0 # 1 = i ++ vperm v2, $invhi, $invhi, v0 # vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k ++ vxor v0, v0, v1 # vpxor %xmm0, %xmm1, %xmm1 # 0 = j ++ vperm v3, $invlo, $invlo, v1 # vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i ++ vperm v4, $invlo, $invlo, v0 # vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j ++ vand v0, v0, v9 ++ vxor v3, v3, v2 # vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k ++ vxor v4, v4, v2 # vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k ++ vperm v2, $invlo, v7, v3 # vpshufb %xmm3, %xmm10, %xmm2 # 2 = 1/iak ++ vmr v5, v6 ++ lvx v6, r9, $key # vmovdqu (%r9), %xmm0 ++ vperm v3, $invlo, v7, v4 # vpshufb %xmm4, %xmm10, %xmm3 # 3 = 1/jak ++ addi r9, r9, 16 ++ vxor v2, v2, v0 # vpxor %xmm1, %xmm2, %xmm2 # 2 = io ++ ?vperm v5, v5, v6, $keyperm # align round key ++ vxor v3, v3, v1 # vpxor %xmm0, %xmm3, %xmm3 # 3 = jo ++ bdnz Ldec_loop ++ ++ # middle of last round ++ addi r10, r11, 0x80 ++ # vmovdqa 0x60(%r10), %xmm4 # 3 : sbou ++ vperm v4, $sbou, v7, v2 # vpshufb %xmm2, %xmm4, %xmm4 # 4 = sbou ++ # vmovdqa 0x70(%r10), %xmm1 # 0 : sbot ++ lvx v2, r12, r10 # vmovdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 ++ vperm v1, $sbot, v7, v3 # vpshufb %xmm3, %xmm1, %xmm1 # 0 = sb1t ++ vxor v4, v4, v5 # vpxor %xmm0, %xmm4, %xmm4 # 4 = sb1u + k ++ vxor v0, v1, v4 # vpxor %xmm4, %xmm1, %xmm0 # 0 = A ++ vperm v0, v0, v7, v2 # vpshufb %xmm2, %xmm0, %xmm0 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++.globl .vpaes_decrypt ++.align 5 ++.vpaes_decrypt: ++ $STU $sp,-$FRAME($sp) ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mflr r6 ++ mfspr r7, 256 # save vrsave ++ stvx v20,r10,$sp ++ addi r10,r10,32 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$sp ++ stw r7,`$FRAME-4`($sp) # save vrsave ++ li r0, -1 ++ $PUSH r6,`$FRAME+$LRSAVE`($sp) ++ mtspr 256, r0 # preserve all AltiVec registers ++ ++ bl _vpaes_decrypt_preheat ++ ++ ?lvsl $inpperm, 0, $inp # prepare for unaligned access ++ lvx v0, 0, $inp ++ addi $inp, $inp, 15 # 15 is not a typo ++ ?lvsr $outperm, 0, $out ++ ?lvsl $keyperm, 0, $key ++ vnor $outmask, v7, v7 # 0xff..ff ++ lvx $inptail, 0, $inp # redundant in aligned case ++ ?vperm $outmask, v7, $outmask, $outperm ++ lvx $outhead, 0, $out ++ ?vperm v0, v0, $inptail, $inpperm ++ ++ bl _vpaes_decrypt_core ++ ++ vperm v0, v0, v0, $outperm # rotate right/left ++ vsel v1, $outhead, v0, $outmask ++ vmr $outhead, v0 ++ stvx v1, 0, $out ++ addi $out, $out, 15 # 15 is not a typo ++ ######## ++ ++ lvx v1, 0, $out # redundant in aligned case ++ vsel v1, $outhead, v1, $outmask ++ stvx v1, 0, $out ++ ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mtlr r6 ++ mtspr 256, r7 # restore vrsave ++ lvx v20,r10,$sp ++ 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 ++ addi $sp,$sp,$FRAME ++ blr ++ .long 0 ++ .byte 0,12,0x04,1,0x80,0,3,0 ++ .long 0 ++.size .vpaes_decrypt,.-.vpaes_decrypt ++ ++.globl .vpaes_cbc_encrypt ++.align 5 ++.vpaes_cbc_encrypt: ++ ${UCMP}i r5,16 ++ bltlr- ++ ++ $STU $sp,-`($FRAME+2*$SIZE_T)`($sp) ++ mflr r0 ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mfspr r12, 256 ++ stvx v20,r10,$sp ++ addi r10,r10,32 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$sp ++ stw r12,`$FRAME-4`($sp) # save vrsave ++ $PUSH r30,`$FRAME+$SIZE_T*0`($sp) ++ $PUSH r31,`$FRAME+$SIZE_T*1`($sp) ++ li r9, -16 ++ $PUSH r0, `$FRAME+$SIZE_T*2+$LRSAVE`($sp) ++ ++ and r30, r5, r9 # copy length&-16 ++ mr r5, r6 # copy pointer to key ++ mr r31, r7 # copy pointer to iv ++ blt Lcbc_abort ++ cmpwi r8, 0 # test direction ++ li r6, -1 ++ mr r7, r12 # copy vrsave ++ mtspr 256, r6 # preserve all AltiVec registers ++ ++ lvx v24, 0, r31 # load [potentially unaligned] iv ++ li r9, 15 ++ ?lvsl $inpperm, 0, r31 ++ lvx v25, r9, r31 ++ ?vperm v24, v24, v25, $inpperm ++ ++ neg r8, $inp # prepare for unaligned access ++ vxor v7, v7, v7 ++ ?lvsl $keyperm, 0, $key ++ ?lvsr $outperm, 0, $out ++ ?lvsr $inpperm, 0, r8 # -$inp ++ vnor $outmask, v7, v7 # 0xff..ff ++ lvx $inptail, 0, $inp ++ ?vperm $outmask, v7, $outmask, $outperm ++ addi $inp, $inp, 15 # 15 is not a typo ++ lvx $outhead, 0, $out ++ ++ beq Lcbc_decrypt ++ ++ bl _vpaes_encrypt_preheat ++ li r0, 16 ++ ++Lcbc_enc_loop: ++ vmr v0, $inptail ++ lvx $inptail, 0, $inp ++ addi $inp, $inp, 16 ++ ?vperm v0, v0, $inptail, $inpperm ++ vxor v0, v0, v24 # ^= iv ++ ++ bl _vpaes_encrypt_core ++ ++ vmr v24, v0 # put aside iv ++ sub. r30, r30, r0 # len -= 16 ++ vperm v0, v0, v0, $outperm # rotate right/left ++ vsel v1, $outhead, v0, $outmask ++ vmr $outhead, v0 ++ stvx v1, 0, $out ++ addi $out, $out, 16 ++ bne Lcbc_enc_loop ++ ++ b Lcbc_done ++ ++.align 5 ++Lcbc_decrypt: ++ bl _vpaes_decrypt_preheat ++ li r0, 16 ++ ++Lcbc_dec_loop: ++ vmr v0, $inptail ++ lvx $inptail, 0, $inp ++ addi $inp, $inp, 16 ++ ?vperm v0, v0, $inptail, $inpperm ++ vmr v25, v0 # put aside input ++ ++ bl _vpaes_decrypt_core ++ ++ vxor v0, v0, v24 # ^= iv ++ vmr v24, v25 ++ sub. r30, r30, r0 # len -= 16 ++ vperm v0, v0, v0, $outperm # rotate right/left ++ vsel v1, $outhead, v0, $outmask ++ vmr $outhead, v0 ++ stvx v1, 0, $out ++ addi $out, $out, 16 ++ bne Lcbc_dec_loop ++ ++Lcbc_done: ++ addi $out, $out, -1 ++ lvx v1, 0, $out # redundant in aligned case ++ vsel v1, $outhead, v1, $outmask ++ stvx v1, 0, $out ++ ++ neg r8, r31 # write [potentially unaligned] iv ++ ?lvsl $outperm, 0, r8 ++ li r6, 15 ++ vnor $outmask, v7, v7 # 0xff..ff ++ ?vperm $outmask, v7, $outmask, $outperm ++ lvx $outhead, 0, r31 ++ vperm v24, v24, v24, $outperm # rotate right/left ++ vsel v0, $outhead, v24, $outmask ++ lvx v1, r6, r31 ++ stvx v0, 0, r31 ++ vsel v1, v24, v1, $outmask ++ stvx v1, r6, r31 ++ ++ mtspr 256, r7 # restore vrsave ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ lvx v20,r10,$sp ++ 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 ++Lcbc_abort: ++ $POP r0, `$FRAME+$SIZE_T*2+$LRSAVE`($sp) ++ $POP r30,`$FRAME+$SIZE_T*0`($sp) ++ $POP r31,`$FRAME+$SIZE_T*1`($sp) ++ mtlr r0 ++ addi $sp,$sp,`$FRAME+$SIZE_T*2` ++ blr ++ .long 0 ++ .byte 0,12,0x04,1,0x80,2,6,0 ++ .long 0 ++.size .vpaes_cbc_encrypt,.-.vpaes_cbc_encrypt ++___ ++} ++{ ++my ($inp,$bits,$out)=map("r$_",(3..5)); ++my $dir="cr1"; ++my ($invlo,$invhi,$iptlo,$ipthi,$rcon) = map("v$_",(10..13,24)); ++ ++$code.=<<___; ++######################################################## ++## ## ++## AES key schedule ## ++## ## ++######################################################## ++.align 4 ++_vpaes_key_preheat: ++ mflr r8 ++ bl Lconsts ++ mtlr r8 ++ li r11, 0xc0 # Lk_inv ++ li r10, 0xd0 ++ li r9, 0xe0 # L_ipt ++ li r8, 0xf0 ++ ++ vspltisb v8,4 # 0x04..04 ++ vxor v9,v9,v9 # 0x00..00 ++ lvx $invlo, r12, r11 # Lk_inv ++ li r11, 0x120 ++ lvx $invhi, r12, r10 ++ li r10, 0x130 ++ lvx $iptlo, r12, r9 # Lk_ipt ++ li r9, 0x220 ++ lvx $ipthi, r12, r8 ++ li r8, 0x230 ++ ++ lvx v14, r12, r11 # Lk_sb1 ++ li r11, 0x240 ++ lvx v15, r12, r10 ++ li r10, 0x250 ++ ++ lvx v16, r12, r9 # Lk_dksd ++ li r9, 0x260 ++ lvx v17, r12, r8 ++ li r8, 0x270 ++ lvx v18, r12, r11 # Lk_dksb ++ li r11, 0x280 ++ lvx v19, r12, r10 ++ li r10, 0x290 ++ lvx v20, r12, r9 # Lk_dkse ++ li r9, 0x2a0 ++ lvx v21, r12, r8 ++ li r8, 0x2b0 ++ lvx v22, r12, r11 # Lk_dks9 ++ lvx v23, r12, r10 ++ ++ lvx v24, r12, r9 # Lk_rcon ++ lvx v25, 0, r12 # Lk_mc_forward[0] ++ lvx v26, r12, r8 # Lks63 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++.align 4 ++_vpaes_schedule_core: ++ mflr r7 ++ ++ bl _vpaes_key_preheat # load the tables ++ ++ #lvx v0, 0, $inp # vmovdqu (%rdi), %xmm0 # load key (unaligned) ++ neg r8, $inp # prepare for unaligned access ++ lvx v0, 0, $inp ++ addi $inp, $inp, 15 # 15 is not typo ++ ?lvsr $inpperm, 0, r8 # -$inp ++ lvx v6, 0, $inp # v6 serves as inptail ++ addi $inp, $inp, 8 ++ ?vperm v0, v0, v6, $inpperm ++ ++ # input transform ++ vmr v3, v0 # vmovdqa %xmm0, %xmm3 ++ bl _vpaes_schedule_transform ++ vmr v7, v0 # vmovdqa %xmm0, %xmm7 ++ ++ bne $dir, Lschedule_am_decrypting ++ ++ # encrypting, output zeroth round key after transform ++ li r8, 0x30 # mov \$0x30,%r8d ++ addi r10, r12, 0x80 # lea .Lk_sr(%rip),%r10 ++ ++ ?lvsr $outperm, 0, $out # prepare for unaligned access ++ vnor $outmask, v9, v9 # 0xff..ff ++ lvx $outhead, 0, $out ++ ?vperm $outmask, v9, $outmask, $outperm ++ ++ #stvx v0, 0, $out # vmovdqu %xmm0, (%rdx) ++ vperm v1, v0, v0, $outperm # rotate right/left ++ vsel v2, $outhead, v1, $outmask ++ vmr $outhead, v1 ++ stvx v2, 0, $out ++ b Lschedule_go ++ ++Lschedule_am_decrypting: ++ srwi r8, $bits, 1 # shr \$1,%r8d ++ andi. r8, r8, 32 # and \$32,%r8d ++ xori r8, r8, 32 # xor \$32,%r8d # nbits==192?0:32 ++ addi r10, r12, 0x80 # lea .Lk_sr(%rip),%r10 ++ # decrypting, output zeroth round key after shiftrows ++ lvx v1, r8, r10 # vmovdqa (%r8,%r10), %xmm1 ++ vperm v4, v3, v3, v1 # vpshufb %xmm1, %xmm3, %xmm3 ++ ++ neg r0, $out # prepare for unaligned access ++ ?lvsl $outperm, 0, r0 ++ addi $out, $out, 15 # 15 is not typo ++ vnor $outmask, v9, v9 # 0xff..ff ++ lvx $outhead, 0, $out ++ ?vperm $outmask, $outmask, v9, $outperm ++ ++ #stvx v4, 0, $out # vmovdqu %xmm3, (%rdx) ++ vperm v4, v4, v4, $outperm # rotate right/left ++ vsel v2, $outhead, v4, $outmask ++ vmr $outhead, v4 ++ stvx v2, 0, $out ++ xori r8, r8, 0x30 # xor \$0x30, %r8 ++ ++Lschedule_go: ++ cmplwi $bits, 192 # cmp \$192, %esi ++ bgt Lschedule_256 ++ beq Lschedule_192 ++ # 128: fall though ++ ++## ++## .schedule_128 ++## ++## 128-bit specific part of key schedule. ++## ++## This schedule is really simple, because all its parts ++## are accomplished by the subroutines. ++## ++Lschedule_128: ++ li r0, 10 # mov \$10, %esi ++ mtctr r0 ++ ++Loop_schedule_128: ++ bl _vpaes_schedule_round ++ bdz Lschedule_mangle_last # dec %esi ++ bl _vpaes_schedule_mangle # write output ++ b Loop_schedule_128 ++ ++## ++## .aes_schedule_192 ++## ++## 192-bit specific part of key schedule. ++## ++## The main body of this schedule is the same as the 128-bit ++## schedule, but with more smearing. The long, high side is ++## stored in %xmm7 as before, and the short, low side is in ++## the high bits of %xmm6. ++## ++## This schedule is somewhat nastier, however, because each ++## round produces 192 bits of key material, or 1.5 round keys. ++## Therefore, on each cycle we do 2 rounds and produce 3 round ++## keys. ++## ++.align 4 ++Lschedule_192: ++ li r0, 4 # mov \$4, %esi ++ lvx v0, 0, $inp ++ ?vperm v0, v6, v0, $inpperm ++ ?vsldoi v0, v3, v0, 8 # vmovdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) ++ bl _vpaes_schedule_transform # input transform ++ ?vsldoi v6, v0, v9, 8 ++ ?vsldoi v6, v9, v6, 8 # clobber "low" side with zeros ++ mtctr r0 ++ ++Loop_schedule_192: ++ bl _vpaes_schedule_round ++ ?vsldoi v0, v6, v0, 8 # vpalignr \$8,%xmm6,%xmm0,%xmm0 ++ bl _vpaes_schedule_mangle # save key n ++ bl _vpaes_schedule_192_smear ++ bl _vpaes_schedule_mangle # save key n+1 ++ bl _vpaes_schedule_round ++ bdz Lschedule_mangle_last # dec %esi ++ bl _vpaes_schedule_mangle # save key n+2 ++ bl _vpaes_schedule_192_smear ++ b Loop_schedule_192 ++ ++## ++## .aes_schedule_256 ++## ++## 256-bit specific part of key schedule. ++## ++## The structure here is very similar to the 128-bit ++## schedule, but with an additional "low side" in ++## %xmm6. The low side's rounds are the same as the ++## high side's, except no rcon and no rotation. ++## ++.align 4 ++Lschedule_256: ++ li r0, 7 # mov \$7, %esi ++ addi $inp, $inp, 8 ++ lvx v0, 0, $inp # vmovdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) ++ ?vperm v0, v6, v0, $inpperm ++ bl _vpaes_schedule_transform # input transform ++ mtctr r0 ++ ++Loop_schedule_256: ++ bl _vpaes_schedule_mangle # output low result ++ vmr v6, v0 # vmovdqa %xmm0, %xmm6 # save cur_lo in xmm6 ++ ++ # high round ++ bl _vpaes_schedule_round ++ bdz Lschedule_mangle_last # dec %esi ++ bl _vpaes_schedule_mangle ++ ++ # low round. swap xmm7 and xmm6 ++ ?vspltw v0, v0, 3 # vpshufd \$0xFF, %xmm0, %xmm0 ++ vmr v5, v7 # vmovdqa %xmm7, %xmm5 ++ vmr v7, v6 # vmovdqa %xmm6, %xmm7 ++ bl _vpaes_schedule_low_round ++ vmr v7, v5 # vmovdqa %xmm5, %xmm7 ++ ++ b Loop_schedule_256 ++## ++## .aes_schedule_mangle_last ++## ++## Mangler for last round of key schedule ++## Mangles %xmm0 ++## when encrypting, outputs out(%xmm0) ^ 63 ++## when decrypting, outputs unskew(%xmm0) ++## ++## Always called right before return... jumps to cleanup and exits ++## ++.align 4 ++Lschedule_mangle_last: ++ # schedule last round key from xmm0 ++ li r11, 0x2e0 # lea .Lk_deskew(%rip),%r11 ++ li r9, 0x2f0 ++ bne $dir, Lschedule_mangle_last_dec ++ ++ # encrypting ++ lvx v1, r8, r10 # vmovdqa (%r8,%r10),%xmm1 ++ li r11, 0x2c0 # lea .Lk_opt(%rip), %r11 # prepare to output transform ++ li r9, 0x2d0 # prepare to output transform ++ vperm v0, v0, v0, v1 # vpshufb %xmm1, %xmm0, %xmm0 # output permute ++ ++ lvx $iptlo, r11, r12 # reload $ipt ++ lvx $ipthi, r9, r12 ++ addi $out, $out, 16 # add \$16, %rdx ++ vxor v0, v0, v26 # vpxor .Lk_s63(%rip), %xmm0, %xmm0 ++ bl _vpaes_schedule_transform # output transform ++ ++ #stvx v0, r0, $out # vmovdqu %xmm0, (%rdx) # save last key ++ vperm v0, v0, v0, $outperm # rotate right/left ++ vsel v2, $outhead, v0, $outmask ++ vmr $outhead, v0 ++ stvx v2, 0, $out ++ ++ addi $out, $out, 15 # 15 is not typo ++ lvx v1, 0, $out # redundant in aligned case ++ vsel v1, $outhead, v1, $outmask ++ stvx v1, 0, $out ++ b Lschedule_mangle_done ++ ++.align 4 ++Lschedule_mangle_last_dec: ++ lvx $iptlo, r11, r12 # reload $ipt ++ lvx $ipthi, r9, r12 ++ addi $out, $out, -16 # add \$-16, %rdx ++ vxor v0, v0, v26 # vpxor .Lk_s63(%rip), %xmm0, %xmm0 ++ bl _vpaes_schedule_transform # output transform ++ ++ #stvx v0, r0, $out # vmovdqu %xmm0, (%rdx) # save last key ++ vperm v0, v0, v0, $outperm # rotate right/left ++ vsel v2, $outhead, v0, $outmask ++ vmr $outhead, v0 ++ stvx v2, 0, $out ++ ++ addi $out, $out, -15 # -15 is not typo ++ lvx v1, 0, $out # redundant in aligned case ++ vsel v1, $outhead, v1, $outmask ++ stvx v1, 0, $out ++ ++Lschedule_mangle_done: ++ mtlr r7 ++ # cleanup ++ vxor v0, v0, v0 # vpxor %xmm0, %xmm0, %xmm0 ++ vxor v1, v1, v1 # vpxor %xmm1, %xmm1, %xmm1 ++ vxor v2, v2, v2 # vpxor %xmm2, %xmm2, %xmm2 ++ vxor v3, v3, v3 # vpxor %xmm3, %xmm3, %xmm3 ++ vxor v4, v4, v4 # vpxor %xmm4, %xmm4, %xmm4 ++ vxor v5, v5, v5 # vpxor %xmm5, %xmm5, %xmm5 ++ vxor v6, v6, v6 # vpxor %xmm6, %xmm6, %xmm6 ++ vxor v7, v7, v7 # vpxor %xmm7, %xmm7, %xmm7 ++ ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++## ++## .aes_schedule_192_smear ++## ++## Smear the short, low side in the 192-bit key schedule. ++## ++## Inputs: ++## %xmm7: high side, b a x y ++## %xmm6: low side, d c 0 0 ++## %xmm13: 0 ++## ++## Outputs: ++## %xmm6: b+c+d b+c 0 0 ++## %xmm0: b+c+d b+c b a ++## ++.align 4 ++_vpaes_schedule_192_smear: ++ ?vspltw v0, v7, 3 ++ ?vsldoi v1, v9, v6, 12 # vpshufd \$0x80, %xmm6, %xmm1 # d c 0 0 -> c 0 0 0 ++ ?vsldoi v0, v7, v0, 8 # vpshufd \$0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a ++ vxor v6, v6, v1 # vpxor %xmm1, %xmm6, %xmm6 # -> c+d c 0 0 ++ vxor v6, v6, v0 # vpxor %xmm0, %xmm6, %xmm6 # -> b+c+d b+c b a ++ vmr v0, v6 ++ ?vsldoi v6, v6, v9, 8 ++ ?vsldoi v6, v9, v6, 8 # clobber low side with zeros ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++## ++## .aes_schedule_round ++## ++## Runs one main round of the key schedule on %xmm0, %xmm7 ++## ++## Specifically, runs subbytes on the high dword of %xmm0 ++## then rotates it by one byte and xors into the low dword of ++## %xmm7. ++## ++## Adds rcon from low byte of %xmm8, then rotates %xmm8 for ++## next rcon. ++## ++## Smears the dwords of %xmm7 by xoring the low into the ++## second low, result into third, result into highest. ++## ++## Returns results in %xmm7 = %xmm0. ++## Clobbers %xmm1-%xmm4, %r11. ++## ++.align 4 ++_vpaes_schedule_round: ++ # extract rcon from xmm8 ++ #vxor v4, v4, v4 # vpxor %xmm4, %xmm4, %xmm4 ++ ?vsldoi v1, $rcon, v9, 15 # vpalignr \$15, %xmm8, %xmm4, %xmm1 ++ ?vsldoi $rcon, $rcon, $rcon, 15 # vpalignr \$15, %xmm8, %xmm8, %xmm8 ++ vxor v7, v7, v1 # vpxor %xmm1, %xmm7, %xmm7 ++ ++ # rotate ++ ?vspltw v0, v0, 3 # vpshufd \$0xFF, %xmm0, %xmm0 ++ ?vsldoi v0, v0, v0, 1 # vpalignr \$1, %xmm0, %xmm0, %xmm0 ++ ++ # fall through... ++ ++ # low round: same as high round, but no rotation and no rcon. ++_vpaes_schedule_low_round: ++ # smear xmm7 ++ ?vsldoi v1, v9, v7, 12 # vpslldq \$4, %xmm7, %xmm1 ++ vxor v7, v7, v1 # vpxor %xmm1, %xmm7, %xmm7 ++ vspltisb v1, 0x0f # 0x0f..0f ++ ?vsldoi v4, v9, v7, 8 # vpslldq \$8, %xmm7, %xmm4 ++ ++ # subbytes ++ vand v1, v1, v0 # vpand %xmm9, %xmm0, %xmm1 # 0 = k ++ vsrb v0, v0, v8 # vpsrlb \$4, %xmm0, %xmm0 # 1 = i ++ vxor v7, v7, v4 # vpxor %xmm4, %xmm7, %xmm7 ++ vperm v2, $invhi, v9, v1 # vpshufb %xmm1, %xmm11, %xmm2 # 2 = a/k ++ vxor v1, v1, v0 # vpxor %xmm0, %xmm1, %xmm1 # 0 = j ++ vperm v3, $invlo, v9, v0 # vpshufb %xmm0, %xmm10, %xmm3 # 3 = 1/i ++ vxor v3, v3, v2 # vpxor %xmm2, %xmm3, %xmm3 # 3 = iak = 1/i + a/k ++ vperm v4, $invlo, v9, v1 # vpshufb %xmm1, %xmm10, %xmm4 # 4 = 1/j ++ vxor v7, v7, v26 # vpxor .Lk_s63(%rip), %xmm7, %xmm7 ++ vperm v3, $invlo, v9, v3 # vpshufb %xmm3, %xmm10, %xmm3 # 2 = 1/iak ++ vxor v4, v4, v2 # vpxor %xmm2, %xmm4, %xmm4 # 4 = jak = 1/j + a/k ++ vperm v2, $invlo, v9, v4 # vpshufb %xmm4, %xmm10, %xmm2 # 3 = 1/jak ++ vxor v3, v3, v1 # vpxor %xmm1, %xmm3, %xmm3 # 2 = io ++ vxor v2, v2, v0 # vpxor %xmm0, %xmm2, %xmm2 # 3 = jo ++ vperm v4, v15, v9, v3 # vpshufb %xmm3, %xmm13, %xmm4 # 4 = sbou ++ vperm v1, v14, v9, v2 # vpshufb %xmm2, %xmm12, %xmm1 # 0 = sb1t ++ vxor v1, v1, v4 # vpxor %xmm4, %xmm1, %xmm1 # 0 = sbox output ++ ++ # add in smeared stuff ++ vxor v0, v1, v7 # vpxor %xmm7, %xmm1, %xmm0 ++ vxor v7, v1, v7 # vmovdqa %xmm0, %xmm7 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++## ++## .aes_schedule_transform ++## ++## Linear-transform %xmm0 according to tables at (%r11) ++## ++## Requires that %xmm9 = 0x0F0F... as in preheat ++## Output in %xmm0 ++## Clobbers %xmm2 ++## ++.align 4 ++_vpaes_schedule_transform: ++ #vand v1, v0, v9 # vpand %xmm9, %xmm0, %xmm1 ++ vsrb v2, v0, v8 # vpsrlb \$4, %xmm0, %xmm0 ++ # vmovdqa (%r11), %xmm2 # lo ++ vperm v0, $iptlo, $iptlo, v0 # vpshufb %xmm1, %xmm2, %xmm2 ++ # vmovdqa 16(%r11), %xmm1 # hi ++ vperm v2, $ipthi, $ipthi, v2 # vpshufb %xmm0, %xmm1, %xmm0 ++ vxor v0, v0, v2 # vpxor %xmm2, %xmm0, %xmm0 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++## ++## .aes_schedule_mangle ++## ++## Mangle xmm0 from (basis-transformed) standard version ++## to our version. ++## ++## On encrypt, ++## xor with 0x63 ++## multiply by circulant 0,1,1,1 ++## apply shiftrows transform ++## ++## On decrypt, ++## xor with 0x63 ++## multiply by "inverse mixcolumns" circulant E,B,D,9 ++## deskew ++## apply shiftrows transform ++## ++## ++## Writes out to (%rdx), and increments or decrements it ++## Keeps track of round number mod 4 in %r8 ++## Preserves xmm0 ++## Clobbers xmm1-xmm5 ++## ++.align 4 ++_vpaes_schedule_mangle: ++ #vmr v4, v0 # vmovdqa %xmm0, %xmm4 # save xmm0 for later ++ # vmovdqa .Lk_mc_forward(%rip),%xmm5 ++ bne $dir, Lschedule_mangle_dec ++ ++ # encrypting ++ vxor v4, v0, v26 # vpxor .Lk_s63(%rip), %xmm0, %xmm4 ++ addi $out, $out, 16 # add \$16, %rdx ++ vperm v4, v4, v4, v25 # vpshufb %xmm5, %xmm4, %xmm4 ++ vperm v1, v4, v4, v25 # vpshufb %xmm5, %xmm4, %xmm1 ++ vperm v3, v1, v1, v25 # vpshufb %xmm5, %xmm1, %xmm3 ++ vxor v4, v4, v1 # vpxor %xmm1, %xmm4, %xmm4 ++ lvx v1, r8, r10 # vmovdqa (%r8,%r10), %xmm1 ++ vxor v3, v3, v4 # vpxor %xmm4, %xmm3, %xmm3 ++ ++ vperm v3, v3, v3, v1 # vpshufb %xmm1, %xmm3, %xmm3 ++ addi r8, r8, -16 # add \$-16, %r8 ++ andi. r8, r8, 0x30 # and \$0x30, %r8 ++ ++ #stvx v3, 0, $out # vmovdqu %xmm3, (%rdx) ++ vperm v1, v3, v3, $outperm # rotate right/left ++ vsel v2, $outhead, v1, $outmask ++ vmr $outhead, v1 ++ stvx v2, 0, $out ++ blr ++ ++.align 4 ++Lschedule_mangle_dec: ++ # inverse mix columns ++ # lea .Lk_dksd(%rip),%r11 ++ vsrb v1, v0, v8 # vpsrlb \$4, %xmm4, %xmm1 # 1 = hi ++ #and v4, v0, v9 # vpand %xmm9, %xmm4, %xmm4 # 4 = lo ++ ++ # vmovdqa 0x00(%r11), %xmm2 ++ vperm v2, v16, v16, v0 # vpshufb %xmm4, %xmm2, %xmm2 ++ # vmovdqa 0x10(%r11), %xmm3 ++ vperm v3, v17, v17, v1 # vpshufb %xmm1, %xmm3, %xmm3 ++ vxor v3, v3, v2 # vpxor %xmm2, %xmm3, %xmm3 ++ vperm v3, v3, v9, v25 # vpshufb %xmm5, %xmm3, %xmm3 ++ ++ # vmovdqa 0x20(%r11), %xmm2 ++ vperm v2, v18, v18, v0 # vpshufb %xmm4, %xmm2, %xmm2 ++ vxor v2, v2, v3 # vpxor %xmm3, %xmm2, %xmm2 ++ # vmovdqa 0x30(%r11), %xmm3 ++ vperm v3, v19, v19, v1 # vpshufb %xmm1, %xmm3, %xmm3 ++ vxor v3, v3, v2 # vpxor %xmm2, %xmm3, %xmm3 ++ vperm v3, v3, v9, v25 # vpshufb %xmm5, %xmm3, %xmm3 ++ ++ # vmovdqa 0x40(%r11), %xmm2 ++ vperm v2, v20, v20, v0 # vpshufb %xmm4, %xmm2, %xmm2 ++ vxor v2, v2, v3 # vpxor %xmm3, %xmm2, %xmm2 ++ # vmovdqa 0x50(%r11), %xmm3 ++ vperm v3, v21, v21, v1 # vpshufb %xmm1, %xmm3, %xmm3 ++ vxor v3, v3, v2 # vpxor %xmm2, %xmm3, %xmm3 ++ ++ # vmovdqa 0x60(%r11), %xmm2 ++ vperm v2, v22, v22, v0 # vpshufb %xmm4, %xmm2, %xmm2 ++ vperm v3, v3, v9, v25 # vpshufb %xmm5, %xmm3, %xmm3 ++ # vmovdqa 0x70(%r11), %xmm4 ++ vperm v4, v23, v23, v1 # vpshufb %xmm1, %xmm4, %xmm4 ++ lvx v1, r8, r10 # vmovdqa (%r8,%r10), %xmm1 ++ vxor v2, v2, v3 # vpxor %xmm3, %xmm2, %xmm2 ++ vxor v3, v4, v2 # vpxor %xmm2, %xmm4, %xmm3 ++ ++ addi $out, $out, -16 # add \$-16, %rdx ++ ++ vperm v3, v3, v3, v1 # vpshufb %xmm1, %xmm3, %xmm3 ++ addi r8, r8, -16 # add \$-16, %r8 ++ andi. r8, r8, 0x30 # and \$0x30, %r8 ++ ++ #stvx v3, 0, $out # vmovdqu %xmm3, (%rdx) ++ vperm v1, v3, v3, $outperm # rotate right/left ++ vsel v2, $outhead, v1, $outmask ++ vmr $outhead, v1 ++ stvx v2, 0, $out ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ ++.globl .vpaes_set_encrypt_key ++.align 5 ++.vpaes_set_encrypt_key: ++ $STU $sp,-$FRAME($sp) ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mflr r0 ++ mfspr r6, 256 # save vrsave ++ stvx v20,r10,$sp ++ addi r10,r10,32 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$sp ++ stw r6,`$FRAME-4`($sp) # save vrsave ++ li r7, -1 ++ $PUSH r0, `$FRAME+$LRSAVE`($sp) ++ mtspr 256, r7 # preserve all AltiVec registers ++ ++ srwi r9, $bits, 5 # shr \$5,%eax ++ addi r9, r9, 6 # add \$5,%eax ++ stw r9, 240($out) # mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; ++ ++ cmplw $dir, $bits, $bits # set encrypt direction ++ li r8, 0x30 # mov \$0x30,%r8d ++ bl _vpaes_schedule_core ++ ++ $POP r0, `$FRAME+$LRSAVE`($sp) ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mtspr 256, r6 # restore vrsave ++ mtlr r0 ++ xor r3, r3, r3 ++ lvx v20,r10,$sp ++ 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 ++ addi $sp,$sp,$FRAME ++ blr ++ .long 0 ++ .byte 0,12,0x04,1,0x80,0,3,0 ++ .long 0 ++.size .vpaes_set_encrypt_key,.-.vpaes_set_encrypt_key ++ ++.globl .vpaes_set_decrypt_key ++.align 4 ++.vpaes_set_decrypt_key: ++ $STU $sp,-$FRAME($sp) ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mflr r0 ++ mfspr r6, 256 # save vrsave ++ stvx v20,r10,$sp ++ addi r10,r10,32 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$sp ++ stw r6,`$FRAME-4`($sp) # save vrsave ++ li r7, -1 ++ $PUSH r0, `$FRAME+$LRSAVE`($sp) ++ mtspr 256, r7 # preserve all AltiVec registers ++ ++ srwi r9, $bits, 5 # shr \$5,%eax ++ addi r9, r9, 6 # add \$5,%eax ++ stw r9, 240($out) # mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; ++ ++ slwi r9, r9, 4 # shl \$4,%eax ++ add $out, $out, r9 # lea (%rdx,%rax),%rdx ++ ++ cmplwi $dir, $bits, 0 # set decrypt direction ++ srwi r8, $bits, 1 # shr \$1,%r8d ++ andi. r8, r8, 32 # and \$32,%r8d ++ xori r8, r8, 32 # xor \$32,%r8d # nbits==192?0:32 ++ bl _vpaes_schedule_core ++ ++ $POP r0, `$FRAME+$LRSAVE`($sp) ++ li r10,`15+6*$SIZE_T` ++ li r11,`31+6*$SIZE_T` ++ mtspr 256, r6 # restore vrsave ++ mtlr r0 ++ xor r3, r3, r3 ++ lvx v20,r10,$sp ++ 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 ++ addi $sp,$sp,$FRAME ++ blr ++ .long 0 ++ .byte 0,12,0x04,1,0x80,0,3,0 ++ .long 0 ++.size .vpaes_set_decrypt_key,.-.vpaes_set_decrypt_key ++___ ++} ++ ++my $consts=1; ++foreach (split("\n",$code)) { ++ s/\`([^\`]*)\`/eval $1/geo; ++ ++ # constants table endian-specific conversion ++ if ($consts && m/\.long\s+(.+)\s+(\?[a-z]*)$/o) { ++ my $conv=$2; ++ my @bytes=(); ++ ++ # convert to endian-agnostic format ++ foreach (split(/,\s+/,$1)) { ++ my $l = /^0/?oct:int; ++ push @bytes,($l>>24)&0xff,($l>>16)&0xff,($l>>8)&0xff,$l&0xff; ++ } ++ ++ # little-endian conversion ++ if ($flavour =~ /le$/o) { ++ SWITCH: for($conv) { ++ /\?inv/ && do { @bytes=map($_^0xf,@bytes); last; }; ++ /\?rev/ && do { @bytes=reverse(@bytes); last; }; ++ } ++ } ++ ++ #emit ++ print ".byte\t",join(',',map (sprintf("0x%02x",$_),@bytes)),"\n"; ++ next; ++ } ++ $consts=0 if (m/Lconsts:/o); # end of table ++ ++ # instructions prefixed with '?' are endian-specific and need ++ # to be adjusted accordingly... ++ if ($flavour =~ /le$/o) { # little-endian ++ s/\?lvsr/lvsl/o or ++ s/\?lvsl/lvsr/o or ++ s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/o or ++ s/\?(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/o or ++ s/\?(vspltw\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9])/$1$2 3-$3/o; ++ } else { # big-endian ++ s/\?([a-z]+)/$1/o; ++ } ++ ++ print $_,"\n"; ++} ++ ++close STDOUT; +diff --git a/crypto/aes/asm/vpaes-x86_64.pl b/crypto/aes/asm/vpaes-x86_64.pl +index 41f2e46..bd7f45b 100644 +--- a/crypto/aes/asm/vpaes-x86_64.pl ++++ b/crypto/aes/asm/vpaes-x86_64.pl +@@ -1060,7 +1060,7 @@ _vpaes_consts: + .Lk_dsbo: # decryption sbox final output + .quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D + .quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +-.asciz "Vector Permutaion AES for x86_64/SSSE3, Mike Hamburg (Stanford University)" ++.asciz "Vector Permutation AES for x86_64/SSSE3, Mike Hamburg (Stanford University)" + .align 64 + .size _vpaes_consts,.-_vpaes_consts + ___ +diff --git a/crypto/bn/asm/ppc-mont.pl b/crypto/bn/asm/ppc-mont.pl +index f9b6992..da69c6a 100644 +--- a/crypto/bn/asm/ppc-mont.pl ++++ b/crypto/bn/asm/ppc-mont.pl +@@ -325,6 +325,7 @@ Lcopy: ; copy or in-place refresh + .long 0 + .byte 0,12,4,0,0x80,12,6,0 + .long 0 ++.size .bn_mul_mont_int,.-.bn_mul_mont_int + + .asciz "Montgomery Multiplication for PPC, CRYPTOGAMS by " + ___ +diff --git a/crypto/bn/asm/ppc.pl b/crypto/bn/asm/ppc.pl +index 1249ce2..04df1fe 100644 +--- a/crypto/bn/asm/ppc.pl ++++ b/crypto/bn/asm/ppc.pl +@@ -392,6 +392,7 @@ $data=< for the OpenSSL ++# Written by Andy Polyakov for the OpenSSL + # project. The module is, however, dual licensed under OpenSSL and + # CRYPTOGAMS licenses depending on where you obtain it. For further + # details see http://www.openssl.org/~appro/cryptogams/. +@@ -65,6 +65,14 @@ + # others alternative would be to break dependence on upper halves of + # GPRs by sticking to 32-bit integer operations... + ++# December 2012 ++ ++# Remove above mentioned dependence on GPRs' upper halves in 32-bit ++# build. No signal masking overhead, but integer instructions are ++# *more* numerous... It's still "universally" faster than 32-bit ++# ppc-mont.pl, but improvement coefficient is not as impressive ++# for longer keys... ++ + $flavour = shift; + + if ($flavour =~ /32/) { +@@ -110,6 +118,9 @@ $tp="r10"; + $j="r11"; + $i="r12"; + # non-volatile registers ++$c1="r19"; ++$n1="r20"; ++$a1="r21"; + $nap_d="r22"; # interleaved ap and np in double format + $a0="r23"; # ap[0] + $t0="r24"; # temporary registers +@@ -180,8 +191,8 @@ $T3a="f30"; $T3b="f31"; + # . . + # +-------------------------------+ + # . . +-# -12*size_t +-------------------------------+ +-# | 10 saved gpr, r22-r31 | ++# -13*size_t +-------------------------------+ ++# | 13 saved gpr, r19-r31 | + # . . + # . . + # -12*8 +-------------------------------+ +@@ -215,6 +226,9 @@ $code=<<___; + mr $i,$sp + $STUX $sp,$sp,$tp ; alloca + ++ $PUSH r19,`-12*8-13*$SIZE_T`($i) ++ $PUSH r20,`-12*8-12*$SIZE_T`($i) ++ $PUSH r21,`-12*8-11*$SIZE_T`($i) + $PUSH r22,`-12*8-10*$SIZE_T`($i) + $PUSH r23,`-12*8-9*$SIZE_T`($i) + $PUSH r24,`-12*8-8*$SIZE_T`($i) +@@ -237,40 +251,26 @@ $code=<<___; + stfd f29,`-3*8`($i) + stfd f30,`-2*8`($i) + stfd f31,`-1*8`($i) +-___ +-$code.=<<___ if ($SIZE_T==8); +- ld $a0,0($ap) ; pull ap[0] value +- ld $n0,0($n0) ; pull n0[0] value +- ld $t3,0($bp) ; bp[0] +-___ +-$code.=<<___ if ($SIZE_T==4); +- mr $t1,$n0 +- lwz $a0,0($ap) ; pull ap[0,1] value +- lwz $t0,4($ap) +- lwz $n0,0($t1) ; pull n0[0,1] value +- lwz $t1,4($t1) +- lwz $t3,0($bp) ; bp[0,1] +- lwz $t2,4($bp) +- insrdi $a0,$t0,32,0 +- insrdi $n0,$t1,32,0 +- insrdi $t3,$t2,32,0 +-___ +-$code.=<<___; ++ + addi $tp,$sp,`$FRAME+$TRANSFER+8+64` + li $i,-64 + add $nap_d,$tp,$num + and $nap_d,$nap_d,$i ; align to 64 bytes +- +- mulld $t7,$a0,$t3 ; ap[0]*bp[0] + ; nap_d is off by 1, because it's used with stfdu/lfdu + addi $nap_d,$nap_d,-8 + srwi $j,$num,`3+1` ; counter register, num/2 +- mulld $t7,$t7,$n0 ; tp[0]*n0 + addi $j,$j,-1 + addi $tp,$sp,`$FRAME+$TRANSFER-8` + li $carry,0 + mtctr $j ++___ ++ ++$code.=<<___ if ($SIZE_T==8); ++ ld $a0,0($ap) ; pull ap[0] value ++ ld $t3,0($bp) ; bp[0] ++ ld $n0,0($n0) ; pull n0[0] value + ++ mulld $t7,$a0,$t3 ; ap[0]*bp[0] + ; transfer bp[0] to FPU as 4x16-bit values + extrdi $t0,$t3,16,48 + extrdi $t1,$t3,16,32 +@@ -280,6 +280,8 @@ $code.=<<___; + std $t1,`$FRAME+8`($sp) + std $t2,`$FRAME+16`($sp) + std $t3,`$FRAME+24`($sp) ++ ++ mulld $t7,$t7,$n0 ; tp[0]*n0 + ; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values + extrdi $t4,$t7,16,48 + extrdi $t5,$t7,16,32 +@@ -289,21 +291,61 @@ $code.=<<___; + std $t5,`$FRAME+40`($sp) + std $t6,`$FRAME+48`($sp) + std $t7,`$FRAME+56`($sp) +-___ +-$code.=<<___ if ($SIZE_T==8); +- lwz $t0,4($ap) ; load a[j] as 32-bit word pair +- lwz $t1,0($ap) +- lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair ++ ++ extrdi $t0,$a0,32,32 ; lwz $t0,4($ap) ++ extrdi $t1,$a0,32,0 ; lwz $t1,0($ap) ++ lwz $t2,12($ap) ; load a[1] as 32-bit word pair + lwz $t3,8($ap) +- lwz $t4,4($np) ; load n[j] as 32-bit word pair ++ lwz $t4,4($np) ; load n[0] as 32-bit word pair + lwz $t5,0($np) +- lwz $t6,12($np) ; load n[j+1] as 32-bit word pair ++ lwz $t6,12($np) ; load n[1] as 32-bit word pair + lwz $t7,8($np) + ___ + $code.=<<___ if ($SIZE_T==4); +- lwz $t0,0($ap) ; load a[j..j+3] as 32-bit word pairs +- lwz $t1,4($ap) +- lwz $t2,8($ap) ++ lwz $a0,0($ap) ; pull ap[0,1] value ++ mr $n1,$n0 ++ lwz $a1,4($ap) ++ li $c1,0 ++ lwz $t1,0($bp) ; bp[0,1] ++ lwz $t3,4($bp) ++ lwz $n0,0($n1) ; pull n0[0,1] value ++ lwz $n1,4($n1) ++ ++ mullw $t4,$a0,$t1 ; mulld ap[0]*bp[0] ++ mulhwu $t5,$a0,$t1 ++ mullw $t6,$a1,$t1 ++ mullw $t7,$a0,$t3 ++ add $t5,$t5,$t6 ++ add $t5,$t5,$t7 ++ ; transfer bp[0] to FPU as 4x16-bit values ++ extrwi $t0,$t1,16,16 ++ extrwi $t1,$t1,16,0 ++ extrwi $t2,$t3,16,16 ++ extrwi $t3,$t3,16,0 ++ std $t0,`$FRAME+0`($sp) ; yes, std in 32-bit build ++ std $t1,`$FRAME+8`($sp) ++ std $t2,`$FRAME+16`($sp) ++ std $t3,`$FRAME+24`($sp) ++ ++ mullw $t0,$t4,$n0 ; mulld tp[0]*n0 ++ mulhwu $t1,$t4,$n0 ++ mullw $t2,$t5,$n0 ++ mullw $t3,$t4,$n1 ++ add $t1,$t1,$t2 ++ add $t1,$t1,$t3 ++ ; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values ++ extrwi $t4,$t0,16,16 ++ extrwi $t5,$t0,16,0 ++ extrwi $t6,$t1,16,16 ++ extrwi $t7,$t1,16,0 ++ std $t4,`$FRAME+32`($sp) ; yes, std in 32-bit build ++ std $t5,`$FRAME+40`($sp) ++ std $t6,`$FRAME+48`($sp) ++ std $t7,`$FRAME+56`($sp) ++ ++ mr $t0,$a0 ; lwz $t0,0($ap) ++ mr $t1,$a1 ; lwz $t1,4($ap) ++ lwz $t2,8($ap) ; load a[j..j+3] as 32-bit word pairs + lwz $t3,12($ap) + lwz $t4,0($np) ; load n[j..j+3] as 32-bit word pairs + lwz $t5,4($np) +@@ -319,7 +361,7 @@ $code.=<<___; + lfd $nb,`$FRAME+40`($sp) + lfd $nc,`$FRAME+48`($sp) + lfd $nd,`$FRAME+56`($sp) +- std $t0,`$FRAME+64`($sp) ++ std $t0,`$FRAME+64`($sp) ; yes, std even in 32-bit build + std $t1,`$FRAME+72`($sp) + std $t2,`$FRAME+80`($sp) + std $t3,`$FRAME+88`($sp) +@@ -441,7 +483,7 @@ $code.=<<___ if ($SIZE_T==4); + lwz $t7,12($np) + ___ + $code.=<<___; +- std $t0,`$FRAME+64`($sp) ++ std $t0,`$FRAME+64`($sp) ; yes, std even in 32-bit build + std $t1,`$FRAME+72`($sp) + std $t2,`$FRAME+80`($sp) + std $t3,`$FRAME+88`($sp) +@@ -449,6 +491,9 @@ $code.=<<___; + std $t5,`$FRAME+104`($sp) + std $t6,`$FRAME+112`($sp) + std $t7,`$FRAME+120`($sp) ++___ ++if ($SIZE_T==8 or $flavour =~ /osx/) { ++$code.=<<___; + ld $t0,`$FRAME+0`($sp) + ld $t1,`$FRAME+8`($sp) + ld $t2,`$FRAME+16`($sp) +@@ -457,6 +502,20 @@ $code.=<<___; + ld $t5,`$FRAME+40`($sp) + ld $t6,`$FRAME+48`($sp) + ld $t7,`$FRAME+56`($sp) ++___ ++} else { ++$code.=<<___; ++ lwz $t1,`$FRAME+0`($sp) ++ lwz $t0,`$FRAME+4`($sp) ++ lwz $t3,`$FRAME+8`($sp) ++ lwz $t2,`$FRAME+12`($sp) ++ lwz $t5,`$FRAME+16`($sp) ++ lwz $t4,`$FRAME+20`($sp) ++ lwz $t7,`$FRAME+24`($sp) ++ lwz $t6,`$FRAME+28`($sp) ++___ ++} ++$code.=<<___; + lfd $A0,`$FRAME+64`($sp) + lfd $A1,`$FRAME+72`($sp) + lfd $A2,`$FRAME+80`($sp) +@@ -488,7 +547,9 @@ $code.=<<___; + fmadd $T0b,$A0,$bb,$dotb + stfd $A2,24($nap_d) ; save a[j+1] in double format + stfd $A3,32($nap_d) +- ++___ ++if ($SIZE_T==8 or $flavour =~ /osx/) { ++$code.=<<___; + fmadd $T1a,$A0,$bc,$T1a + fmadd $T1b,$A0,$bd,$T1b + fmadd $T2a,$A1,$bc,$T2a +@@ -561,11 +622,123 @@ $code.=<<___; + stfd $T3b,`$FRAME+56`($sp) + std $t0,8($tp) ; tp[j-1] + stdu $t4,16($tp) ; tp[j] ++___ ++} else { ++$code.=<<___; ++ fmadd $T1a,$A0,$bc,$T1a ++ fmadd $T1b,$A0,$bd,$T1b ++ addc $t0,$t0,$carry ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ fmadd $T2a,$A1,$bc,$T2a ++ fmadd $T2b,$A1,$bd,$T2b ++ stfd $N0,40($nap_d) ; save n[j] in double format ++ stfd $N1,48($nap_d) ++ srwi $c1,$t1,16 ++ insrwi $carry,$t1,16,0 ++ fmadd $T3a,$A2,$bc,$T3a ++ fmadd $T3b,$A2,$bd,$T3b ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ fmul $dota,$A3,$bc ++ fmul $dotb,$A3,$bd ++ stfd $N2,56($nap_d) ; save n[j+1] in double format ++ stfdu $N3,64($nap_d) ++ insrwi $t0,$t2,16,0 ; 0..31 bits ++ srwi $c1,$t3,16 ++ insrwi $carry,$t3,16,0 ++ ++ fmadd $T1a,$N1,$na,$T1a ++ fmadd $T1b,$N1,$nb,$T1b ++ lwz $t3,`$FRAME+32`($sp) ; permuted $t1 ++ lwz $t2,`$FRAME+36`($sp) ; permuted $t0 ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ fmadd $T2a,$N2,$na,$T2a ++ fmadd $T2b,$N2,$nb,$T2b ++ srwi $c1,$t5,16 ++ insrwi $carry,$t5,16,0 ++ fmadd $T3a,$N3,$na,$T3a ++ fmadd $T3b,$N3,$nb,$T3b ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ fmadd $T0a,$N0,$na,$T0a ++ fmadd $T0b,$N0,$nb,$T0b ++ insrwi $t4,$t6,16,0 ; 32..63 bits ++ srwi $c1,$t7,16 ++ insrwi $carry,$t7,16,0 ++ ++ fmadd $T1a,$N0,$nc,$T1a ++ fmadd $T1b,$N0,$nd,$T1b ++ lwz $t7,`$FRAME+40`($sp) ; permuted $t3 ++ lwz $t6,`$FRAME+44`($sp) ; permuted $t2 ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ fmadd $T2a,$N1,$nc,$T2a ++ fmadd $T2b,$N1,$nd,$T2b ++ stw $t0,12($tp) ; tp[j-1] ++ stw $t4,8($tp) ++ srwi $c1,$t3,16 ++ insrwi $carry,$t3,16,0 ++ fmadd $T3a,$N2,$nc,$T3a ++ fmadd $T3b,$N2,$nd,$T3b ++ lwz $t1,`$FRAME+48`($sp) ; permuted $t5 ++ lwz $t0,`$FRAME+52`($sp) ; permuted $t4 ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ fmadd $dota,$N3,$nc,$dota ++ fmadd $dotb,$N3,$nd,$dotb ++ insrwi $t2,$t6,16,0 ; 64..95 bits ++ srwi $c1,$t7,16 ++ insrwi $carry,$t7,16,0 ++ ++ fctid $T0a,$T0a ++ fctid $T0b,$T0b ++ lwz $t5,`$FRAME+56`($sp) ; permuted $t7 ++ lwz $t4,`$FRAME+60`($sp) ; permuted $t6 ++ addc $t0,$t0,$carry ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ fctid $T1a,$T1a ++ fctid $T1b,$T1b ++ srwi $c1,$t1,16 ++ insrwi $carry,$t1,16,0 ++ fctid $T2a,$T2a ++ fctid $T2b,$T2b ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ fctid $T3a,$T3a ++ fctid $T3b,$T3b ++ insrwi $t0,$t4,16,0 ; 96..127 bits ++ srwi $c1,$t5,16 ++ insrwi $carry,$t5,16,0 ++ ++ stfd $T0a,`$FRAME+0`($sp) ++ stfd $T0b,`$FRAME+8`($sp) ++ stfd $T1a,`$FRAME+16`($sp) ++ stfd $T1b,`$FRAME+24`($sp) ++ stfd $T2a,`$FRAME+32`($sp) ++ stfd $T2b,`$FRAME+40`($sp) ++ stfd $T3a,`$FRAME+48`($sp) ++ stfd $T3b,`$FRAME+56`($sp) ++ stw $t2,20($tp) ; tp[j] ++ stwu $t0,16($tp) ++___ ++} ++$code.=<<___; + bdnz- L1st + + fctid $dota,$dota + fctid $dotb,$dotb +- ++___ ++if ($SIZE_T==8 or $flavour =~ /osx/) { ++$code.=<<___; + ld $t0,`$FRAME+0`($sp) + ld $t1,`$FRAME+8`($sp) + ld $t2,`$FRAME+16`($sp) +@@ -611,33 +784,117 @@ $code.=<<___; + insrdi $t6,$t7,48,0 + srdi $ovf,$t7,48 + std $t6,8($tp) ; tp[num-1] ++___ ++} else { ++$code.=<<___; ++ lwz $t1,`$FRAME+0`($sp) ++ lwz $t0,`$FRAME+4`($sp) ++ lwz $t3,`$FRAME+8`($sp) ++ lwz $t2,`$FRAME+12`($sp) ++ lwz $t5,`$FRAME+16`($sp) ++ lwz $t4,`$FRAME+20`($sp) ++ lwz $t7,`$FRAME+24`($sp) ++ lwz $t6,`$FRAME+28`($sp) ++ stfd $dota,`$FRAME+64`($sp) ++ stfd $dotb,`$FRAME+72`($sp) + ++ addc $t0,$t0,$carry ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ insrwi $carry,$t1,16,0 ++ srwi $c1,$t1,16 ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ insrwi $t0,$t2,16,0 ; 0..31 bits ++ insrwi $carry,$t3,16,0 ++ srwi $c1,$t3,16 ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ insrwi $carry,$t5,16,0 ++ srwi $c1,$t5,16 ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ insrwi $t4,$t6,16,0 ; 32..63 bits ++ insrwi $carry,$t7,16,0 ++ srwi $c1,$t7,16 ++ stw $t0,12($tp) ; tp[j-1] ++ stw $t4,8($tp) ++ ++ lwz $t3,`$FRAME+32`($sp) ; permuted $t1 ++ lwz $t2,`$FRAME+36`($sp) ; permuted $t0 ++ lwz $t7,`$FRAME+40`($sp) ; permuted $t3 ++ lwz $t6,`$FRAME+44`($sp) ; permuted $t2 ++ lwz $t1,`$FRAME+48`($sp) ; permuted $t5 ++ lwz $t0,`$FRAME+52`($sp) ; permuted $t4 ++ lwz $t5,`$FRAME+56`($sp) ; permuted $t7 ++ lwz $t4,`$FRAME+60`($sp) ; permuted $t6 ++ ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ insrwi $carry,$t3,16,0 ++ srwi $c1,$t3,16 ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ insrwi $t2,$t6,16,0 ; 64..95 bits ++ insrwi $carry,$t7,16,0 ++ srwi $c1,$t7,16 ++ addc $t0,$t0,$carry ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ insrwi $carry,$t1,16,0 ++ srwi $c1,$t1,16 ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ insrwi $t0,$t4,16,0 ; 96..127 bits ++ insrwi $carry,$t5,16,0 ++ srwi $c1,$t5,16 ++ stw $t2,20($tp) ; tp[j] ++ stwu $t0,16($tp) ++ ++ lwz $t7,`$FRAME+64`($sp) ++ lwz $t6,`$FRAME+68`($sp) ++ lwz $t5,`$FRAME+72`($sp) ++ lwz $t4,`$FRAME+76`($sp) ++ ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ insrwi $carry,$t7,16,0 ++ srwi $c1,$t7,16 ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ ++ insrwi $t6,$t4,16,0 ++ srwi $t4,$t4,16 ++ insrwi $t4,$t5,16,0 ++ srwi $ovf,$t5,16 ++ stw $t6,12($tp) ; tp[num-1] ++ stw $t4,8($tp) ++___ ++} ++$code.=<<___; + slwi $t7,$num,2 + subf $nap_d,$t7,$nap_d ; rewind pointer + + li $i,8 ; i=1 + .align 5 + Louter: +-___ +-$code.=<<___ if ($SIZE_T==8); +- ldx $t3,$bp,$i ; bp[i] +-___ +-$code.=<<___ if ($SIZE_T==4); +- add $t0,$bp,$i +- lwz $t3,0($t0) ; bp[i,i+1] +- lwz $t0,4($t0) +- insrdi $t3,$t0,32,0 +-___ +-$code.=<<___; +- ld $t6,`$FRAME+$TRANSFER+8`($sp) ; tp[0] +- mulld $t7,$a0,$t3 ; ap[0]*bp[i] +- + addi $tp,$sp,`$FRAME+$TRANSFER` +- add $t7,$t7,$t6 ; ap[0]*bp[i]+tp[0] + li $carry,0 +- mulld $t7,$t7,$n0 ; tp[0]*n0 + mtctr $j ++___ ++$code.=<<___ if ($SIZE_T==8); ++ ldx $t3,$bp,$i ; bp[i] + ++ ld $t6,`$FRAME+$TRANSFER+8`($sp) ; tp[0] ++ mulld $t7,$a0,$t3 ; ap[0]*bp[i] ++ add $t7,$t7,$t6 ; ap[0]*bp[i]+tp[0] + ; transfer bp[i] to FPU as 4x16-bit values + extrdi $t0,$t3,16,48 + extrdi $t1,$t3,16,32 +@@ -647,6 +904,8 @@ $code.=<<___; + std $t1,`$FRAME+8`($sp) + std $t2,`$FRAME+16`($sp) + std $t3,`$FRAME+24`($sp) ++ ++ mulld $t7,$t7,$n0 ; tp[0]*n0 + ; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values + extrdi $t4,$t7,16,48 + extrdi $t5,$t7,16,32 +@@ -656,7 +915,50 @@ $code.=<<___; + std $t5,`$FRAME+40`($sp) + std $t6,`$FRAME+48`($sp) + std $t7,`$FRAME+56`($sp) ++___ ++$code.=<<___ if ($SIZE_T==4); ++ add $t0,$bp,$i ++ li $c1,0 ++ lwz $t1,0($t0) ; bp[i,i+1] ++ lwz $t3,4($t0) ++ ++ mullw $t4,$a0,$t1 ; ap[0]*bp[i] ++ lwz $t0,`$FRAME+$TRANSFER+8+4`($sp) ; tp[0] ++ mulhwu $t5,$a0,$t1 ++ lwz $t2,`$FRAME+$TRANSFER+8`($sp) ; tp[0] ++ mullw $t6,$a1,$t1 ++ mullw $t7,$a0,$t3 ++ add $t5,$t5,$t6 ++ add $t5,$t5,$t7 ++ addc $t4,$t4,$t0 ; ap[0]*bp[i]+tp[0] ++ adde $t5,$t5,$t2 ++ ; transfer bp[i] to FPU as 4x16-bit values ++ extrwi $t0,$t1,16,16 ++ extrwi $t1,$t1,16,0 ++ extrwi $t2,$t3,16,16 ++ extrwi $t3,$t3,16,0 ++ std $t0,`$FRAME+0`($sp) ; yes, std in 32-bit build ++ std $t1,`$FRAME+8`($sp) ++ std $t2,`$FRAME+16`($sp) ++ std $t3,`$FRAME+24`($sp) + ++ mullw $t0,$t4,$n0 ; mulld tp[0]*n0 ++ mulhwu $t1,$t4,$n0 ++ mullw $t2,$t5,$n0 ++ mullw $t3,$t4,$n1 ++ add $t1,$t1,$t2 ++ add $t1,$t1,$t3 ++ ; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values ++ extrwi $t4,$t0,16,16 ++ extrwi $t5,$t0,16,0 ++ extrwi $t6,$t1,16,16 ++ extrwi $t7,$t1,16,0 ++ std $t4,`$FRAME+32`($sp) ; yes, std in 32-bit build ++ std $t5,`$FRAME+40`($sp) ++ std $t6,`$FRAME+48`($sp) ++ std $t7,`$FRAME+56`($sp) ++___ ++$code.=<<___; + lfd $A0,8($nap_d) ; load a[j] in double format + lfd $A1,16($nap_d) + lfd $A2,24($nap_d) ; load a[j+1] in double format +@@ -769,7 +1071,9 @@ Linner: + fmul $dotb,$A3,$bd + lfd $A2,24($nap_d) ; load a[j+1] in double format + lfd $A3,32($nap_d) +- ++___ ++if ($SIZE_T==8 or $flavour =~ /osx/) { ++$code.=<<___; + fmadd $T1a,$N1,$na,$T1a + fmadd $T1b,$N1,$nb,$T1b + ld $t0,`$FRAME+0`($sp) +@@ -856,10 +1160,131 @@ $code.=<<___; + addze $carry,$carry + std $t3,-16($tp) ; tp[j-1] + std $t5,-8($tp) ; tp[j] ++___ ++} else { ++$code.=<<___; ++ fmadd $T1a,$N1,$na,$T1a ++ fmadd $T1b,$N1,$nb,$T1b ++ lwz $t1,`$FRAME+0`($sp) ++ lwz $t0,`$FRAME+4`($sp) ++ fmadd $T2a,$N2,$na,$T2a ++ fmadd $T2b,$N2,$nb,$T2b ++ lwz $t3,`$FRAME+8`($sp) ++ lwz $t2,`$FRAME+12`($sp) ++ fmadd $T3a,$N3,$na,$T3a ++ fmadd $T3b,$N3,$nb,$T3b ++ lwz $t5,`$FRAME+16`($sp) ++ lwz $t4,`$FRAME+20`($sp) ++ addc $t0,$t0,$carry ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ fmadd $T0a,$N0,$na,$T0a ++ fmadd $T0b,$N0,$nb,$T0b ++ lwz $t7,`$FRAME+24`($sp) ++ lwz $t6,`$FRAME+28`($sp) ++ srwi $c1,$t1,16 ++ insrwi $carry,$t1,16,0 ++ ++ fmadd $T1a,$N0,$nc,$T1a ++ fmadd $T1b,$N0,$nd,$T1b ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ fmadd $T2a,$N1,$nc,$T2a ++ fmadd $T2b,$N1,$nd,$T2b ++ insrwi $t0,$t2,16,0 ; 0..31 bits ++ srwi $c1,$t3,16 ++ insrwi $carry,$t3,16,0 ++ fmadd $T3a,$N2,$nc,$T3a ++ fmadd $T3b,$N2,$nd,$T3b ++ lwz $t2,12($tp) ; tp[j] ++ lwz $t3,8($tp) ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ fmadd $dota,$N3,$nc,$dota ++ fmadd $dotb,$N3,$nd,$dotb ++ srwi $c1,$t5,16 ++ insrwi $carry,$t5,16,0 ++ ++ fctid $T0a,$T0a ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ fctid $T0b,$T0b ++ insrwi $t4,$t6,16,0 ; 32..63 bits ++ srwi $c1,$t7,16 ++ insrwi $carry,$t7,16,0 ++ fctid $T1a,$T1a ++ addc $t0,$t0,$t2 ++ adde $t4,$t4,$t3 ++ lwz $t3,`$FRAME+32`($sp) ; permuted $t1 ++ lwz $t2,`$FRAME+36`($sp) ; permuted $t0 ++ fctid $T1b,$T1b ++ addze $carry,$carry ++ addze $c1,$c1 ++ stw $t0,4($tp) ; tp[j-1] ++ stw $t4,0($tp) ++ fctid $T2a,$T2a ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ lwz $t7,`$FRAME+40`($sp) ; permuted $t3 ++ lwz $t6,`$FRAME+44`($sp) ; permuted $t2 ++ fctid $T2b,$T2b ++ srwi $c1,$t3,16 ++ insrwi $carry,$t3,16,0 ++ lwz $t1,`$FRAME+48`($sp) ; permuted $t5 ++ lwz $t0,`$FRAME+52`($sp) ; permuted $t4 ++ fctid $T3a,$T3a ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ lwz $t5,`$FRAME+56`($sp) ; permuted $t7 ++ lwz $t4,`$FRAME+60`($sp) ; permuted $t6 ++ fctid $T3b,$T3b ++ ++ insrwi $t2,$t6,16,0 ; 64..95 bits ++ insrwi $carry,$t7,16,0 ++ srwi $c1,$t7,16 ++ lwz $t6,20($tp) ++ lwzu $t7,16($tp) ++ addc $t0,$t0,$carry ++ stfd $T0a,`$FRAME+0`($sp) ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ stfd $T0b,`$FRAME+8`($sp) ++ insrwi $carry,$t1,16,0 ++ srwi $c1,$t1,16 ++ addc $t4,$t4,$carry ++ stfd $T1a,`$FRAME+16`($sp) ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ insrwi $t0,$t4,16,0 ; 96..127 bits ++ stfd $T1b,`$FRAME+24`($sp) ++ insrwi $carry,$t5,16,0 ++ srwi $c1,$t5,16 ++ ++ addc $t2,$t2,$t6 ++ stfd $T2a,`$FRAME+32`($sp) ++ adde $t0,$t0,$t7 ++ stfd $T2b,`$FRAME+40`($sp) ++ addze $carry,$carry ++ stfd $T3a,`$FRAME+48`($sp) ++ addze $c1,$c1 ++ stfd $T3b,`$FRAME+56`($sp) ++ stw $t2,-4($tp) ; tp[j] ++ stw $t0,-8($tp) ++___ ++} ++$code.=<<___; + bdnz- Linner + + fctid $dota,$dota + fctid $dotb,$dotb ++___ ++if ($SIZE_T==8 or $flavour =~ /osx/) { ++$code.=<<___; + ld $t0,`$FRAME+0`($sp) + ld $t1,`$FRAME+8`($sp) + ld $t2,`$FRAME+16`($sp) +@@ -926,7 +1351,116 @@ $code.=<<___; + insrdi $t6,$t7,48,0 + srdi $ovf,$t7,48 + std $t6,0($tp) ; tp[num-1] ++___ ++} else { ++$code.=<<___; ++ lwz $t1,`$FRAME+0`($sp) ++ lwz $t0,`$FRAME+4`($sp) ++ lwz $t3,`$FRAME+8`($sp) ++ lwz $t2,`$FRAME+12`($sp) ++ lwz $t5,`$FRAME+16`($sp) ++ lwz $t4,`$FRAME+20`($sp) ++ lwz $t7,`$FRAME+24`($sp) ++ lwz $t6,`$FRAME+28`($sp) ++ stfd $dota,`$FRAME+64`($sp) ++ stfd $dotb,`$FRAME+72`($sp) + ++ addc $t0,$t0,$carry ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ insrwi $carry,$t1,16,0 ++ srwi $c1,$t1,16 ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ insrwi $t0,$t2,16,0 ; 0..31 bits ++ lwz $t2,12($tp) ; tp[j] ++ insrwi $carry,$t3,16,0 ++ srwi $c1,$t3,16 ++ lwz $t3,8($tp) ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ insrwi $carry,$t5,16,0 ++ srwi $c1,$t5,16 ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ insrwi $t4,$t6,16,0 ; 32..63 bits ++ insrwi $carry,$t7,16,0 ++ srwi $c1,$t7,16 ++ ++ addc $t0,$t0,$t2 ++ adde $t4,$t4,$t3 ++ addze $carry,$carry ++ addze $c1,$c1 ++ stw $t0,4($tp) ; tp[j-1] ++ stw $t4,0($tp) ++ ++ lwz $t3,`$FRAME+32`($sp) ; permuted $t1 ++ lwz $t2,`$FRAME+36`($sp) ; permuted $t0 ++ lwz $t7,`$FRAME+40`($sp) ; permuted $t3 ++ lwz $t6,`$FRAME+44`($sp) ; permuted $t2 ++ lwz $t1,`$FRAME+48`($sp) ; permuted $t5 ++ lwz $t0,`$FRAME+52`($sp) ; permuted $t4 ++ lwz $t5,`$FRAME+56`($sp) ; permuted $t7 ++ lwz $t4,`$FRAME+60`($sp) ; permuted $t6 ++ ++ addc $t2,$t2,$carry ++ adde $t3,$t3,$c1 ++ srwi $carry,$t2,16 ++ insrwi $carry,$t3,16,0 ++ srwi $c1,$t3,16 ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ srwi $carry,$t6,16 ++ insrwi $t2,$t6,16,0 ; 64..95 bits ++ lwz $t6,20($tp) ++ insrwi $carry,$t7,16,0 ++ srwi $c1,$t7,16 ++ lwzu $t7,16($tp) ++ addc $t0,$t0,$carry ++ adde $t1,$t1,$c1 ++ srwi $carry,$t0,16 ++ insrwi $carry,$t1,16,0 ++ srwi $c1,$t1,16 ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ srwi $carry,$t4,16 ++ insrwi $t0,$t4,16,0 ; 96..127 bits ++ insrwi $carry,$t5,16,0 ++ srwi $c1,$t5,16 ++ ++ addc $t2,$t2,$t6 ++ adde $t0,$t0,$t7 ++ lwz $t7,`$FRAME+64`($sp) ++ lwz $t6,`$FRAME+68`($sp) ++ addze $carry,$carry ++ addze $c1,$c1 ++ lwz $t5,`$FRAME+72`($sp) ++ lwz $t4,`$FRAME+76`($sp) ++ ++ addc $t6,$t6,$carry ++ adde $t7,$t7,$c1 ++ stw $t2,-4($tp) ; tp[j] ++ stw $t0,-8($tp) ++ addc $t6,$t6,$ovf ++ addze $t7,$t7 ++ srwi $carry,$t6,16 ++ insrwi $carry,$t7,16,0 ++ srwi $c1,$t7,16 ++ addc $t4,$t4,$carry ++ adde $t5,$t5,$c1 ++ ++ insrwi $t6,$t4,16,0 ++ srwi $t4,$t4,16 ++ insrwi $t4,$t5,16,0 ++ srwi $ovf,$t5,16 ++ stw $t6,4($tp) ; tp[num-1] ++ stw $t4,0($tp) ++___ ++} ++$code.=<<___; + slwi $t7,$num,2 + addi $i,$i,8 + subf $nap_d,$t7,$nap_d ; rewind pointer +@@ -994,14 +1528,14 @@ $code.=<<___ if ($SIZE_T==4); + mtctr $j + + .align 4 +-Lsub: ld $t0,8($tp) ; load tp[j..j+3] in 64-bit word order +- ldu $t2,16($tp) ++Lsub: lwz $t0,12($tp) ; load tp[j..j+3] in 64-bit word order ++ lwz $t1,8($tp) ++ lwz $t2,20($tp) ++ lwzu $t3,16($tp) + lwz $t4,4($np) ; load np[j..j+3] in 32-bit word order + lwz $t5,8($np) + lwz $t6,12($np) + lwzu $t7,16($np) +- extrdi $t1,$t0,32,0 +- extrdi $t3,$t2,32,0 + subfe $t4,$t4,$t0 ; tp[j]-np[j] + stw $t0,4($ap) ; save tp[j..j+3] in 32-bit word order + subfe $t5,$t5,$t1 ; tp[j+1]-np[j+1] +@@ -1052,6 +1586,9 @@ ___ + $code.=<<___; + $POP $i,0($sp) + li r3,1 ; signal "handled" ++ $POP r19,`-12*8-13*$SIZE_T`($i) ++ $POP r20,`-12*8-12*$SIZE_T`($i) ++ $POP r21,`-12*8-11*$SIZE_T`($i) + $POP r22,`-12*8-10*$SIZE_T`($i) + $POP r23,`-12*8-9*$SIZE_T`($i) + $POP r24,`-12*8-8*$SIZE_T`($i) +@@ -1077,8 +1614,9 @@ $code.=<<___; + mr $sp,$i + blr + .long 0 +- .byte 0,12,4,0,0x8c,10,6,0 ++ .byte 0,12,4,0,0x8c,13,6,0 + .long 0 ++.size .$fname,.-.$fname + + .asciz "Montgomery Multiplication for PPC64, CRYPTOGAMS by " + ___ +diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c +index 1bfb5d9..51137fd 100644 +--- a/crypto/evp/e_aes.c ++++ b/crypto/evp/e_aes.c +@@ -153,6 +153,20 @@ void AES_xts_decrypt(const char *inp,char *out,size_t len, + const unsigned char iv[16]); + #endif + ++#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) ++# include "ppc_arch.h" ++# ifdef VPAES_ASM ++# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC) ++# endif ++# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207) ++# define HWAES_set_encrypt_key aes_p8_set_encrypt_key ++# define HWAES_set_decrypt_key aes_p8_set_decrypt_key ++# define HWAES_encrypt aes_p8_encrypt ++# define HWAES_decrypt aes_p8_decrypt ++# define HWAES_cbc_encrypt aes_p8_cbc_encrypt ++# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks ++#endif ++ + #if defined(AES_ASM) && !defined(I386_ONLY) && ( \ + ((defined(__i386) || defined(__i386__) || \ + defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ +diff --git a/crypto/modes/Makefile b/crypto/modes/Makefile +index c825b12..e684e02 100644 +--- a/crypto/modes/Makefile ++++ b/crypto/modes/Makefile +@@ -56,6 +56,10 @@ ghash-alpha.s: asm/ghash-alpha.pl + $(PERL) $< | $(CC) -E - | tee $@ > /dev/null + ghash-parisc.s: asm/ghash-parisc.pl + $(PERL) asm/ghash-parisc.pl $(PERLASM_SCHEME) $@ ++ghashv8-armx.S: asm/ghashv8-armx.pl ++ $(PERL) asm/ghashv8-armx.pl $(PERLASM_SCHEME) $@ ++ghashp8-ppc.s: asm/ghashp8-ppc.pl ++ $(PERL) asm/ghashp8-ppc.pl $(PERLASM_SCHEME) $@ + + # GNU make "catch all" + ghash-%.S: asm/ghash-%.pl; $(PERL) $< $(PERLASM_SCHEME) $@ +diff --git a/crypto/modes/asm/ghashp8-ppc.pl b/crypto/modes/asm/ghashp8-ppc.pl +new file mode 100755 +index 0000000..e76a58c +--- /dev/null ++++ b/crypto/modes/asm/ghashp8-ppc.pl +@@ -0,0 +1,234 @@ ++#!/usr/bin/env perl ++# ++# ==================================================================== ++# Written by Andy Polyakov for the OpenSSL ++# project. The module is, however, dual licensed under OpenSSL and ++# CRYPTOGAMS licenses depending on where you obtain it. For further ++# details see http://www.openssl.org/~appro/cryptogams/. ++# ==================================================================== ++# ++# GHASH for for PowerISA v2.07. ++# ++# July 2014 ++# ++# Accurate performance measurements are problematic, because it's ++# always virtualized setup with possibly throttled processor. ++# Relative comparison is therefore more informative. This initial ++# version is ~2.1x slower than hardware-assisted AES-128-CTR, ~12x ++# faster than "4-bit" integer-only compiler-generated 64-bit code. ++# "Initial version" means that there is room for futher improvement. ++ ++$flavour=shift; ++$output =shift; ++ ++if ($flavour =~ /64/) { ++ $SIZE_T=8; ++ $LRSAVE=2*$SIZE_T; ++ $STU="stdu"; ++ $POP="ld"; ++ $PUSH="std"; ++} elsif ($flavour =~ /32/) { ++ $SIZE_T=4; ++ $LRSAVE=$SIZE_T; ++ $STU="stwu"; ++ $POP="lwz"; ++ $PUSH="stw"; ++} else { die "nonsense $flavour"; } ++ ++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ++( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ++( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or ++die "can't locate ppc-xlate.pl"; ++ ++open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; ++ ++my ($Xip,$Htbl,$inp,$len)=map("r$_",(3..6)); # argument block ++ ++my ($Xl,$Xm,$Xh,$IN)=map("v$_",(0..3)); ++my ($zero,$t0,$t1,$t2,$xC2,$H,$Hh,$Hl,$lemask)=map("v$_",(4..12)); ++my $vrsave="r12"; ++ ++$code=<<___; ++.machine "any" ++ ++.text ++ ++.globl .gcm_init_p8 ++.align 5 ++.gcm_init_p8: ++ lis r0,0xfff0 ++ li r8,0x10 ++ mfspr $vrsave,256 ++ li r9,0x20 ++ mtspr 256,r0 ++ li r10,0x30 ++ lvx_u $H,0,r4 # load H ++ ++ vspltisb $xC2,-16 # 0xf0 ++ vspltisb $t0,1 # one ++ vaddubm $xC2,$xC2,$xC2 # 0xe0 ++ vxor $zero,$zero,$zero ++ vor $xC2,$xC2,$t0 # 0xe1 ++ vsldoi $xC2,$xC2,$zero,15 # 0xe1... ++ vsldoi $t1,$zero,$t0,1 # ...1 ++ vaddubm $xC2,$xC2,$xC2 # 0xc2... ++ vspltisb $t2,7 ++ vor $xC2,$xC2,$t1 # 0xc2....01 ++ vspltb $t1,$H,0 # most significant byte ++ vsl $H,$H,$t0 # H<<=1 ++ vsrab $t1,$t1,$t2 # broadcast carry bit ++ vand $t1,$t1,$xC2 ++ vxor $H,$H,$t1 # twisted H ++ ++ vsldoi $H,$H,$H,8 # twist even more ... ++ vsldoi $xC2,$zero,$xC2,8 # 0xc2.0 ++ vsldoi $Hl,$zero,$H,8 # ... and split ++ vsldoi $Hh,$H,$zero,8 ++ ++ stvx_u $xC2,0,r3 # save pre-computed table ++ stvx_u $Hl,r8,r3 ++ stvx_u $H, r9,r3 ++ stvx_u $Hh,r10,r3 ++ ++ mtspr 256,$vrsave ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,2,0 ++ .long 0 ++.size .gcm_init_p8,.-.gcm_init_p8 ++ ++.globl .gcm_gmult_p8 ++.align 5 ++.gcm_gmult_p8: ++ lis r0,0xfff8 ++ li r8,0x10 ++ mfspr $vrsave,256 ++ li r9,0x20 ++ mtspr 256,r0 ++ li r10,0x30 ++ lvx_u $IN,0,$Xip # load Xi ++ ++ lvx_u $Hl,r8,$Htbl # load pre-computed table ++ le?lvsl $lemask,r0,r0 ++ lvx_u $H, r9,$Htbl ++ le?vspltisb $t0,0x07 ++ lvx_u $Hh,r10,$Htbl ++ le?vxor $lemask,$lemask,$t0 ++ lvx_u $xC2,0,$Htbl ++ le?vperm $IN,$IN,$IN,$lemask ++ vxor $zero,$zero,$zero ++ ++ vpmsumd $Xl,$IN,$Hl # H.lo·Xi.lo ++ vpmsumd $Xm,$IN,$H # H.hi·Xi.lo+H.lo·Xi.hi ++ vpmsumd $Xh,$IN,$Hh # H.hi·Xi.hi ++ ++ vpmsumd $t2,$Xl,$xC2 # 1st phase ++ ++ vsldoi $t0,$Xm,$zero,8 ++ vsldoi $t1,$zero,$Xm,8 ++ vxor $Xl,$Xl,$t0 ++ vxor $Xh,$Xh,$t1 ++ ++ vsldoi $Xl,$Xl,$Xl,8 ++ vxor $Xl,$Xl,$t2 ++ ++ vsldoi $t1,$Xl,$Xl,8 # 2nd phase ++ vpmsumd $Xl,$Xl,$xC2 ++ vxor $t1,$t1,$Xh ++ vxor $Xl,$Xl,$t1 ++ ++ le?vperm $Xl,$Xl,$Xl,$lemask ++ stvx_u $Xl,0,$Xip # write out Xi ++ ++ mtspr 256,$vrsave ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,2,0 ++ .long 0 ++.size .gcm_gmult_p8,.-.gcm_gmult_p8 ++ ++.globl .gcm_ghash_p8 ++.align 5 ++.gcm_ghash_p8: ++ lis r0,0xfff8 ++ li r8,0x10 ++ mfspr $vrsave,256 ++ li r9,0x20 ++ mtspr 256,r0 ++ li r10,0x30 ++ lvx_u $Xl,0,$Xip # load Xi ++ ++ lvx_u $Hl,r8,$Htbl # load pre-computed table ++ le?lvsl $lemask,r0,r0 ++ lvx_u $H, r9,$Htbl ++ le?vspltisb $t0,0x07 ++ lvx_u $Hh,r10,$Htbl ++ le?vxor $lemask,$lemask,$t0 ++ lvx_u $xC2,0,$Htbl ++ le?vperm $Xl,$Xl,$Xl,$lemask ++ vxor $zero,$zero,$zero ++ ++ lvx_u $IN,0,$inp ++ addi $inp,$inp,16 ++ subi $len,$len,16 ++ le?vperm $IN,$IN,$IN,$lemask ++ vxor $IN,$IN,$Xl ++ b Loop ++ ++.align 5 ++Loop: ++ subic $len,$len,16 ++ vpmsumd $Xl,$IN,$Hl # H.lo·Xi.lo ++ subfe. r0,r0,r0 # borrow?-1:0 ++ vpmsumd $Xm,$IN,$H # H.hi·Xi.lo+H.lo·Xi.hi ++ and r0,r0,$len ++ vpmsumd $Xh,$IN,$Hh # H.hi·Xi.hi ++ add $inp,$inp,r0 ++ ++ vpmsumd $t2,$Xl,$xC2 # 1st phase ++ ++ vsldoi $t0,$Xm,$zero,8 ++ vsldoi $t1,$zero,$Xm,8 ++ vxor $Xl,$Xl,$t0 ++ vxor $Xh,$Xh,$t1 ++ ++ vsldoi $Xl,$Xl,$Xl,8 ++ vxor $Xl,$Xl,$t2 ++ lvx_u $IN,0,$inp ++ addi $inp,$inp,16 ++ ++ vsldoi $t1,$Xl,$Xl,8 # 2nd phase ++ vpmsumd $Xl,$Xl,$xC2 ++ le?vperm $IN,$IN,$IN,$lemask ++ vxor $t1,$t1,$Xh ++ vxor $IN,$IN,$t1 ++ vxor $IN,$IN,$Xl ++ beq Loop # did $len-=16 borrow? ++ ++ vxor $Xl,$Xl,$t1 ++ le?vperm $Xl,$Xl,$Xl,$lemask ++ stvx_u $Xl,0,$Xip # write out Xi ++ ++ mtspr 256,$vrsave ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,4,0 ++ .long 0 ++.size .gcm_ghash_p8,.-.gcm_ghash_p8 ++ ++.asciz "GHASH for PowerISA 2.07, CRYPTOGAMS by " ++.align 2 ++___ ++ ++foreach (split("\n",$code)) { ++ if ($flavour =~ /le$/o) { # little-endian ++ s/le\?//o or ++ s/be\?/#be#/o; ++ } else { ++ s/le\?/#le#/o or ++ s/be\?//o; ++ } ++ print $_,"\n"; ++} ++ ++close STDOUT; # enforce flush +diff --git a/crypto/modes/gcm128.c b/crypto/modes/gcm128.c +index 0e6ff8b..6f8e7ee 100644 +--- a/crypto/modes/gcm128.c ++++ b/crypto/modes/gcm128.c +@@ -671,6 +671,21 @@ void gcm_ghash_4bit_x86(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len + void gcm_gmult_neon(u64 Xi[2],const u128 Htable[16]); + void gcm_ghash_neon(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len); + # endif ++# elif defined(__sparc__) || defined(__sparc) ++# include "sparc_arch.h" ++# define GHASH_ASM_SPARC ++# define GCM_FUNCREF_4BIT ++extern unsigned int OPENSSL_sparcv9cap_P[]; ++void gcm_init_vis3(u128 Htable[16],const u64 Xi[2]); ++void gcm_gmult_vis3(u64 Xi[2],const u128 Htable[16]); ++void gcm_ghash_vis3(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len); ++#elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) ++# include "ppc_arch.h" ++# define GHASH_ASM_PPC ++# define GCM_FUNCREF_4BIT ++void gcm_init_p8(u128 Htable[16],const u64 Xi[2]); ++void gcm_gmult_p8(u64 Xi[2],const u128 Htable[16]); ++void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len); + # endif + #endif + +@@ -747,6 +762,16 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block) + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; + } ++# elif defined(GHASH_ASM_PPC) ++ if (OPENSSL_ppccap_P & PPC_CRYPTO207) { ++ gcm_init_p8(ctx->Htable,ctx->H.u); ++ ctx->gmult = gcm_gmult_p8; ++ ctx->ghash = gcm_ghash_p8; ++ } else { ++ gcm_init_4bit(ctx->Htable,ctx->H.u); ++ ctx->gmult = gcm_gmult_4bit; ++ ctx->ghash = gcm_ghash_4bit; ++ } + # else + gcm_init_4bit(ctx->Htable,ctx->H.u); + # endif +diff --git a/crypto/perlasm/ppc-xlate.pl b/crypto/perlasm/ppc-xlate.pl +index a3edd98..f89e814 100755 +--- a/crypto/perlasm/ppc-xlate.pl ++++ b/crypto/perlasm/ppc-xlate.pl +@@ -27,7 +27,8 @@ my $globl = sub { + /osx/ && do { $name = "_$name"; + last; + }; +- /linux.*32/ && do { $ret .= ".globl $name\n"; ++ /linux.*(32|64le)/ ++ && do { $ret .= ".globl $name\n"; + $ret .= ".type $name,\@function"; + last; + }; +@@ -37,7 +38,6 @@ my $globl = sub { + $ret .= ".align 3\n"; + $ret .= "$name:\n"; + $ret .= ".quad .$name,.TOC.\@tocbase,0\n"; +- $ret .= ".size $name,24\n"; + $ret .= ".previous\n"; + + $name = ".$name"; +@@ -50,7 +50,9 @@ my $globl = sub { + $ret; + }; + my $text = sub { +- ($flavour =~ /aix/) ? ".csect" : ".text"; ++ my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text"; ++ $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/); ++ $ret; + }; + my $machine = sub { + my $junk = shift; +@@ -62,9 +64,12 @@ my $machine = sub { + ".machine $arch"; + }; + my $size = sub { +- if ($flavour =~ /linux.*32/) ++ if ($flavour =~ /linux/) + { shift; +- ".size " . join(",",@_); ++ my $name = shift; $name =~ s|^[\.\_]||; ++ my $ret = ".size $name,.-".($flavour=~/64$/?".":"").$name; ++ $ret .= "\n.size .$name,.-.$name" if ($flavour=~/64$/); ++ $ret; + } + else + { ""; } +@@ -77,6 +82,25 @@ my $asciz = sub { + else + { ""; } + }; ++my $quad = sub { ++ shift; ++ my @ret; ++ my ($hi,$lo); ++ for (@_) { ++ if (/^0x([0-9a-f]*?)([0-9a-f]{1,8})$/io) ++ { $hi=$1?"0x$1":"0"; $lo="0x$2"; } ++ elsif (/^([0-9]+)$/o) ++ { $hi=$1>>32; $lo=$1&0xffffffff; } # error-prone with 32-bit perl ++ else ++ { $hi=undef; $lo=$_; } ++ ++ if (defined($hi)) ++ { push(@ret,$flavour=~/le$/o?".long\t$lo,$hi":".long\t$hi,$lo"); } ++ else ++ { push(@ret,".quad $lo"); } ++ } ++ join("\n",@ret); ++}; + + ################################################################ + # simplified mnemonics not handled by at least one assembler +@@ -122,6 +146,46 @@ my $extrdi = sub { + $b = ($b+$n)&63; $n = 64-$n; + " rldicl $ra,$rs,$b,$n"; + }; ++my $vmr = sub { ++ my ($f,$vx,$vy) = @_; ++ " vor $vx,$vy,$vy"; ++}; ++ ++# PowerISA 2.06 stuff ++sub vsxmem_op { ++ my ($f, $vrt, $ra, $rb, $op) = @_; ++ " .long ".sprintf "0x%X",(31<<26)|($vrt<<21)|($ra<<16)|($rb<<11)|($op*2+1); ++} ++# made-up unaligned memory reference AltiVec/VMX instructions ++my $lvx_u = sub { vsxmem_op(@_, 844); }; # lxvd2x ++my $stvx_u = sub { vsxmem_op(@_, 972); }; # stxvd2x ++my $lvdx_u = sub { vsxmem_op(@_, 588); }; # lxsdx ++my $stvdx_u = sub { vsxmem_op(@_, 716); }; # stxsdx ++my $lvx_4w = sub { vsxmem_op(@_, 780); }; # lxvw4x ++my $stvx_4w = sub { vsxmem_op(@_, 908); }; # stxvw4x ++ ++# PowerISA 2.07 stuff ++sub vcrypto_op { ++ my ($f, $vrt, $vra, $vrb, $op) = @_; ++ " .long ".sprintf "0x%X",(4<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|$op; ++} ++my $vcipher = sub { vcrypto_op(@_, 1288); }; ++my $vcipherlast = sub { vcrypto_op(@_, 1289); }; ++my $vncipher = sub { vcrypto_op(@_, 1352); }; ++my $vncipherlast= sub { vcrypto_op(@_, 1353); }; ++my $vsbox = sub { vcrypto_op(@_, 0, 1480); }; ++my $vshasigmad = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1730); }; ++my $vshasigmaw = sub { my ($st,$six)=splice(@_,-2); vcrypto_op(@_, $st<<4|$six, 1666); }; ++my $vpmsumb = sub { vcrypto_op(@_, 1032); }; ++my $vpmsumd = sub { vcrypto_op(@_, 1224); }; ++my $vpmsubh = sub { vcrypto_op(@_, 1096); }; ++my $vpmsumw = sub { vcrypto_op(@_, 1160); }; ++my $vaddudm = sub { vcrypto_op(@_, 192); }; ++ ++my $mtsle = sub { ++ my ($f, $arg) = @_; ++ " .long ".sprintf "0x%X",(31<<26)|($arg<<21)|(147*2); ++}; + + while($line=<>) { + +@@ -138,7 +202,10 @@ while($line=<>) { + { + $line =~ s|(^[\.\w]+)\:\s*||; + my $label = $1; +- printf "%s:",($GLOBALS{$label} or $label) if ($label); ++ if ($label) { ++ printf "%s:",($GLOBALS{$label} or $label); ++ printf "\n.localentry\t$GLOBALS{$label},0" if ($GLOBALS{$label} && $flavour =~ /linux.*64le/); ++ } + } + + { +@@ -147,7 +214,7 @@ while($line=<>) { + my $mnemonic = $2; + my $f = $3; + my $opcode = eval("\$$mnemonic"); +- $line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/); ++ $line =~ s/\b(c?[rf]|v|vs)([0-9]+)\b/$2/g if ($c ne "." and $flavour !~ /osx/); + if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); } + elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; } + } +diff --git a/crypto/ppc_arch.h b/crypto/ppc_arch.h +new file mode 100644 +index 0000000..1192edf +--- /dev/null ++++ b/crypto/ppc_arch.h +@@ -0,0 +1,10 @@ ++#ifndef __PPC_ARCH_H__ ++#define __PPC_ARCH_H__ ++ ++extern unsigned int OPENSSL_ppccap_P; ++ ++#define PPC_FPU64 (1<<0) ++#define PPC_ALTIVEC (1<<1) ++#define PPC_CRYPTO207 (1<<2) ++ ++#endif +diff --git a/crypto/ppccap.c b/crypto/ppccap.c +index f71ba66..13c2ca5 100644 +--- a/crypto/ppccap.c ++++ b/crypto/ppccap.c +@@ -4,13 +4,15 @@ + #include + #include + #include ++#if defined(__linux) || defined(_AIX) ++#include ++#endif + #include + #include + +-#define PPC_FPU64 (1<<0) +-#define PPC_ALTIVEC (1<<1) ++#include "ppc_arch.h" + +-static int OPENSSL_ppccap_P = 0; ++unsigned int OPENSSL_ppccap_P = 0; + + static sigset_t all_masked; + +@@ -22,7 +24,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_U + + if (sizeof(size_t)==4) + { +-#if (defined(__APPLE__) && defined(__MACH__)) ++#if 1 || (defined(__APPLE__) && defined(__MACH__)) + if (num>=8 && (num&3)==0 && (OPENSSL_ppccap_P&PPC_FPU64)) + return bn_mul_mont_fpu64(rp,ap,bp,np,n0,num); + #else +@@ -50,11 +52,28 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_U + } + #endif + ++void sha256_block_p8(void *ctx,const void *inp,size_t len); ++void sha256_block_ppc(void *ctx,const void *inp,size_t len); ++void sha256_block_data_order(void *ctx,const void *inp,size_t len) ++ { ++ OPENSSL_ppccap_P&PPC_CRYPTO207? sha256_block_p8(ctx,inp,len): ++ sha256_block_ppc(ctx,inp,len); ++ } ++ ++void sha512_block_p8(void *ctx,const void *inp,size_t len); ++void sha512_block_ppc(void *ctx,const void *inp,size_t len); ++void sha512_block_data_order(void *ctx,const void *inp,size_t len) ++ { ++ OPENSSL_ppccap_P&PPC_CRYPTO207? sha512_block_p8(ctx,inp,len): ++ sha512_block_ppc(ctx,inp,len); ++ } ++ + static sigjmp_buf ill_jmp; + static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); } + + void OPENSSL_ppc64_probe(void); + void OPENSSL_altivec_probe(void); ++void OPENSSL_crypto207_probe(void); + + void OPENSSL_cpuid_setup(void) + { +@@ -85,12 +104,14 @@ void OPENSSL_cpuid_setup(void) + OPENSSL_ppccap_P = 0; + + #if defined(_AIX) +- if (sizeof(size_t)==4 ++ if (sizeof(size_t)==4) ++ { ++ struct utsname uts; + # if defined(_SC_AIX_KERNEL_BITMODE) +- && sysconf(_SC_AIX_KERNEL_BITMODE)!=64 ++ if (sysconf(_SC_AIX_KERNEL_BITMODE)!=64) return; + # endif +- ) +- return; ++ if (uname(&uts)!=0 || atoi(uts.version)<6) return; ++ } + #endif + + memset(&ill_act,0,sizeof(ill_act)); +@@ -102,6 +123,10 @@ void OPENSSL_cpuid_setup(void) + + if (sizeof(size_t)==4) + { ++#ifdef __linux ++ struct utsname uts; ++ if (uname(&uts)==0 && strcmp(uts.machine,"ppc64")==0) ++#endif + if (sigsetjmp(ill_jmp,1) == 0) + { + OPENSSL_ppc64_probe(); +@@ -119,6 +144,11 @@ void OPENSSL_cpuid_setup(void) + { + OPENSSL_altivec_probe(); + OPENSSL_ppccap_P |= PPC_ALTIVEC; ++ if (sigsetjmp(ill_jmp,1) == 0) ++ { ++ OPENSSL_crypto207_probe(); ++ OPENSSL_ppccap_P |= PPC_CRYPTO207; ++ } + } + + sigaction (SIGILL,&ill_oact,NULL); +diff --git a/crypto/ppccpuid.pl b/crypto/ppccpuid.pl +index 4ba736a..56cc851 100755 +--- a/crypto/ppccpuid.pl ++++ b/crypto/ppccpuid.pl +@@ -31,6 +31,7 @@ $code=<<___; + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size .OPENSSL_ppc64_probe,.-.OPENSSL_ppc64_probe + + .globl .OPENSSL_altivec_probe + .align 4 +@@ -39,6 +40,17 @@ $code=<<___; + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size .OPENSSL_altivec_probe,.-..OPENSSL_altivec_probe ++ ++.globl .OPENSSL_crypto207_probe ++.align 4 ++.OPENSSL_crypto207_probe: ++ lvx_u v0,0,r1 ++ vcipher v0,v0,v0 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++.size .OPENSSL_crypto207_probe,.-.OPENSSL_crypto207_probe + + .globl .OPENSSL_wipe_cpu + .align 4 +@@ -71,6 +83,7 @@ $code=<<___; + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size .OPENSSL_wipe_cpu,.-.OPENSSL_wipe_cpu + + .globl .OPENSSL_atomic_add + .align 4 +@@ -84,6 +97,7 @@ Ladd: lwarx r5,0,r3 + .long 0 + .byte 0,12,0x14,0,0,0,2,0 + .long 0 ++.size .OPENSSL_atomic_add,.-.OPENSSL_atomic_add + + .globl .OPENSSL_rdtsc + .align 4 +@@ -93,6 +107,7 @@ Ladd: lwarx r5,0,r3 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size .OPENSSL_rdtsc,.-.OPENSSL_rdtsc + + .globl .OPENSSL_cleanse + .align 4 +@@ -125,7 +140,99 @@ Laligned: + .long 0 + .byte 0,12,0x14,0,0,0,2,0 + .long 0 ++.size .OPENSSL_cleanse,.-.OPENSSL_cleanse ++___ ++{ ++my ($out,$cnt,$max)=("r3","r4","r5"); ++my ($tick,$lasttick)=("r6","r7"); ++my ($diff,$lastdiff)=("r8","r9"); ++ ++$code.=<<___; ++.globl .OPENSSL_instrument_bus ++.align 4 ++.OPENSSL_instrument_bus: ++ mtctr $cnt ++ ++ mftb $lasttick # collect 1st tick ++ li $diff,0 ++ ++ dcbf 0,$out # flush cache line ++ lwarx $tick,0,$out # load and lock ++ add $tick,$tick,$diff ++ stwcx. $tick,0,$out ++ stwx $tick,0,$out ++ ++Loop: mftb $tick ++ sub $diff,$tick,$lasttick ++ mr $lasttick,$tick ++ dcbf 0,$out # flush cache line ++ lwarx $tick,0,$out # load and lock ++ add $tick,$tick,$diff ++ stwcx. $tick,0,$out ++ stwx $tick,0,$out ++ addi $out,$out,4 # ++$out ++ bdnz Loop ++ ++ mr r3,$cnt ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,2,0 ++ .long 0 ++.size .OPENSSL_instrument_bus,.-.OPENSSL_instrument_bus ++ ++.globl .OPENSSL_instrument_bus2 ++.align 4 ++.OPENSSL_instrument_bus2: ++ mr r0,$cnt ++ slwi $cnt,$cnt,2 ++ ++ mftb $lasttick # collect 1st tick ++ li $diff,0 ++ ++ dcbf 0,$out # flush cache line ++ lwarx $tick,0,$out # load and lock ++ add $tick,$tick,$diff ++ stwcx. $tick,0,$out ++ stwx $tick,0,$out ++ ++ mftb $tick # collect 1st diff ++ sub $diff,$tick,$lasttick ++ mr $lasttick,$tick ++ mr $lastdiff,$diff ++Loop2: ++ dcbf 0,$out # flush cache line ++ lwarx $tick,0,$out # load and lock ++ add $tick,$tick,$diff ++ stwcx. $tick,0,$out ++ stwx $tick,0,$out ++ ++ addic. $max,$max,-1 ++ beq Ldone2 ++ ++ mftb $tick ++ sub $diff,$tick,$lasttick ++ mr $lasttick,$tick ++ cmplw 7,$diff,$lastdiff ++ mr $lastdiff,$diff ++ ++ mfcr $tick # pull cr ++ not $tick,$tick # flip bits ++ rlwinm $tick,$tick,1,29,29 # isolate flipped eq bit and scale ++ ++ sub. $cnt,$cnt,$tick # conditional --$cnt ++ add $out,$out,$tick # conditional ++$out ++ bne Loop2 ++ ++Ldone2: ++ srwi $cnt,$cnt,2 ++ sub r3,r0,$cnt ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,3,0 ++ .long 0 ++.size .OPENSSL_instrument_bus2,.-.OPENSSL_instrument_bus2 + ___ ++} + + $code =~ s/\`([^\`]*)\`/eval $1/gem; + print $code; +diff --git a/crypto/sha/Makefile b/crypto/sha/Makefile +index 6d191d3..58c6705 100644 +--- a/crypto/sha/Makefile ++++ b/crypto/sha/Makefile +@@ -73,6 +73,8 @@ sha512-sparcv9.s:asm/sha512-sparcv9.pl; $(PERL) asm/sha512-sparcv9.pl $@ $(CFLAG + sha1-ppc.s: asm/sha1-ppc.pl; $(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@ + sha256-ppc.s: asm/sha512-ppc.pl; $(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@ + sha512-ppc.s: asm/sha512-ppc.pl; $(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@ ++sha256p8-ppc.s: asm/sha512p8-ppc.pl; $(PERL) asm/sha512p8-ppc.pl $(PERLASM_SCHEME) $@ ++sha512p8-ppc.s: asm/sha512p8-ppc.pl; $(PERL) asm/sha512p8-ppc.pl $(PERLASM_SCHEME) $@ + + sha1-parisc.s: asm/sha1-parisc.pl; $(PERL) asm/sha1-parisc.pl $(PERLASM_SCHEME) $@ + sha256-parisc.s:asm/sha512-parisc.pl; $(PERL) asm/sha512-parisc.pl $(PERLASM_SCHEME) $@ +diff --git a/crypto/sha/asm/sha1-ppc.pl b/crypto/sha/asm/sha1-ppc.pl +index 2140dd2..df59896 100755 +--- a/crypto/sha/asm/sha1-ppc.pl ++++ b/crypto/sha/asm/sha1-ppc.pl +@@ -9,8 +9,7 @@ + + # I let hardware handle unaligned input(*), except on page boundaries + # (see below for details). Otherwise straightforward implementation +-# with X vector in register bank. The module is big-endian [which is +-# not big deal as there're no little-endian targets left around]. ++# with X vector in register bank. + # + # (*) this means that this module is inappropriate for PPC403? Does + # anybody know if pre-POWER3 can sustain unaligned load? +@@ -38,6 +37,10 @@ if ($flavour =~ /64/) { + $PUSH ="stw"; + } else { die "nonsense $flavour"; } + ++# Define endianess based on flavour ++# i.e.: linux64le ++$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0; ++ + $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; + ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or + ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +@@ -68,14 +71,28 @@ $T ="r12"; + @X=("r16","r17","r18","r19","r20","r21","r22","r23", + "r24","r25","r26","r27","r28","r29","r30","r31"); + ++sub loadbe { ++my ($dst, $src, $temp_reg) = @_; ++$code.=<<___ if (!$LITTLE_ENDIAN); ++ lwz $dst,$src ++___ ++$code.=<<___ if ($LITTLE_ENDIAN); ++ lwz $temp_reg,$src ++ rotlwi $dst,$temp_reg,8 ++ rlwimi $dst,$temp_reg,24,0,7 ++ rlwimi $dst,$temp_reg,24,16,23 ++___ ++} ++ + sub BODY_00_19 { + my ($i,$a,$b,$c,$d,$e,$f)=@_; + my $j=$i+1; +-$code.=<<___ if ($i==0); +- lwz @X[$i],`$i*4`($inp) +-___ ++ ++ # Since the last value of $f is discarded, we can use ++ # it as a temp reg to swap byte-order when needed. ++ loadbe("@X[$i]","`$i*4`($inp)",$f) if ($i==0); ++ loadbe("@X[$j]","`$j*4`($inp)",$f) if ($i<15); + $code.=<<___ if ($i<15); +- lwz @X[$j],`$j*4`($inp) + add $f,$K,$e + rotlwi $e,$a,5 + add $f,$f,@X[$i] +@@ -108,31 +125,31 @@ my ($i,$a,$b,$c,$d,$e,$f)=@_; + my $j=$i+1; + $code.=<<___ if ($i<79); + add $f,$K,$e ++ xor $t0,$b,$d + rotlwi $e,$a,5 + xor @X[$j%16],@X[$j%16],@X[($j+2)%16] + add $f,$f,@X[$i%16] +- xor $t0,$b,$c ++ xor $t0,$t0,$c + xor @X[$j%16],@X[$j%16],@X[($j+8)%16] +- add $f,$f,$e ++ add $f,$f,$t0 + rotlwi $b,$b,30 +- xor $t0,$t0,$d + xor @X[$j%16],@X[$j%16],@X[($j+13)%16] +- add $f,$f,$t0 ++ add $f,$f,$e + rotlwi @X[$j%16],@X[$j%16],1 + ___ + $code.=<<___ if ($i==79); + add $f,$K,$e ++ xor $t0,$b,$d + rotlwi $e,$a,5 + lwz r16,0($ctx) + add $f,$f,@X[$i%16] +- xor $t0,$b,$c ++ xor $t0,$t0,$c + lwz r17,4($ctx) +- add $f,$f,$e ++ add $f,$f,$t0 + rotlwi $b,$b,30 + lwz r18,8($ctx) +- xor $t0,$t0,$d + lwz r19,12($ctx) +- add $f,$f,$t0 ++ add $f,$f,$e + lwz r20,16($ctx) + ___ + } +@@ -316,6 +333,7 @@ $code.=<<___; + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size .sha1_block_data_order,.-.sha1_block_data_order + ___ + $code.=<<___; + .asciz "SHA1 block transform for PPC, CRYPTOGAMS by " +diff --git a/crypto/sha/asm/sha512-ppc.pl b/crypto/sha/asm/sha512-ppc.pl +index 6b44a68..734f3c1 100755 +--- a/crypto/sha/asm/sha512-ppc.pl ++++ b/crypto/sha/asm/sha512-ppc.pl +@@ -1,7 +1,7 @@ + #!/usr/bin/env perl + + # ==================================================================== +-# Written by Andy Polyakov for the OpenSSL ++# Written by Andy Polyakov for the OpenSSL + # project. The module is, however, dual licensed under OpenSSL and + # CRYPTOGAMS licenses depending on where you obtain it. For further + # details see http://www.openssl.org/~appro/cryptogams/. +@@ -9,8 +9,7 @@ + + # I let hardware handle unaligned input, except on page boundaries + # (see below for details). Otherwise straightforward implementation +-# with X vector in register bank. The module is big-endian [which is +-# not big deal as there're no little-endian targets left around]. ++# with X vector in register bank. + + # sha256 | sha512 + # -m64 -m32 | -m64 -m32 +@@ -56,6 +55,8 @@ if ($flavour =~ /64/) { + $PUSH="stw"; + } else { die "nonsense $flavour"; } + ++$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0; ++ + $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; + ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or + ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +@@ -64,7 +65,7 @@ die "can't locate ppc-xlate.pl"; + open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; + + if ($output =~ /512/) { +- $func="sha512_block_data_order"; ++ $func="sha512_block_ppc"; + $SZ=8; + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); +@@ -76,7 +77,7 @@ if ($output =~ /512/) { + $ROR="rotrdi"; + $SHR="srdi"; + } else { +- $func="sha256_block_data_order"; ++ $func="sha256_block_ppc"; + $SZ=4; + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); +@@ -110,7 +111,7 @@ $B ="r9"; + $C ="r10"; + $D ="r11"; + $E ="r12"; +-$F ="r13"; $F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer ++$F =$t1; $t1 = "r0"; # stay away from "r13"; + $G ="r14"; + $H ="r15"; + +@@ -118,24 +119,23 @@ $H ="r15"; + @X=("r16","r17","r18","r19","r20","r21","r22","r23", + "r24","r25","r26","r27","r28","r29","r30","r31"); + +-$inp="r31"; # reassigned $inp! aliases with @X[15] ++$inp="r31" if($SZ==4 || $SIZE_T==8); # reassigned $inp! aliases with @X[15] + + sub ROUND_00_15 { + my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; + $code.=<<___; +- $LD $T,`$i*$SZ`($Tbl) + $ROR $a0,$e,$Sigma1[0] + $ROR $a1,$e,$Sigma1[1] + and $t0,$f,$e +- andc $t1,$g,$e +- add $T,$T,$h + xor $a0,$a0,$a1 ++ add $h,$h,$t1 ++ andc $t1,$g,$e + $ROR $a1,$a1,`$Sigma1[2]-$Sigma1[1]` + or $t0,$t0,$t1 ; Ch(e,f,g) +- add $T,$T,@X[$i] ++ add $h,$h,@X[$i%16] + xor $a0,$a0,$a1 ; Sigma1(e) +- add $T,$T,$t0 +- add $T,$T,$a0 ++ add $h,$h,$t0 ++ add $h,$h,$a0 + + $ROR $a0,$a,$Sigma0[0] + $ROR $a1,$a,$Sigma0[1] +@@ -146,9 +146,14 @@ $code.=<<___; + xor $t0,$t0,$t1 + and $t1,$b,$c + xor $a0,$a0,$a1 ; Sigma0(a) +- add $d,$d,$T ++ add $d,$d,$h + xor $t0,$t0,$t1 ; Maj(a,b,c) +- add $h,$T,$a0 ++___ ++$code.=<<___ if ($i<15); ++ $LD $t1,`($i+1)*$SZ`($Tbl) ++___ ++$code.=<<___; ++ add $h,$h,$a0 + add $h,$h,$t0 + + ___ +@@ -169,10 +174,11 @@ $code.=<<___; + add @X[$i],@X[$i],@X[($i+9)%16] + xor $a0,$a0,$a1 ; sigma0(X[(i+1)&0x0f]) + xor $t0,$t0,$t1 ; sigma1(X[(i+14)&0x0f]) ++ $LD $t1,`$i*$SZ`($Tbl) + add @X[$i],@X[$i],$a0 + add @X[$i],@X[$i],$t0 + ___ +-&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h); ++&ROUND_00_15($i+16,$a,$b,$c,$d,$e,$f,$g,$h); + } + + $code=<<___; +@@ -188,8 +194,6 @@ $func: + + $PUSH $ctx,`$FRAME-$SIZE_T*22`($sp) + +- $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) +- $PUSH r13,`$FRAME-$SIZE_T*19`($sp) + $PUSH r14,`$FRAME-$SIZE_T*18`($sp) + $PUSH r15,`$FRAME-$SIZE_T*17`($sp) + $PUSH r16,`$FRAME-$SIZE_T*16`($sp) +@@ -209,7 +213,10 @@ $func: + $PUSH r30,`$FRAME-$SIZE_T*2`($sp) + $PUSH r31,`$FRAME-$SIZE_T*1`($sp) + $PUSH r0,`$FRAME+$LRSAVE`($sp) ++___ + ++if ($SZ==4 || $SIZE_T==8) { ++$code.=<<___; + $LD $A,`0*$SZ`($ctx) + mr $inp,r4 ; incarnate $inp + $LD $B,`1*$SZ`($ctx) +@@ -219,7 +226,16 @@ $func: + $LD $F,`5*$SZ`($ctx) + $LD $G,`6*$SZ`($ctx) + $LD $H,`7*$SZ`($ctx) ++___ ++} else { ++ for ($i=16;$i<32;$i++) { ++ $code.=<<___; ++ lwz r$i,`$LITTLE_ENDIAN^(4*($i-16))`($ctx) ++___ ++ } ++} + ++$code.=<<___; + bl LPICmeup + LPICedup: + andi. r0,$inp,3 +@@ -255,6 +271,9 @@ Lunaligned: + Lcross_page: + li $t1,`16*$SZ/4` + mtctr $t1 ++___ ++if ($SZ==4 || $SIZE_T==8) { ++$code.=<<___; + addi r20,$sp,$LOCALS ; aligned spot below the frame + Lmemcpy: + lbz r16,0($inp) +@@ -268,7 +287,26 @@ Lmemcpy: + stb r19,3(r20) + addi r20,r20,4 + bdnz Lmemcpy ++___ ++} else { ++$code.=<<___; ++ addi r12,$sp,$LOCALS ; aligned spot below the frame ++Lmemcpy: ++ lbz r8,0($inp) ++ lbz r9,1($inp) ++ lbz r10,2($inp) ++ lbz r11,3($inp) ++ addi $inp,$inp,4 ++ stb r8,0(r12) ++ stb r9,1(r12) ++ stb r10,2(r12) ++ stb r11,3(r12) ++ addi r12,r12,4 ++ bdnz Lmemcpy ++___ ++} + ++$code.=<<___; + $PUSH $inp,`$FRAME-$SIZE_T*26`($sp) ; save real inp + addi $t1,$sp,`$LOCALS+16*$SZ` ; fictitious end pointer + addi $inp,$sp,$LOCALS ; fictitious inp pointer +@@ -283,8 +321,6 @@ Lmemcpy: + + Ldone: + $POP r0,`$FRAME+$LRSAVE`($sp) +- $POP $toc,`$FRAME-$SIZE_T*20`($sp) +- $POP r13,`$FRAME-$SIZE_T*19`($sp) + $POP r14,`$FRAME-$SIZE_T*18`($sp) + $POP r15,`$FRAME-$SIZE_T*17`($sp) + $POP r16,`$FRAME-$SIZE_T*16`($sp) +@@ -309,27 +345,48 @@ Ldone: + .long 0 + .byte 0,12,4,1,0x80,18,3,0 + .long 0 ++___ + ++if ($SZ==4 || $SIZE_T==8) { ++$code.=<<___; + .align 4 + Lsha2_block_private: ++ $LD $t1,0($Tbl) + ___ + for($i=0;$i<16;$i++) { +-$code.=<<___ if ($SZ==4); ++$code.=<<___ if ($SZ==4 && !$LITTLE_ENDIAN); + lwz @X[$i],`$i*$SZ`($inp) + ___ ++$code.=<<___ if ($SZ==4 && $LITTLE_ENDIAN); ++ lwz $a0,`$i*$SZ`($inp) ++ rotlwi @X[$i],$a0,8 ++ rlwimi @X[$i],$a0,24,0,7 ++ rlwimi @X[$i],$a0,24,16,23 ++___ + # 64-bit loads are split to 2x32-bit ones, as CPU can't handle + # unaligned 64-bit loads, only 32-bit ones... +-$code.=<<___ if ($SZ==8); ++$code.=<<___ if ($SZ==8 && !$LITTLE_ENDIAN); + lwz $t0,`$i*$SZ`($inp) + lwz @X[$i],`$i*$SZ+4`($inp) + insrdi @X[$i],$t0,32,0 + ___ ++$code.=<<___ if ($SZ==8 && $LITTLE_ENDIAN); ++ lwz $a0,`$i*$SZ`($inp) ++ lwz $a1,`$i*$SZ+4`($inp) ++ rotlwi $t0,$a0,8 ++ rotlwi @X[$i],$a1,8 ++ rlwimi $t0,$a0,24,0,7 ++ rlwimi @X[$i],$a1,24,0,7 ++ rlwimi $t0,$a0,24,16,23 ++ rlwimi @X[$i],$a1,24,16,23 ++ insrdi @X[$i],$t0,32,0 ++___ + &ROUND_00_15($i,@V); + unshift(@V,pop(@V)); + } + $code.=<<___; +- li $T,`$rounds/16-1` +- mtctr $T ++ li $t0,`$rounds/16-1` ++ mtctr $t0 + .align 4 + Lrounds: + addi $Tbl,$Tbl,`16*$SZ` +@@ -377,7 +434,282 @@ $code.=<<___; + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 ++.size $func,.-$func ++___ ++} else { ++######################################################################## ++# SHA512 for PPC32, X vector is off-loaded to stack... ++# ++# | sha512 ++# | -m32 ++# ----------------------+----------------------- ++# PPC74x0,gcc-4.0.1 | +48% ++# POWER6,gcc-4.4.6 | +124%(*) ++# POWER7,gcc-4.4.6 | +79%(*) ++# e300,gcc-4.1.0 | +167% ++# ++# (*) ~1/3 of -m64 result [and ~20% better than -m32 code generated ++# by xlc-12.1] ++ ++my $XOFF=$LOCALS; ++ ++my @V=map("r$_",(16..31)); # A..H ++ ++my ($s0,$s1,$t0,$t1,$t2,$t3,$a0,$a1,$a2,$a3)=map("r$_",(0,5,6,8..12,14,15)); ++my ($x0,$x1)=("r3","r4"); # zaps $ctx and $inp ++ ++sub ROUND_00_15_ppc32 { ++my ($i, $ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo, ++ $ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo)=@_; ++ ++$code.=<<___; ++ lwz $t2,`$SZ*($i%16)+($LITTLE_ENDIAN^4)`($Tbl) ++ xor $a0,$flo,$glo ++ lwz $t3,`$SZ*($i%16)+($LITTLE_ENDIAN^0)`($Tbl) ++ xor $a1,$fhi,$ghi ++ addc $hlo,$hlo,$t0 ; h+=x[i] ++ stw $t0,`$XOFF+0+$SZ*($i%16)`($sp) ; save x[i] ++ ++ srwi $s0,$elo,$Sigma1[0] ++ srwi $s1,$ehi,$Sigma1[0] ++ and $a0,$a0,$elo ++ adde $hhi,$hhi,$t1 ++ and $a1,$a1,$ehi ++ stw $t1,`$XOFF+4+$SZ*($i%16)`($sp) ++ srwi $t0,$elo,$Sigma1[1] ++ srwi $t1,$ehi,$Sigma1[1] ++ addc $hlo,$hlo,$t2 ; h+=K512[i] ++ insrwi $s0,$ehi,$Sigma1[0],0 ++ insrwi $s1,$elo,$Sigma1[0],0 ++ xor $a0,$a0,$glo ; Ch(e,f,g) ++ adde $hhi,$hhi,$t3 ++ xor $a1,$a1,$ghi ++ insrwi $t0,$ehi,$Sigma1[1],0 ++ insrwi $t1,$elo,$Sigma1[1],0 ++ addc $hlo,$hlo,$a0 ; h+=Ch(e,f,g) ++ srwi $t2,$ehi,$Sigma1[2]-32 ++ srwi $t3,$elo,$Sigma1[2]-32 ++ xor $s0,$s0,$t0 ++ xor $s1,$s1,$t1 ++ insrwi $t2,$elo,$Sigma1[2]-32,0 ++ insrwi $t3,$ehi,$Sigma1[2]-32,0 ++ xor $a0,$alo,$blo ; a^b, b^c in next round ++ adde $hhi,$hhi,$a1 ++ xor $a1,$ahi,$bhi ++ xor $s0,$s0,$t2 ; Sigma1(e) ++ xor $s1,$s1,$t3 ++ ++ srwi $t0,$alo,$Sigma0[0] ++ and $a2,$a2,$a0 ++ addc $hlo,$hlo,$s0 ; h+=Sigma1(e) ++ and $a3,$a3,$a1 ++ srwi $t1,$ahi,$Sigma0[0] ++ srwi $s0,$ahi,$Sigma0[1]-32 ++ adde $hhi,$hhi,$s1 ++ srwi $s1,$alo,$Sigma0[1]-32 ++ insrwi $t0,$ahi,$Sigma0[0],0 ++ insrwi $t1,$alo,$Sigma0[0],0 ++ xor $a2,$a2,$blo ; Maj(a,b,c) ++ addc $dlo,$dlo,$hlo ; d+=h ++ xor $a3,$a3,$bhi ++ insrwi $s0,$alo,$Sigma0[1]-32,0 ++ insrwi $s1,$ahi,$Sigma0[1]-32,0 ++ adde $dhi,$dhi,$hhi ++ srwi $t2,$ahi,$Sigma0[2]-32 ++ srwi $t3,$alo,$Sigma0[2]-32 ++ xor $s0,$s0,$t0 ++ addc $hlo,$hlo,$a2 ; h+=Maj(a,b,c) ++ xor $s1,$s1,$t1 ++ insrwi $t2,$alo,$Sigma0[2]-32,0 ++ insrwi $t3,$ahi,$Sigma0[2]-32,0 ++ adde $hhi,$hhi,$a3 ++___ ++$code.=<<___ if ($i>=15); ++ lwz $t0,`$XOFF+0+$SZ*(($i+2)%16)`($sp) ++ lwz $t1,`$XOFF+4+$SZ*(($i+2)%16)`($sp) ++___ ++$code.=<<___ if ($i<15 && !$LITTLE_ENDIAN); ++ lwz $t1,`$SZ*($i+1)+0`($inp) ++ lwz $t0,`$SZ*($i+1)+4`($inp) + ___ ++$code.=<<___ if ($i<15 && $LITTLE_ENDIAN); ++ lwz $a2,`$SZ*($i+1)+0`($inp) ++ lwz $a3,`$SZ*($i+1)+4`($inp) ++ rotlwi $t1,$a2,8 ++ rotlwi $t0,$a3,8 ++ rlwimi $t1,$a2,24,0,7 ++ rlwimi $t0,$a3,24,0,7 ++ rlwimi $t1,$a2,24,16,23 ++ rlwimi $t0,$a3,24,16,23 ++___ ++$code.=<<___; ++ xor $s0,$s0,$t2 ; Sigma0(a) ++ xor $s1,$s1,$t3 ++ addc $hlo,$hlo,$s0 ; h+=Sigma0(a) ++ adde $hhi,$hhi,$s1 ++___ ++$code.=<<___ if ($i==15); ++ lwz $x0,`$XOFF+0+$SZ*(($i+1)%16)`($sp) ++ lwz $x1,`$XOFF+4+$SZ*(($i+1)%16)`($sp) ++___ ++} ++sub ROUND_16_xx_ppc32 { ++my ($i, $ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo, ++ $ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo)=@_; ++ ++$code.=<<___; ++ srwi $s0,$t0,$sigma0[0] ++ srwi $s1,$t1,$sigma0[0] ++ srwi $t2,$t0,$sigma0[1] ++ srwi $t3,$t1,$sigma0[1] ++ insrwi $s0,$t1,$sigma0[0],0 ++ insrwi $s1,$t0,$sigma0[0],0 ++ srwi $a0,$t0,$sigma0[2] ++ insrwi $t2,$t1,$sigma0[1],0 ++ insrwi $t3,$t0,$sigma0[1],0 ++ insrwi $a0,$t1,$sigma0[2],0 ++ xor $s0,$s0,$t2 ++ lwz $t2,`$XOFF+0+$SZ*(($i+14)%16)`($sp) ++ srwi $a1,$t1,$sigma0[2] ++ xor $s1,$s1,$t3 ++ lwz $t3,`$XOFF+4+$SZ*(($i+14)%16)`($sp) ++ xor $a0,$a0,$s0 ++ srwi $s0,$t2,$sigma1[0] ++ xor $a1,$a1,$s1 ++ srwi $s1,$t3,$sigma1[0] ++ addc $x0,$x0,$a0 ; x[i]+=sigma0(x[i+1]) ++ srwi $a0,$t3,$sigma1[1]-32 ++ insrwi $s0,$t3,$sigma1[0],0 ++ insrwi $s1,$t2,$sigma1[0],0 ++ adde $x1,$x1,$a1 ++ srwi $a1,$t2,$sigma1[1]-32 ++ ++ insrwi $a0,$t2,$sigma1[1]-32,0 ++ srwi $t2,$t2,$sigma1[2] ++ insrwi $a1,$t3,$sigma1[1]-32,0 ++ insrwi $t2,$t3,$sigma1[2],0 ++ xor $s0,$s0,$a0 ++ lwz $a0,`$XOFF+0+$SZ*(($i+9)%16)`($sp) ++ srwi $t3,$t3,$sigma1[2] ++ xor $s1,$s1,$a1 ++ lwz $a1,`$XOFF+4+$SZ*(($i+9)%16)`($sp) ++ xor $s0,$s0,$t2 ++ addc $x0,$x0,$a0 ; x[i]+=x[i+9] ++ xor $s1,$s1,$t3 ++ adde $x1,$x1,$a1 ++ addc $x0,$x0,$s0 ; x[i]+=sigma1(x[i+14]) ++ adde $x1,$x1,$s1 ++___ ++ ($t0,$t1,$x0,$x1) = ($x0,$x1,$t0,$t1); ++ &ROUND_00_15_ppc32(@_); ++} ++ ++$code.=<<___; ++.align 4 ++Lsha2_block_private: ++___ ++$code.=<<___ if (!$LITTLE_ENDIAN); ++ lwz $t1,0($inp) ++ xor $a2,@V[3],@V[5] ; B^C, magic seed ++ lwz $t0,4($inp) ++ xor $a3,@V[2],@V[4] ++___ ++$code.=<<___ if ($LITTLE_ENDIAN); ++ lwz $a1,0($inp) ++ xor $a2,@V[3],@V[5] ; B^C, magic seed ++ lwz $a0,4($inp) ++ xor $a3,@V[2],@V[4] ++ rotlwi $t1,$a1,8 ++ rotlwi $t0,$a0,8 ++ rlwimi $t1,$a1,24,0,7 ++ rlwimi $t0,$a0,24,0,7 ++ rlwimi $t1,$a1,24,16,23 ++ rlwimi $t0,$a0,24,16,23 ++___ ++for($i=0;$i<16;$i++) { ++ &ROUND_00_15_ppc32($i,@V); ++ unshift(@V,pop(@V)); unshift(@V,pop(@V)); ++ ($a0,$a1,$a2,$a3) = ($a2,$a3,$a0,$a1); ++} ++$code.=<<___; ++ li $a0,`$rounds/16-1` ++ mtctr $a0 ++.align 4 ++Lrounds: ++ addi $Tbl,$Tbl,`16*$SZ` ++___ ++for(;$i<32;$i++) { ++ &ROUND_16_xx_ppc32($i,@V); ++ unshift(@V,pop(@V)); unshift(@V,pop(@V)); ++ ($a0,$a1,$a2,$a3) = ($a2,$a3,$a0,$a1); ++} ++$code.=<<___; ++ bdnz- Lrounds ++ ++ $POP $ctx,`$FRAME-$SIZE_T*22`($sp) ++ $POP $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer ++ $POP $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer ++ subi $Tbl,$Tbl,`($rounds-16)*$SZ` ; rewind Tbl ++ ++ lwz $t0,`$LITTLE_ENDIAN^0`($ctx) ++ lwz $t1,`$LITTLE_ENDIAN^4`($ctx) ++ lwz $t2,`$LITTLE_ENDIAN^8`($ctx) ++ lwz $t3,`$LITTLE_ENDIAN^12`($ctx) ++ lwz $a0,`$LITTLE_ENDIAN^16`($ctx) ++ lwz $a1,`$LITTLE_ENDIAN^20`($ctx) ++ lwz $a2,`$LITTLE_ENDIAN^24`($ctx) ++ addc @V[1],@V[1],$t1 ++ lwz $a3,`$LITTLE_ENDIAN^28`($ctx) ++ adde @V[0],@V[0],$t0 ++ lwz $t0,`$LITTLE_ENDIAN^32`($ctx) ++ addc @V[3],@V[3],$t3 ++ lwz $t1,`$LITTLE_ENDIAN^36`($ctx) ++ adde @V[2],@V[2],$t2 ++ lwz $t2,`$LITTLE_ENDIAN^40`($ctx) ++ addc @V[5],@V[5],$a1 ++ lwz $t3,`$LITTLE_ENDIAN^44`($ctx) ++ adde @V[4],@V[4],$a0 ++ lwz $a0,`$LITTLE_ENDIAN^48`($ctx) ++ addc @V[7],@V[7],$a3 ++ lwz $a1,`$LITTLE_ENDIAN^52`($ctx) ++ adde @V[6],@V[6],$a2 ++ lwz $a2,`$LITTLE_ENDIAN^56`($ctx) ++ addc @V[9],@V[9],$t1 ++ lwz $a3,`$LITTLE_ENDIAN^60`($ctx) ++ adde @V[8],@V[8],$t0 ++ stw @V[0],`$LITTLE_ENDIAN^0`($ctx) ++ stw @V[1],`$LITTLE_ENDIAN^4`($ctx) ++ addc @V[11],@V[11],$t3 ++ stw @V[2],`$LITTLE_ENDIAN^8`($ctx) ++ stw @V[3],`$LITTLE_ENDIAN^12`($ctx) ++ adde @V[10],@V[10],$t2 ++ stw @V[4],`$LITTLE_ENDIAN^16`($ctx) ++ stw @V[5],`$LITTLE_ENDIAN^20`($ctx) ++ addc @V[13],@V[13],$a1 ++ stw @V[6],`$LITTLE_ENDIAN^24`($ctx) ++ stw @V[7],`$LITTLE_ENDIAN^28`($ctx) ++ adde @V[12],@V[12],$a0 ++ stw @V[8],`$LITTLE_ENDIAN^32`($ctx) ++ stw @V[9],`$LITTLE_ENDIAN^36`($ctx) ++ addc @V[15],@V[15],$a3 ++ stw @V[10],`$LITTLE_ENDIAN^40`($ctx) ++ stw @V[11],`$LITTLE_ENDIAN^44`($ctx) ++ adde @V[14],@V[14],$a2 ++ stw @V[12],`$LITTLE_ENDIAN^48`($ctx) ++ stw @V[13],`$LITTLE_ENDIAN^52`($ctx) ++ stw @V[14],`$LITTLE_ENDIAN^56`($ctx) ++ stw @V[15],`$LITTLE_ENDIAN^60`($ctx) ++ ++ addi $inp,$inp,`16*$SZ` ; advance inp ++ $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ++ $UCMP $inp,$num ++ bne Lsha2_block_private ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++.size $func,.-$func ++___ ++} + + # Ugly hack here, because PPC assembler syntax seem to vary too + # much from platforms to platform... +@@ -395,46 +727,46 @@ LPICmeup: + .space `64-9*4` + ___ + $code.=<<___ if ($SZ==8); +- .long 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd +- .long 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc +- .long 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019 +- .long 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118 +- .long 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe +- .long 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2 +- .long 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1 +- .long 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694 +- .long 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3 +- .long 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65 +- .long 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483 +- .long 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5 +- .long 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210 +- .long 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4 +- .long 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725 +- .long 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70 +- .long 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926 +- .long 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df +- .long 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8 +- .long 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b +- .long 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001 +- .long 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30 +- .long 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910 +- .long 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8 +- .long 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53 +- .long 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8 +- .long 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb +- .long 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3 +- .long 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60 +- .long 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec +- .long 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9 +- .long 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b +- .long 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207 +- .long 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178 +- .long 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6 +- .long 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b +- .long 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493 +- .long 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c +- .long 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a +- .long 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817 ++ .quad 0x428a2f98d728ae22,0x7137449123ef65cd ++ .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc ++ .quad 0x3956c25bf348b538,0x59f111f1b605d019 ++ .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 ++ .quad 0xd807aa98a3030242,0x12835b0145706fbe ++ .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 ++ .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 ++ .quad 0x9bdc06a725c71235,0xc19bf174cf692694 ++ .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 ++ .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 ++ .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 ++ .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 ++ .quad 0x983e5152ee66dfab,0xa831c66d2db43210 ++ .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 ++ .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 ++ .quad 0x06ca6351e003826f,0x142929670a0e6e70 ++ .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 ++ .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df ++ .quad 0x650a73548baf63de,0x766a0abb3c77b2a8 ++ .quad 0x81c2c92e47edaee6,0x92722c851482353b ++ .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 ++ .quad 0xc24b8b70d0f89791,0xc76c51a30654be30 ++ .quad 0xd192e819d6ef5218,0xd69906245565a910 ++ .quad 0xf40e35855771202a,0x106aa07032bbd1b8 ++ .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 ++ .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 ++ .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb ++ .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 ++ .quad 0x748f82ee5defb2fc,0x78a5636f43172f60 ++ .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec ++ .quad 0x90befffa23631e28,0xa4506cebde82bde9 ++ .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b ++ .quad 0xca273eceea26619c,0xd186b8c721c0c207 ++ .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 ++ .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 ++ .quad 0x113f9804bef90dae,0x1b710b35131c471b ++ .quad 0x28db77f523047d84,0x32caab7b40c72493 ++ .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c ++ .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a ++ .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 + ___ + $code.=<<___ if ($SZ==4); + .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +diff --git a/crypto/sha/asm/sha512p8-ppc.pl b/crypto/sha/asm/sha512p8-ppc.pl +new file mode 100755 +index 0000000..a316b31 +--- /dev/null ++++ b/crypto/sha/asm/sha512p8-ppc.pl +@@ -0,0 +1,423 @@ ++#!/usr/bin/env perl ++ ++# ==================================================================== ++# Written by Andy Polyakov for the OpenSSL ++# project. The module is, however, dual licensed under OpenSSL and ++# CRYPTOGAMS licenses depending on where you obtain it. For further ++# details see http://www.openssl.org/~appro/cryptogams/. ++# ==================================================================== ++ ++# SHA256/512 for PowerISA v2.07. ++# ++# Accurate performance measurements are problematic, because it's ++# always virtualized setup with possibly throttled processor. ++# Relative comparison is therefore more informative. This module is ++# ~60% faster than integer-only sha512-ppc.pl. To anchor to something ++# else, SHA256 is 24% slower than sha1-ppc.pl and 2.5x slower than ++# hardware-assisted aes-128-cbc encrypt. SHA512 is 20% faster than ++# sha1-ppc.pl and 1.6x slower than aes-128-cbc. Another interesting ++# result is degree of computational resources' utilization. POWER8 is ++# "massively multi-threaded chip" and difference between single- and ++# maximum multi-process benchmark results tells that utlization is ++# whooping 94%. For sha512-ppc.pl we get [not unimpressive] 84% and ++# for sha1-ppc.pl - 73%. 100% means that multi-process result equals ++# to single-process one, given that all threads end up on the same ++# physical core. ++ ++$flavour=shift; ++$output =shift; ++ ++if ($flavour =~ /64/) { ++ $SIZE_T=8; ++ $LRSAVE=2*$SIZE_T; ++ $STU="stdu"; ++ $POP="ld"; ++ $PUSH="std"; ++} elsif ($flavour =~ /32/) { ++ $SIZE_T=4; ++ $LRSAVE=$SIZE_T; ++ $STU="stwu"; ++ $POP="lwz"; ++ $PUSH="stw"; ++} else { die "nonsense $flavour"; } ++ ++$LENDIAN=($flavour=~/le/); ++ ++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ++( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ++( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or ++die "can't locate ppc-xlate.pl"; ++ ++open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; ++ ++if ($output =~ /512/) { ++ $bits=512; ++ $SZ=8; ++ $sz="d"; ++ $rounds=80; ++} else { ++ $bits=256; ++ $SZ=4; ++ $sz="w"; ++ $rounds=64; ++} ++ ++$func="sha${bits}_block_p8"; ++$FRAME=8*$SIZE_T; ++ ++$sp ="r1"; ++$toc="r2"; ++$ctx="r3"; ++$inp="r4"; ++$num="r5"; ++$Tbl="r6"; ++$idx="r7"; ++$lrsave="r8"; ++$offload="r11"; ++$vrsave="r12"; ++($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,10,26..31)); ++ ++@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("v$_",(0..7)); ++@X=map("v$_",(8..23)); ++($Ki,$Func,$S0,$S1,$s0,$s1,$lemask)=map("v$_",(24..31)); ++ ++sub ROUND { ++my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; ++my $j=($i+1)%16; ++ ++$code.=<<___ if ($i<15 && ($i%(16/$SZ))==(16/$SZ-1)); ++ lvx_u @X[$i+1],0,$inp ; load X[i] in advance ++ addi $inp,$inp,16 ++___ ++$code.=<<___ if ($i<16 && ($i%(16/$SZ))); ++ vsldoi @X[$i],@X[$i-1],@X[$i-1],$SZ ++___ ++$code.=<<___ if ($LENDIAN && $i<16 && ($i%(16/$SZ))==0); ++ vperm @X[$i],@X[$i],@X[$i],$lemask ++___ ++$code.=<<___; ++ `"vshasigma${sz} $s0,@X[($j+1)%16],0,0" if ($i>=15)` ++ vsel $Func,$g,$f,$e ; Ch(e,f,g) ++ vshasigma${sz} $S1,$e,1,15 ; Sigma1(e) ++ vaddu${sz}m $h,$h,@X[$i%16] ; h+=X[i] ++ vshasigma${sz} $S0,$a,1,0 ; Sigma0(a) ++ `"vshasigma${sz} $s1,@X[($j+14)%16],0,15" if ($i>=15)` ++ vaddu${sz}m $h,$h,$Func ; h+=Ch(e,f,g) ++ vxor $Func,$a,$b ++ `"vaddu${sz}m @X[$j],@X[$j],@X[($j+9)%16]" if ($i>=15)` ++ vaddu${sz}m $h,$h,$S1 ; h+=Sigma1(e) ++ vsel $Func,$b,$c,$Func ; Maj(a,b,c) ++ vaddu${sz}m $g,$g,$Ki ; future h+=K[i] ++ vaddu${sz}m $d,$d,$h ; d+=h ++ vaddu${sz}m $S0,$S0,$Func ; Sigma0(a)+Maj(a,b,c) ++ `"vaddu${sz}m @X[$j],@X[$j],$s0" if ($i>=15)` ++ lvx $Ki,$idx,$Tbl ; load next K[i] ++ addi $idx,$idx,16 ++ vaddu${sz}m $h,$h,$S0 ; h+=Sigma0(a)+Maj(a,b,c) ++ `"vaddu${sz}m @X[$j],@X[$j],$s1" if ($i>=15)` ++___ ++} ++ ++$code=<<___; ++.machine "any" ++.text ++ ++.globl $func ++.align 6 ++$func: ++ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp) ++ mflr $lrsave ++ li r10,`$FRAME+8*16+15` ++ li r11,`$FRAME+8*16+31` ++ stvx v20,r10,$sp # ABI says so ++ addi r10,r10,32 ++ mfspr $vrsave,256 ++ stvx v21,r11,$sp ++ addi r11,r11,32 ++ stvx v22,r10,$sp ++ addi r10,r10,32 ++ stvx v23,r11,$sp ++ addi r11,r11,32 ++ stvx v24,r10,$sp ++ addi r10,r10,32 ++ stvx v25,r11,$sp ++ addi r11,r11,32 ++ stvx v26,r10,$sp ++ addi r10,r10,32 ++ stvx v27,r11,$sp ++ addi r11,r11,32 ++ stvx v28,r10,$sp ++ addi r10,r10,32 ++ stvx v29,r11,$sp ++ addi r11,r11,32 ++ stvx v30,r10,$sp ++ stvx v31,r11,$sp ++ li r11,-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 ++ $PUSH $lrsave,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp) ++ mtspr 256,r11 ++ ++ bl LPICmeup ++ addi $offload,$sp,$FRAME+15 ++___ ++$code.=<<___ if ($LENDIAN); ++ li $idx,8 ++ lvsl $lemask,0,$idx ++ vspltisb $Ki,0x0f ++ vxor $lemask,$lemask,$Ki ++___ ++$code.=<<___ if ($SZ==4); ++ lvx_4w $A,$x00,$ctx ++ lvx_4w $E,$x10,$ctx ++ vsldoi $B,$A,$A,4 # unpack ++ vsldoi $C,$A,$A,8 ++ vsldoi $D,$A,$A,12 ++ vsldoi $F,$E,$E,4 ++ vsldoi $G,$E,$E,8 ++ vsldoi $H,$E,$E,12 ++___ ++$code.=<<___ if ($SZ==8); ++ lvx_u $A,$x00,$ctx ++ lvx_u $C,$x10,$ctx ++ lvx_u $E,$x20,$ctx ++ vsldoi $B,$A,$A,8 # unpack ++ lvx_u $G,$x30,$ctx ++ vsldoi $D,$C,$C,8 ++ vsldoi $F,$E,$E,8 ++ vsldoi $H,$G,$G,8 ++___ ++$code.=<<___; ++ li r0,`($rounds-16)/16` # inner loop counter ++ b Loop ++.align 5 ++Loop: ++ lvx $Ki,$x00,$Tbl ++ li $idx,16 ++ lvx_u @X[0],0,$inp ++ addi $inp,$inp,16 ++ stvx $A,$x00,$offload # offload $A-$H ++ stvx $B,$x10,$offload ++ stvx $C,$x20,$offload ++ stvx $D,$x30,$offload ++ stvx $E,$x40,$offload ++ stvx $F,$x50,$offload ++ stvx $G,$x60,$offload ++ stvx $H,$x70,$offload ++ vaddu${sz}m $H,$H,$Ki # h+K[i] ++ lvx $Ki,$idx,$Tbl ++ addi $idx,$idx,16 ++___ ++for ($i=0;$i<16;$i++) { &ROUND($i,@V); unshift(@V,pop(@V)); } ++$code.=<<___; ++ mtctr r0 ++ b L16_xx ++.align 5 ++L16_xx: ++___ ++for (;$i<32;$i++) { &ROUND($i,@V); unshift(@V,pop(@V)); } ++$code.=<<___; ++ bdnz L16_xx ++ ++ lvx @X[2],$x00,$offload ++ subic. $num,$num,1 ++ lvx @X[3],$x10,$offload ++ vaddu${sz}m $A,$A,@X[2] ++ lvx @X[4],$x20,$offload ++ vaddu${sz}m $B,$B,@X[3] ++ lvx @X[5],$x30,$offload ++ vaddu${sz}m $C,$C,@X[4] ++ lvx @X[6],$x40,$offload ++ vaddu${sz}m $D,$D,@X[5] ++ lvx @X[7],$x50,$offload ++ vaddu${sz}m $E,$E,@X[6] ++ lvx @X[8],$x60,$offload ++ vaddu${sz}m $F,$F,@X[7] ++ lvx @X[9],$x70,$offload ++ vaddu${sz}m $G,$G,@X[8] ++ vaddu${sz}m $H,$H,@X[9] ++ bne Loop ++___ ++$code.=<<___ if ($SZ==4); ++ lvx @X[0],$idx,$Tbl ++ addi $idx,$idx,16 ++ vperm $A,$A,$B,$Ki # pack the answer ++ lvx @X[1],$idx,$Tbl ++ vperm $E,$E,$F,$Ki ++ vperm $A,$A,$C,@X[0] ++ vperm $E,$E,$G,@X[0] ++ vperm $A,$A,$D,@X[1] ++ vperm $E,$E,$H,@X[1] ++ stvx_4w $A,$x00,$ctx ++ stvx_4w $E,$x10,$ctx ++___ ++$code.=<<___ if ($SZ==8); ++ vperm $A,$A,$B,$Ki # pack the answer ++ vperm $C,$C,$D,$Ki ++ vperm $E,$E,$F,$Ki ++ vperm $G,$G,$H,$Ki ++ stvx_u $A,$x00,$ctx ++ stvx_u $C,$x10,$ctx ++ stvx_u $E,$x20,$ctx ++ stvx_u $G,$x30,$ctx ++___ ++$code.=<<___; ++ li r10,`$FRAME+8*16+15` ++ mtlr $lrsave ++ li r11,`$FRAME+8*16+31` ++ 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,4,1,0x80,6,3,0 ++ .long 0 ++.size $func,.-$func ++___ ++ ++# Ugly hack here, because PPC assembler syntax seem to vary too ++# much from platforms to platform... ++$code.=<<___; ++.align 6 ++LPICmeup: ++ mflr r0 ++ bcl 20,31,\$+4 ++ mflr $Tbl ; vvvvvv "distance" between . and 1st data entry ++ addi $Tbl,$Tbl,`64-8` ++ mtlr r0 ++ blr ++ .long 0 ++ .byte 0,12,0x14,0,0,0,0,0 ++ .space `64-9*4` ++___ ++ ++if ($SZ==8) { ++ local *table = sub { ++ foreach(@_) { $code.=".quad $_,$_\n"; } ++ }; ++ table( ++ "0x428a2f98d728ae22","0x7137449123ef65cd", ++ "0xb5c0fbcfec4d3b2f","0xe9b5dba58189dbbc", ++ "0x3956c25bf348b538","0x59f111f1b605d019", ++ "0x923f82a4af194f9b","0xab1c5ed5da6d8118", ++ "0xd807aa98a3030242","0x12835b0145706fbe", ++ "0x243185be4ee4b28c","0x550c7dc3d5ffb4e2", ++ "0x72be5d74f27b896f","0x80deb1fe3b1696b1", ++ "0x9bdc06a725c71235","0xc19bf174cf692694", ++ "0xe49b69c19ef14ad2","0xefbe4786384f25e3", ++ "0x0fc19dc68b8cd5b5","0x240ca1cc77ac9c65", ++ "0x2de92c6f592b0275","0x4a7484aa6ea6e483", ++ "0x5cb0a9dcbd41fbd4","0x76f988da831153b5", ++ "0x983e5152ee66dfab","0xa831c66d2db43210", ++ "0xb00327c898fb213f","0xbf597fc7beef0ee4", ++ "0xc6e00bf33da88fc2","0xd5a79147930aa725", ++ "0x06ca6351e003826f","0x142929670a0e6e70", ++ "0x27b70a8546d22ffc","0x2e1b21385c26c926", ++ "0x4d2c6dfc5ac42aed","0x53380d139d95b3df", ++ "0x650a73548baf63de","0x766a0abb3c77b2a8", ++ "0x81c2c92e47edaee6","0x92722c851482353b", ++ "0xa2bfe8a14cf10364","0xa81a664bbc423001", ++ "0xc24b8b70d0f89791","0xc76c51a30654be30", ++ "0xd192e819d6ef5218","0xd69906245565a910", ++ "0xf40e35855771202a","0x106aa07032bbd1b8", ++ "0x19a4c116b8d2d0c8","0x1e376c085141ab53", ++ "0x2748774cdf8eeb99","0x34b0bcb5e19b48a8", ++ "0x391c0cb3c5c95a63","0x4ed8aa4ae3418acb", ++ "0x5b9cca4f7763e373","0x682e6ff3d6b2b8a3", ++ "0x748f82ee5defb2fc","0x78a5636f43172f60", ++ "0x84c87814a1f0ab72","0x8cc702081a6439ec", ++ "0x90befffa23631e28","0xa4506cebde82bde9", ++ "0xbef9a3f7b2c67915","0xc67178f2e372532b", ++ "0xca273eceea26619c","0xd186b8c721c0c207", ++ "0xeada7dd6cde0eb1e","0xf57d4f7fee6ed178", ++ "0x06f067aa72176fba","0x0a637dc5a2c898a6", ++ "0x113f9804bef90dae","0x1b710b35131c471b", ++ "0x28db77f523047d84","0x32caab7b40c72493", ++ "0x3c9ebe0a15c9bebc","0x431d67c49c100d4c", ++ "0x4cc5d4becb3e42b6","0x597f299cfc657e2a", ++ "0x5fcb6fab3ad6faec","0x6c44198c4a475817","0"); ++$code.=<<___ if (!$LENDIAN); ++.quad 0x0001020304050607,0x1011121314151617 ++___ ++$code.=<<___ if ($LENDIAN); # quad-swapped ++.quad 0x1011121314151617,0x0001020304050607 ++___ ++} else { ++ local *table = sub { ++ foreach(@_) { $code.=".long $_,$_,$_,$_\n"; } ++ }; ++ table( ++ "0x428a2f98","0x71374491","0xb5c0fbcf","0xe9b5dba5", ++ "0x3956c25b","0x59f111f1","0x923f82a4","0xab1c5ed5", ++ "0xd807aa98","0x12835b01","0x243185be","0x550c7dc3", ++ "0x72be5d74","0x80deb1fe","0x9bdc06a7","0xc19bf174", ++ "0xe49b69c1","0xefbe4786","0x0fc19dc6","0x240ca1cc", ++ "0x2de92c6f","0x4a7484aa","0x5cb0a9dc","0x76f988da", ++ "0x983e5152","0xa831c66d","0xb00327c8","0xbf597fc7", ++ "0xc6e00bf3","0xd5a79147","0x06ca6351","0x14292967", ++ "0x27b70a85","0x2e1b2138","0x4d2c6dfc","0x53380d13", ++ "0x650a7354","0x766a0abb","0x81c2c92e","0x92722c85", ++ "0xa2bfe8a1","0xa81a664b","0xc24b8b70","0xc76c51a3", ++ "0xd192e819","0xd6990624","0xf40e3585","0x106aa070", ++ "0x19a4c116","0x1e376c08","0x2748774c","0x34b0bcb5", ++ "0x391c0cb3","0x4ed8aa4a","0x5b9cca4f","0x682e6ff3", ++ "0x748f82ee","0x78a5636f","0x84c87814","0x8cc70208", ++ "0x90befffa","0xa4506ceb","0xbef9a3f7","0xc67178f2","0"); ++$code.=<<___ if (!$LENDIAN); ++.long 0x00010203,0x10111213,0x10111213,0x10111213 ++.long 0x00010203,0x04050607,0x10111213,0x10111213 ++.long 0x00010203,0x04050607,0x08090a0b,0x10111213 ++___ ++$code.=<<___ if ($LENDIAN); # word-swapped ++.long 0x10111213,0x10111213,0x10111213,0x00010203 ++.long 0x10111213,0x10111213,0x04050607,0x00010203 ++.long 0x10111213,0x08090a0b,0x04050607,0x00010203 ++___ ++} ++$code.=<<___; ++.asciz "SHA${bits} for PowerISA 2.07, CRYPTOGAMS by " ++.align 2 ++___ ++ ++$code =~ s/\`([^\`]*)\`/eval $1/gem; ++print $code; ++close STDOUT; diff --git a/SOURCES/openssl-1.0.1e-req-keylen.patch b/SOURCES/openssl-1.0.1e-req-keylen.patch new file mode 100755 index 00000000..1574bb85 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-req-keylen.patch @@ -0,0 +1,38 @@ +diff -up openssl-1.0.1e/apps/req.c.keylen openssl-1.0.1e/apps/req.c +--- openssl-1.0.1e/apps/req.c.keylen 2014-02-12 14:58:29.000000000 +0100 ++++ openssl-1.0.1e/apps/req.c 2014-02-14 13:52:48.692325000 +0100 +@@ -644,6 +644,12 @@ bad: + if (inrand) + app_RAND_load_files(inrand); + ++ if (newkey <= 0) ++ { ++ if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey)) ++ newkey=DEFAULT_KEY_LENGTH; ++ } ++ + if (keyalg) + { + genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey, +@@ -651,12 +657,6 @@ bad: + if (!genctx) + goto end; + } +- +- if (newkey <= 0) +- { +- if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey)) +- newkey=DEFAULT_KEY_LENGTH; +- } + + if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) + { +@@ -1649,6 +1649,8 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO + keylen = atol(p + 1); + *pkeylen = keylen; + } ++ else ++ keylen = *pkeylen; + } + else if (p) + paramfile = p + 1; diff --git a/SOURCES/openssl-1.0.1e-rpmbuild.patch b/SOURCES/openssl-1.0.1e-rpmbuild.patch new file mode 100755 index 00000000..14b2ba91 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-rpmbuild.patch @@ -0,0 +1,112 @@ +diff -up openssl-1.0.1e/Configure.rpmbuild openssl-1.0.1e/Configure +--- openssl-1.0.1e/Configure.rpmbuild 2014-08-13 19:19:53.211005598 +0200 ++++ openssl-1.0.1e/Configure 2014-08-13 19:29:21.704099285 +0200 +@@ -345,24 +345,24 @@ my %table=( + #### + # *-generic* is endian-neutral target, but ./config is free to + # throw in -D[BL]_ENDIAN, whichever appropriate... +-"linux-generic32","gcc:-DTERMIO -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 -DTERMIO -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:-DTERMIO -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 -DTERMIO -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)", + # It's believed that majority of ARM toolchains predefine appropriate -march. + # If you compiler does not, do complement config command line with one! +-"linux-armv4", "gcc:-DTERMIO -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-armv4", "gcc:-DTERMIO -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)", + #### IA-32 targets... + "linux-ia32-icc", "icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl: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 -DTERMIO -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 -DTERMIO -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 -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out", + #### +-"linux-generic64","gcc:-DTERMIO -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 -DTERMIO -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 -DTERMIO -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:-DTERMIO -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)", ++"linux-ppc64", "gcc:-m64 -DB_ENDIAN -DTERMIO -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 -DTERMIO -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 -DTERMIO -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-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", + "linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl: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 -DTERMIO -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", +-"linux64-s390x", "gcc:-m64 -DB_ENDIAN -DTERMIO -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", ++"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -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", ++"linux64-s390x", "gcc:-m64 -DB_ENDIAN -DTERMIO -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 +@@ -376,16 +376,17 @@ my %table=( + # ldconfig and run-time linker to autodiscover. Unfortunately it + # doesn't work just yet, because of couple of bugs in glibc + # sysdeps/s390/dl-procinfo.c affecting ldconfig and ld.so.1... +-"linux32-s390x", "gcc:-m31 -Wa,-mzarch -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$s390x_asm;$asm=~s/bn\-s390x\.o/bn_asm.o/;$asm}.":31:dlfcn:linux-shared:-fPIC:-m31:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/highgprs", ++"linux32-s390x", "gcc:-m31 -Wa,-mzarch -DB_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$s390x_asm;$asm=~s/bn\-s390x\.o/bn_asm.o/;$asm}.":31:dlfcn:linux-shared:-fPIC:-m31 \$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::/highgprs", + #### SPARC Linux setups + # Ray Miller has patiently + # assisted with debugging of following two configs. +-"linux-sparcv8","gcc:-mv8 -DB_ENDIAN -DTERMIO -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:-DB_ENDIAN -DTERMIO -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 -DTERMIO -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:-DB_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS) -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:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + # GCC 3.1 is a requirement +-"linux64-sparcv9","gcc:-m64 -mcpu=ultrasparc -DB_ENDIAN -DTERMIO -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:-DB_ENDIAN -DTERMIO -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:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER):::64", ++"linux-aarch64","gcc:-DL_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-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", + #### 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 +@@ -399,8 +400,8 @@ my %table=( + # + # + # +-"linux-alpha-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +-"linux-alpha+bwx-gcc","gcc:-O3 -DL_ENDIAN -DTERMIO::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-alpha-gcc","gcc:-DL_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", ++"linux-alpha+bwx-gcc","gcc:-DL_ENDIAN -DTERMIO -Wall \$(RPM_OPT_FLAGS)::-D_REENTRANT::-Wl,-z,relro -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC:\$(RPM_OPT_FLAGS):.so.\$(SHLIB_SONAMEVER)", + "linux-alpha-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}", + "linux-alpha+bwx-ccc","ccc:-fast -readonly_strings -DL_ENDIAN -DTERMIO::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}", + +@@ -1675,7 +1676,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.1e/Makefile.org.rpmbuild openssl-1.0.1e/Makefile.org +--- openssl-1.0.1e/Makefile.org.rpmbuild 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/Makefile.org 2014-08-13 19:19:53.218005759 +0200 +@@ -10,6 +10,7 @@ SHLIB_VERSION_HISTORY= + SHLIB_MAJOR= + SHLIB_MINOR= + SHLIB_EXT= ++SHLIB_SONAMEVER=10 + PLATFORM=dist + OPTIONS= + CONFIGURE_ARGS= +@@ -333,10 +334,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 +@@ -347,7 +347,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.1e-secure-getenv.patch b/SOURCES/openssl-1.0.1e-secure-getenv.patch new file mode 100755 index 00000000..eb8034d9 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-secure-getenv.patch @@ -0,0 +1,244 @@ +diff -up openssl-1.0.1e/crypto/conf/conf_api.c.secure-getenv openssl-1.0.1e/crypto/conf/conf_api.c +--- openssl-1.0.1e/crypto/conf/conf_api.c.secure-getenv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/conf/conf_api.c 2013-02-19 13:02:02.531188124 +0100 +@@ -63,6 +63,8 @@ + # define NDEBUG + #endif + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -142,7 +144,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); + } + } +@@ -155,7 +157,7 @@ char *_CONF_get_string(const CONF *conf, + return(NULL); + } + else +- return(getenv(name)); ++ return (secure_getenv(name)); + } + + #if 0 /* There's no way to provide error checking with this function, so +diff -up openssl-1.0.1e/crypto/conf/conf_mod.c.secure-getenv openssl-1.0.1e/crypto/conf/conf_mod.c +--- openssl-1.0.1e/crypto/conf/conf_mod.c.secure-getenv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/conf/conf_mod.c 2013-02-19 13:02:02.531188124 +0100 +@@ -56,6 +56,8 @@ + * + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -548,8 +550,8 @@ char *CONF_get1_default_config_file(void + char *file; + int len; + +- file = getenv("OPENSSL_CONF"); +- if (file) ++ file = secure_getenv("OPENSSL_CONF"); ++ if (file) + return BUF_strdup(file); + + len = strlen(X509_get_default_cert_area()); +diff -up openssl-1.0.1e/crypto/engine/eng_list.c.secure-getenv openssl-1.0.1e/crypto/engine/eng_list.c +--- openssl-1.0.1e/crypto/engine/eng_list.c.secure-getenv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/engine/eng_list.c 2013-02-19 13:02:02.536188233 +0100 +@@ -61,6 +61,8 @@ + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include "eng_int.h" + + /* The linked-list of pointers to engine types. engine_list_head +@@ -399,9 +401,9 @@ ENGINE *ENGINE_by_id(const char *id) + if (strcmp(id, "dynamic")) + { + #ifdef OPENSSL_SYS_VMS +- if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]"; ++ if(OPENSSL_issetugid() || (load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]"; + #else +- if((load_dir = getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR; ++ if((load_dir = secure_getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR; + #endif + iterator = ENGINE_by_id("dynamic"); + if(!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) || +diff -up openssl-1.0.1e/crypto/md5/md5_dgst.c.secure-getenv openssl-1.0.1e/crypto/md5/md5_dgst.c +--- openssl-1.0.1e/crypto/md5/md5_dgst.c.secure-getenv 2013-02-19 13:02:02.492187275 +0100 ++++ openssl-1.0.1e/crypto/md5/md5_dgst.c 2013-02-19 13:02:02.537188254 +0100 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include "md5_locl.h" + #include +@@ -74,7 +76,7 @@ const char MD5_version[]="MD5" OPENSSL_V + 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.1e/crypto/o_init.c.secure-getenv openssl-1.0.1e/crypto/o_init.c +--- openssl-1.0.1e/crypto/o_init.c.secure-getenv 2013-02-19 13:02:02.428185882 +0100 ++++ openssl-1.0.1e/crypto/o_init.c 2013-02-19 13:02:02.538188276 +0100 +@@ -52,6 +52,8 @@ + * + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #ifdef OPENSSL_FIPS +@@ -71,7 +73,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'; + } +diff -up openssl-1.0.1e/crypto/rand/randfile.c.secure-getenv openssl-1.0.1e/crypto/rand/randfile.c +--- openssl-1.0.1e/crypto/rand/randfile.c.secure-getenv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/rand/randfile.c 2013-02-19 13:03:06.971591052 +0100 +@@ -60,6 +60,8 @@ + #if !defined(OPENSSL_SYS_VXWORKS) + #define _XOPEN_SOURCE 500 + #endif ++/* for secure_getenv */ ++#define _GNU_SOURCE + + #include + #include +@@ -277,8 +279,7 @@ 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) +@@ -286,8 +287,7 @@ const char *RAND_file_name(char *buf, si + } + else + { +- if (OPENSSL_issetugid() == 0) +- s=getenv("HOME"); ++ s=secure_getenv("HOME"); + #ifdef DEFAULT_HOME + if (s == NULL) + { +diff -up openssl-1.0.1e/crypto/x509/by_dir.c.secure-getenv openssl-1.0.1e/crypto/x509/by_dir.c +--- openssl-1.0.1e/crypto/x509/by_dir.c.secure-getenv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/x509/by_dir.c 2013-02-19 13:02:02.539188298 +0100 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -135,7 +137,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, in + 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.1e/crypto/x509/by_file.c.secure-getenv openssl-1.0.1e/crypto/x509/by_file.c +--- openssl-1.0.1e/crypto/x509/by_file.c.secure-getenv 2013-02-19 13:02:02.236181701 +0100 ++++ openssl-1.0.1e/crypto/x509/by_file.c 2013-02-19 13:02:02.554188624 +0100 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -100,7 +102,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx + 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.1e/crypto/x509/x509_vfy.c.secure-getenv openssl-1.0.1e/crypto/x509/x509_vfy.c +--- openssl-1.0.1e/crypto/x509/x509_vfy.c.secure-getenv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/crypto/x509/x509_vfy.c 2013-02-19 13:02:02.556188668 +0100 +@@ -56,6 +56,8 @@ + * [including the GNU Public Licence.] + */ + ++/* for secure_getenv */ ++#define _GNU_SOURCE + #include + #include + #include +@@ -481,7 +483,7 @@ static int check_chain_extensions(X509_S + !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + /* 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.1e/engines/ccgost/gost_ctl.c.secure-getenv openssl-1.0.1e/engines/ccgost/gost_ctl.c +--- openssl-1.0.1e/engines/ccgost/gost_ctl.c.secure-getenv 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/engines/ccgost/gost_ctl.c 2013-02-19 13:02:02.557188690 +0100 +@@ -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 +@@ -65,7 +67,7 @@ const char *get_gost_engine_param(int pa + { + 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 * */ + if (!tmp) tmp=value; + if (gost_params[param]) OPENSSL_free(gost_params[param]); diff --git a/SOURCES/openssl-1.0.1e-sn-case.patch b/SOURCES/openssl-1.0.1e-sn-case.patch new file mode 100755 index 00000000..eb5955a3 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-sn-case.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1e/apps/s_server.c.sn-case openssl-1.0.1e/apps/s_server.c +--- openssl-1.0.1e/apps/s_server.c.sn-case 2014-09-17 15:31:51.000000000 +0200 ++++ openssl-1.0.1e/apps/s_server.c 2014-09-17 15:43:04.619321492 +0200 +@@ -744,7 +744,7 @@ static int MS_CALLBACK ssl_servername_cb + + if (servername) + { +- if (strcmp(servername,p->servername)) ++ if (strcasecmp(servername,p->servername)) + return p->extension_error; + if (ctx2) + { diff --git a/SOURCES/openssl-1.0.1e-ssl2-no-ec.patch b/SOURCES/openssl-1.0.1e-ssl2-no-ec.patch new file mode 100755 index 00000000..81ad4722 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-ssl2-no-ec.patch @@ -0,0 +1,17 @@ +diff -up openssl-1.0.1e/ssl/s23_lib.c.ssl2noec openssl-1.0.1e/ssl/s23_lib.c +--- openssl-1.0.1e/ssl/s23_lib.c.ssl2noec 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/ssl/s23_lib.c 2014-05-06 15:51:54.053293674 +0200 +@@ -107,6 +107,13 @@ int ssl23_put_cipher_by_char(const SSL_C + long l; + + /* We can write SSLv2 and SSLv3 ciphers */ ++ /* but no ECC ciphers */ ++ if (c->algorithm_mkey == SSL_kECDHr || ++ c->algorithm_mkey == SSL_kECDHe || ++ c->algorithm_mkey == SSL_kEECDH || ++ c->algorithm_auth == SSL_aECDH || ++ c->algorithm_auth == SSL_aECDSA) ++ return 0; + if (p != NULL) + { + l=c->id; diff --git a/SOURCES/openssl-1.0.1e-trusted-first.patch b/SOURCES/openssl-1.0.1e-trusted-first.patch new file mode 100755 index 00000000..08ab639d --- /dev/null +++ b/SOURCES/openssl-1.0.1e-trusted-first.patch @@ -0,0 +1,330 @@ +diff -up openssl-1.0.1e/apps/apps.c.trusted-first openssl-1.0.1e/apps/apps.c +--- openssl-1.0.1e/apps/apps.c.trusted-first 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/apps.c 2013-08-16 15:42:39.920534769 +0200 +@@ -2361,6 +2361,8 @@ int args_verify(char ***pargs, int *parg + flags |= X509_V_FLAG_NOTIFY_POLICY; + else if (!strcmp(arg, "-check_ss_sig")) + flags |= X509_V_FLAG_CHECK_SS_SIGNATURE; ++ else if (!strcmp(arg, "-trusted_first")) ++ flags |= X509_V_FLAG_TRUSTED_FIRST; + else + return 0; + +diff -up openssl-1.0.1e/apps/cms.c.trusted-first openssl-1.0.1e/apps/cms.c +--- openssl-1.0.1e/apps/cms.c.trusted-first 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/cms.c 2013-08-16 15:43:56.671213879 +0200 +@@ -642,6 +642,7 @@ int MAIN(int argc, char **argv) + BIO_printf (bio_err, "-text include or delete text MIME headers\n"); + BIO_printf (bio_err, "-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, "-crl_check check revocation status of signer's certificate using CRLs\n"); + BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); + #ifndef OPENSSL_NO_ENGINE +diff -up openssl-1.0.1e/apps/ocsp.c.trusted-first openssl-1.0.1e/apps/ocsp.c +--- openssl-1.0.1e/apps/ocsp.c.trusted-first 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/ocsp.c 2013-08-16 15:49:47.477572414 +0200 +@@ -595,6 +595,7 @@ int MAIN(int argc, char **argv) + BIO_printf (bio_err, "-path path to use in OCSP request\n"); + BIO_printf (bio_err, "-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, "-VAfile file validator certificates file\n"); + BIO_printf (bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); + BIO_printf (bio_err, "-status_age n maximum status age in seconds\n"); +diff -up openssl-1.0.1e/apps/s_client.c.trusted-first openssl-1.0.1e/apps/s_client.c +--- openssl-1.0.1e/apps/s_client.c.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/apps/s_client.c 2013-08-16 15:49:00.727542994 +0200 +@@ -298,6 +298,7 @@ static void sc_usage(void) + BIO_printf(bio_err," -pass arg - private key file pass phrase source\n"); + 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," -reconnect - Drop and re-make the connection with the same Session-ID\n"); + BIO_printf(bio_err," -pause - sleep(1) after each read(2) and write(2) system call\n"); + BIO_printf(bio_err," -showcerts - show all certificates in the chain\n"); +diff -up openssl-1.0.1e/apps/smime.c.trusted-first openssl-1.0.1e/apps/smime.c +--- openssl-1.0.1e/apps/smime.c.trusted-first 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/smime.c 2013-08-16 15:46:44.024875150 +0200 +@@ -479,6 +479,7 @@ int MAIN(int argc, char **argv) + BIO_printf (bio_err, "-text include or delete text MIME headers\n"); + BIO_printf (bio_err, "-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, "-crl_check check revocation status of signer's certificate using CRLs\n"); + BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); + #ifndef OPENSSL_NO_ENGINE +diff -up openssl-1.0.1e/apps/s_server.c.trusted-first openssl-1.0.1e/apps/s_server.c +--- openssl-1.0.1e/apps/s_server.c.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/apps/s_server.c 2013-08-16 15:48:19.469634430 +0200 +@@ -501,6 +501,7 @@ static void sv_usage(void) + BIO_printf(bio_err," -state - Print the SSL states\n"); + 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," -nocert - Don't use any certificates (Anon-DH)\n"); + BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n"); + BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n"); +diff -up openssl-1.0.1e/apps/s_time.c.trusted-first openssl-1.0.1e/apps/s_time.c +--- openssl-1.0.1e/apps/s_time.c.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/apps/s_time.c 2013-08-16 15:47:35.862674188 +0200 +@@ -179,6 +179,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.1e/apps/ts.c.trusted-first openssl-1.0.1e/apps/ts.c +--- openssl-1.0.1e/apps/ts.c.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/apps/ts.c 2013-08-16 15:45:27.766206812 +0200 +@@ -383,7 +383,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.1e/apps/verify.c.trusted-first openssl-1.0.1e/apps/verify.c +--- openssl-1.0.1e/apps/verify.c.trusted-first 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/apps/verify.c 2013-08-16 15:46:09.720124654 +0200 +@@ -237,7 +237,7 @@ int MAIN(int argc, char **argv) + + end: + if (ret == 1) { +- BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]"); ++ BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-trusted_first] [-purpose purpose] [-crl_check]"); + BIO_printf(bio_err," [-attime timestamp]"); + #ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err," [-engine e]"); +diff -up openssl-1.0.1e/crypto/x509/x509_vfy.c.trusted-first openssl-1.0.1e/crypto/x509/x509_vfy.c +--- openssl-1.0.1e/crypto/x509/x509_vfy.c.trusted-first 2013-08-16 15:42:39.864533545 +0200 ++++ openssl-1.0.1e/crypto/x509/x509_vfy.c 2013-08-16 15:42:39.921534791 +0200 +@@ -207,6 +207,21 @@ int X509_verify_cert(X509_STORE_CTX *ctx + + /* If we are self signed, we break */ + if (ctx->check_issued(ctx, x,x)) break; ++ /* If asked see if we can find issuer in trusted store first */ ++ if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) ++ { ++ ok = ctx->get_issuer(&xtmp, ctx, x); ++ if (ok < 0) ++ return ok; ++ /* If successful for now free up cert so it ++ * will be picked up again later. ++ */ ++ if (ok > 0) ++ { ++ X509_free(xtmp); ++ break; ++ } ++ } + + /* If we were passed a cert chain, use it first */ + if (ctx->untrusted != NULL) +diff -up openssl-1.0.1e/crypto/x509/x509_vfy.h.trusted-first openssl-1.0.1e/crypto/x509/x509_vfy.h +--- openssl-1.0.1e/crypto/x509/x509_vfy.h.trusted-first 2013-08-16 15:42:39.356522432 +0200 ++++ openssl-1.0.1e/crypto/x509/x509_vfy.h 2013-08-16 15:42:39.922534813 +0200 +@@ -389,6 +389,8 @@ void X509_STORE_CTX_set_depth(X509_STORE + #define X509_V_FLAG_USE_DELTAS 0x2000 + /* Check selfsigned CA signature */ + #define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 ++/* Use trusted store first */ ++#define X509_V_FLAG_TRUSTED_FIRST 0x8000 + + + #define X509_VP_FLAG_DEFAULT 0x1 +diff -up openssl-1.0.1e/doc/apps/cms.pod.trusted-first openssl-1.0.1e/doc/apps/cms.pod +--- openssl-1.0.1e/doc/apps/cms.pod.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/doc/apps/cms.pod 2013-08-16 15:50:48.723921117 +0200 +@@ -35,6 +35,7 @@ B B + [B<-print>] + [B<-CAfile file>] + [B<-CApath dir>] ++[B<-trusted_first>] + [B<-md digest>] + [B<-[cipher]>] + [B<-nointern>] +@@ -238,6 +239,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.1e/doc/apps/ocsp.pod.trusted-first openssl-1.0.1e/doc/apps/ocsp.pod +--- openssl-1.0.1e/doc/apps/ocsp.pod.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/doc/apps/ocsp.pod 2013-08-16 15:52:20.106933403 +0200 +@@ -29,6 +29,7 @@ B B + [B<-path>] + [B<-CApath dir>] + [B<-CAfile file>] ++[B<-trusted_first>] + [B<-VAfile file>] + [B<-validity_period n>] + [B<-status_age n>] +@@ -138,6 +139,13 @@ or "/" by default. + 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<-verify_other file> + + file containing additional certificates to search when attempting to locate +diff -up openssl-1.0.1e/doc/apps/s_client.pod.trusted-first openssl-1.0.1e/doc/apps/s_client.pod +--- openssl-1.0.1e/doc/apps/s_client.pod.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/doc/apps/s_client.pod 2013-08-16 15:53:17.364194159 +0200 +@@ -17,6 +17,7 @@ B B + [B<-pass arg>] + [B<-CApath directory>] + [B<-CAfile filename>] ++[B<-trusted_first>] + [B<-reconnect>] + [B<-pause>] + [B<-showcerts>] +@@ -107,7 +108,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> ++=item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig, -trusted_first> + + Set various certificate chain valiadition option. See the + L|verify(1)> manual page for details. +diff -up openssl-1.0.1e/doc/apps/smime.pod.trusted-first openssl-1.0.1e/doc/apps/smime.pod +--- openssl-1.0.1e/doc/apps/smime.pod.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/doc/apps/smime.pod 2013-08-16 15:56:12.497050767 +0200 +@@ -15,6 +15,9 @@ B B + [B<-pk7out>] + [B<-[cipher]>] + [B<-in file>] ++[B<-CAfile file>] ++[B<-CApath dir>] ++[B<-trusted_first>] + [B<-certfile file>] + [B<-signer file>] + [B<-recip file>] +@@ -146,6 +149,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.1e/doc/apps/s_server.pod.trusted-first openssl-1.0.1e/doc/apps/s_server.pod +--- openssl-1.0.1e/doc/apps/s_server.pod.trusted-first 2013-08-16 15:42:39.000000000 +0200 ++++ openssl-1.0.1e/doc/apps/s_server.pod 2013-08-16 15:54:33.609873214 +0200 +@@ -33,6 +33,7 @@ B B + [B<-state>] + [B<-CApath directory>] + [B<-CAfile filename>] ++[B<-trusted_first>] + [B<-nocert>] + [B<-cipher cipherlist>] + [B<-quiet>] +@@ -168,6 +169,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<-state> + + prints out the SSL session states. +diff -up openssl-1.0.1e/doc/apps/s_time.pod.trusted-first openssl-1.0.1e/doc/apps/s_time.pod +--- openssl-1.0.1e/doc/apps/s_time.pod.trusted-first 2013-02-11 16:02:48.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/s_time.pod 2013-08-16 15:55:12.651732938 +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.1e/doc/apps/ts.pod.trusted-first openssl-1.0.1e/doc/apps/ts.pod +--- openssl-1.0.1e/doc/apps/ts.pod.trusted-first 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/ts.pod 2013-08-16 15:57:17.399479957 +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.1e/doc/apps/verify.pod.trusted-first openssl-1.0.1e/doc/apps/verify.pod +--- openssl-1.0.1e/doc/apps/verify.pod.trusted-first 2013-02-11 16:26:04.000000000 +0100 ++++ openssl-1.0.1e/doc/apps/verify.pod 2013-08-16 15:58:00.267423925 +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>] +@@ -56,6 +57,12 @@ in PEM format concatenated together. + 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.1e-version.patch b/SOURCES/openssl-1.0.1e-version.patch new file mode 100755 index 00000000..e73f2c96 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-version.patch @@ -0,0 +1,63 @@ +diff -up openssl-1.0.1e/crypto/cversion.c.version openssl-1.0.1e/crypto/cversion.c +--- openssl-1.0.1e/crypto/cversion.c.version 2013-02-11 16:02:47.000000000 +0100 ++++ openssl-1.0.1e/crypto/cversion.c 2013-07-26 12:28:12.739161925 +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; +@@ -110,8 +110,25 @@ 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); ++ } ++ ++unsigned long _original_SSLeay(void) ++ { ++ return(0x10000003); ++ } ++ ++unsigned long _current_SSLeay(void) + { + return(SSLEAY_VERSION_NUMBER); + } + ++__asm__(".symver _original_SSLeay,SSLeay@"); ++__asm__(".symver _original_SSLeay_version,SSLeay_version@"); ++__asm__(".symver _current_SSLeay,SSLeay@@OPENSSL_1.0.1"); ++__asm__(".symver _current_SSLeay_version,SSLeay_version@@OPENSSL_1.0.1"); +diff -up openssl-1.0.1e/Makefile.shared.version openssl-1.0.1e/Makefile.shared +--- openssl-1.0.1e/Makefile.shared.version 2013-07-26 12:23:43.615545603 +0200 ++++ openssl-1.0.1e/Makefile.shared 2013-07-26 12:23:43.701547398 +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.1e/version.map.version openssl-1.0.1e/version.map +--- openssl-1.0.1e/version.map.version 2013-07-26 12:23:43.701547398 +0200 ++++ openssl-1.0.1e/version.map 2013-07-26 12:29:10.698371472 +0200 +@@ -0,0 +1,8 @@ ++OPENSSL_1.0.1 { ++ global: ++ SSLeay; ++ SSLeay_version; ++ local: ++ _original*; ++ _current*; ++}; diff --git a/SOURCES/openssl-1.0.1e-weak-ciphers.patch b/SOURCES/openssl-1.0.1e-weak-ciphers.patch new file mode 100755 index 00000000..86573453 --- /dev/null +++ b/SOURCES/openssl-1.0.1e-weak-ciphers.patch @@ -0,0 +1,12 @@ +diff -up openssl-1.0.1e/ssl/ssl.h.weak-ciphers openssl-1.0.1e/ssl/ssl.h +--- openssl-1.0.1e/ssl/ssl.h.weak-ciphers 2013-12-18 15:50:40.881620314 +0100 ++++ openssl-1.0.1e/ssl/ssl.h 2013-12-18 14:25:25.596566704 +0100 +@@ -331,7 +331,7 @@ extern "C" { + /* The following cipher list is used by default. + * It also is substituted when an application-defined cipher list string + * starts with 'DEFAULT'. */ +-#define SSL_DEFAULT_CIPHER_LIST "ALL:!aNULL:!eNULL:!SSLv2" ++#define SSL_DEFAULT_CIPHER_LIST "ALL:!aNULL:!eNULL:!SSLv2:!EXPORT:!RC2:!DES" + /* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! 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 00000000..a19877dc --- /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 00000000..2bb8327f --- /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 00000000..1e0993e1 --- /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 00000000..315a9b0d --- /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 00000000..a6a79d7e --- /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 00000000..328079bf --- /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 00000000..65f652cf --- /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 00000000..e42f4a1e --- /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 00000000..825417f8 --- /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 00000000..dd8b42ce --- /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 00000000..a439d141 --- /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 00000000..4aafefdb --- /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 00000000..19d39585 --- /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 00000000..70699891 --- /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 00000000..4de716a3 --- /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 00000000..4510e6e1 --- /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 00000000..b7936b3d --- /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 00000000..25dfff51 --- /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 00000000..7c96a578 --- /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 00000000..aa607be8 --- /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 00000000..dfcae762 --- /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 00000000..4c941333 --- /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 00000000..22b99c1f --- /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 00000000..db1460cb --- /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 00000000..8e3d95b8 --- /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 00000000..fad043c4 --- /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 00000000..12e51030 --- /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 00000000..f8101578 --- /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 00000000..c7f18205 --- /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 00000000..819a3fcc --- /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 00000000..862ef1bb --- /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 00000000..669922c6 --- /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 113 ++# define DSA_R_KEY_SIZE_TOO_SMALL 110 + # define DSA_R_MISSING_PARAMETERS 101 + # define DSA_R_MODULUS_TOO_LARGE 103 +-# define DSA_R_NEED_NEW_SETUP_VALUES 110 ++# define DSA_R_NEED_NEW_SETUP_VALUES 112 + # define DSA_R_NON_FIPS_DSA_METHOD 111 ++# define DSA_R_NON_FIPS_METHOD 111 + # define DSA_R_NO_PARAMETERS_SET 107 ++# define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE /* unused */ 112 + # define DSA_R_PARAMETER_ENCODING_ERROR 105 + # define DSA_R_Q_NOT_PRIME 113 + +diff -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 00000000..da8728e1 --- /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 00000000..12ea01e8 --- /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 00000000..cbfb2e9e --- /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 00000000..6e9e387d --- /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 00000000..9feb8cfb --- /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 00000000..2b9ec066 --- /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 00000000..4d1e578d --- /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 00000000..683d9afd --- /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-3736.patch b/SOURCES/openssl-1.0.2k-cve-2017-3736.patch new file mode 100644 index 00000000..6fc04918 --- /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 00000000..0f6f462e --- /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 00000000..e8b6ba51 --- /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-fips-randlock.patch b/SOURCES/openssl-1.0.2k-fips-randlock.patch new file mode 100644 index 00000000..8b08ef40 --- /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-long-hello.patch b/SOURCES/openssl-1.0.2k-long-hello.patch new file mode 100644 index 00000000..358b0270 --- /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-no-ssl2.patch b/SOURCES/openssl-1.0.2k-no-ssl2.patch new file mode 100644 index 00000000..c6684174 --- /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 00000000..a5efdfaa --- /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 00000000..0be9167c --- /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-starttls.patch b/SOURCES/openssl-1.0.2k-starttls.patch new file mode 100644 index 00000000..da987f85 --- /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/renew-dummy-cert b/SOURCES/renew-dummy-cert new file mode 100755 index 00000000..50f99312 --- /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 00000000..f65ee915 --- /dev/null +++ b/SPECS/openssl.spec @@ -0,0 +1,1943 @@ +# 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 %{power64} 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: 12%{?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 +# 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 + +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 + +%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 + +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 +* 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