diff options
author | Dariusz Michaluk <d.michaluk@samsung.com> | 2018-11-22 11:46:15 +0100 |
---|---|---|
committer | Dariusz Michaluk <d.michaluk@samsung.com> | 2018-11-22 11:46:15 +0100 |
commit | 1f964107cef6adef924015b1d3c73722fb809a5c (patch) | |
tree | 27784edd298c545ef5572f5e039b979056566ef0 | |
parent | 0c4c39e921372ead218d7b8cedd71b7430798a0e (diff) | |
download | openssl-1f964107cef6adef924015b1d3c73722fb809a5c.tar.gz openssl-1f964107cef6adef924015b1d3c73722fb809a5c.tar.bz2 openssl-1f964107cef6adef924015b1d3c73722fb809a5c.zip |
Imported Upstream version 1.0.2qupstream/1.0.2q
64 files changed, 1617 insertions, 226 deletions
@@ -7,6 +7,36 @@ https://github.com/openssl/openssl/commits/ and pick the appropriate release branch. + Changes between 1.0.2p and 1.0.2q [20 Nov 2018] + + *) Microarchitecture timing vulnerability in ECC scalar multiplication + + OpenSSL ECC scalar multiplication, used in e.g. ECDSA and ECDH, has been + shown to be vulnerable to a microarchitecture timing side channel attack. + An attacker with sufficient access to mount local timing attacks during + ECDSA signature generation could recover the private key. + + This issue was reported to OpenSSL on 26th October 2018 by Alejandro + Cabrera Aldaya, Billy Brumley, Sohaib ul Hassan, Cesar Pereida Garcia and + Nicola Tuveri. + (CVE-2018-5407) + [Billy Brumley] + + *) Timing vulnerability in DSA signature generation + + The OpenSSL DSA signature algorithm has been shown to be vulnerable to a + timing side channel attack. An attacker could use variations in the signing + algorithm to recover the private key. + + This issue was reported to OpenSSL on 16th October 2018 by Samuel Weiser. + (CVE-2018-0734) + [Paul Dale] + + *) Resolve a compatibility issue in EC_GROUP handling with the FIPS Object + Module, accidentally introduced while backporting security fixes from the + development branch and hindering the use of ECC in FIPS mode. + [Nicola Tuveri] + Changes between 1.0.2o and 1.0.2p [14 Aug 2018] *) Client DoS due to large DH parameter @@ -4,18 +4,18 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2p +VERSION=1.0.2q MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 SHLIB_VERSION_HISTORY= SHLIB_MAJOR=1 SHLIB_MINOR=0.0 -SHLIB_EXT= -PLATFORM=dist -OPTIONS= no-ec_nistp_64_gcc_128 no-gmp no-jpake no-krb5 no-libunbound no-md2 no-rc5 no-rfc3779 no-sctp no-shared no-ssl-trace no-ssl2 no-store no-unit-test no-weak-ssl-ciphers no-zlib no-zlib-dynamic static-engine -CONFIGURE_ARGS=dist -SHLIB_TARGET= +SHLIB_EXT=.so.$(SHLIB_MAJOR).$(SHLIB_MINOR) +PLATFORM=linux-x86_64 +OPTIONS=-Wa,--noexecstack no-ec_nistp_64_gcc_128 no-gmp no-jpake no-krb5 no-libunbound no-md2 no-rc5 no-rfc3779 no-sctp no-shared no-ssl-trace no-ssl2 no-store no-unit-test no-weak-ssl-ciphers no-zlib no-zlib-dynamic static-engine +CONFIGURE_ARGS=linux-x86_64 -Wa,--noexecstack +SHLIB_TARGET=linux-shared # HERE indicates where this Makefile lives. This can be used to indicate # where sub-Makefiles are expected to be. Currently has very limited usage, @@ -59,11 +59,11 @@ OPENSSLDIR=/usr/local/ssl # equal 4. # PKCS1_CHECK - pkcs1 tests. -CC= cc -CFLAG= -O +CC= gcc +CFLAG= -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_LIBUNBOUND -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_SSL_TRACE -DOPENSSL_NO_SSL2 -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST -DOPENSSL_NO_WEAK_SSL_CIPHERS PEX_LIBS= -EX_LIBS= +EX_LIBS= -ldl EXE_EXT= ARFLAGS= AR= ar $(ARFLAGS) r @@ -73,7 +73,7 @@ NM= nm PERL= /usr/bin/perl TAR= tar TARFLAGS= --no-recursion -MAKEDEPPROG= cc +MAKEDEPPROG= gcc LIBDIR=lib # We let the C compiler driver to take care of .s files. This is done in @@ -89,23 +89,23 @@ ASFLAG=$(CFLAG) PROCESSOR= # CPUID module collects small commonly used assembler snippets -CPUID_OBJ= mem_clr.o -BN_ASM= bn_asm.o -EC_ASM= +CPUID_OBJ= x86_64cpuid.o +BN_ASM= x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o rsaz_exp.o rsaz-x86_64.o rsaz-avx2.o +EC_ASM= ecp_nistz256.o ecp_nistz256-x86_64.o DES_ENC= des_enc.o fcrypt_b.o -AES_ENC= aes_core.o aes_cbc.o +AES_ENC= aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o aesni-sha256-x86_64.o aesni-mb-x86_64.o BF_ENC= bf_enc.o CAST_ENC= c_enc.o -RC4_ENC= rc4_enc.o rc4_skey.o +RC4_ENC= rc4-x86_64.o rc4-md5-x86_64.o RC5_ENC= rc5_enc.o -MD5_ASM_OBJ= -SHA1_ASM_OBJ= +MD5_ASM_OBJ= md5-x86_64.o +SHA1_ASM_OBJ= sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o sha1-mb-x86_64.o sha256-mb-x86_64.o RMD160_ASM_OBJ= -WP_ASM_OBJ= wp_block.o -CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o -MODES_ASM_OBJ= +WP_ASM_OBJ= wp-x86_64.o +CMLL_ENC= cmll-x86_64.o cmll_misc.o +MODES_ASM_OBJ= ghash-x86_64.o aesni-gcm-x86_64.o ENGINES_ASM_OBJ= -PERLASM_SCHEME= +PERLASM_SCHEME= elf # KRB5 stuff KRB5_INCLUDES= @@ -177,8 +177,8 @@ LIBS= libcrypto.a libssl.a SHARED_CRYPTO=libcrypto$(SHLIB_EXT) SHARED_SSL=libssl$(SHLIB_EXT) SHARED_LIBS= -SHARED_LIBS_LINK_EXTS= -SHARED_LDFLAGS= +SHARED_LIBS_LINK_EXTS=.so.$(SHLIB_MAJOR) .so +SHARED_LDFLAGS=-m64 GENERAL= Makefile BASENAME= openssl diff --git a/Makefile.bak b/Makefile.bak index 5cf0bd8..1de4ac3 100644 --- a/Makefile.bak +++ b/Makefile.bak @@ -4,18 +4,18 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2p +VERSION=1.0.2q-dev MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 SHLIB_VERSION_HISTORY= SHLIB_MAJOR=1 SHLIB_MINOR=0.0 -SHLIB_EXT=.so.$(SHLIB_MAJOR).$(SHLIB_MINOR) -PLATFORM=linux-x86_64 -OPTIONS=-Wa,--noexecstack no-ec_nistp_64_gcc_128 no-gmp no-jpake no-krb5 no-libunbound no-md2 no-rc5 no-rfc3779 no-sctp no-shared no-ssl-trace no-ssl2 no-store no-unit-test no-weak-ssl-ciphers no-zlib no-zlib-dynamic static-engine -CONFIGURE_ARGS=linux-x86_64 -Wa,--noexecstack -SHLIB_TARGET=linux-shared +SHLIB_EXT= +PLATFORM=gcc +OPTIONS= no-ec_nistp_64_gcc_128 no-gmp no-jpake no-krb5 no-libunbound no-md2 no-rc5 no-rfc3779 no-sctp no-shared no-ssl-trace no-ssl2 no-store no-unit-test no-weak-ssl-ciphers no-zlib no-zlib-dynamic static-engine +CONFIGURE_ARGS=gcc +SHLIB_TARGET= # HERE indicates where this Makefile lives. This can be used to indicate # where sub-Makefiles are expected to be. Currently has very limited usage, @@ -60,10 +60,10 @@ OPENSSLDIR=/usr/local/ssl # PKCS1_CHECK - pkcs1 tests. CC= gcc -CFLAG= -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM +CFLAG= -O3 DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_LIBUNBOUND -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_SSL_TRACE -DOPENSSL_NO_SSL2 -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST -DOPENSSL_NO_WEAK_SSL_CIPHERS PEX_LIBS= -EX_LIBS= -ldl +EX_LIBS= EXE_EXT= ARFLAGS= AR= ar $(ARFLAGS) r @@ -89,23 +89,23 @@ ASFLAG=$(CFLAG) PROCESSOR= # CPUID module collects small commonly used assembler snippets -CPUID_OBJ= x86_64cpuid.o -BN_ASM= x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o rsaz_exp.o rsaz-x86_64.o rsaz-avx2.o -EC_ASM= ecp_nistz256.o ecp_nistz256-x86_64.o +CPUID_OBJ= mem_clr.o +BN_ASM= bn_asm.o +EC_ASM= DES_ENC= des_enc.o fcrypt_b.o -AES_ENC= aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o aesni-sha256-x86_64.o aesni-mb-x86_64.o +AES_ENC= aes_core.o aes_cbc.o BF_ENC= bf_enc.o CAST_ENC= c_enc.o -RC4_ENC= rc4-x86_64.o rc4-md5-x86_64.o +RC4_ENC= rc4_enc.o rc4_skey.o RC5_ENC= rc5_enc.o -MD5_ASM_OBJ= md5-x86_64.o -SHA1_ASM_OBJ= sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o sha1-mb-x86_64.o sha256-mb-x86_64.o +MD5_ASM_OBJ= +SHA1_ASM_OBJ= RMD160_ASM_OBJ= -WP_ASM_OBJ= wp-x86_64.o -CMLL_ENC= cmll-x86_64.o cmll_misc.o -MODES_ASM_OBJ= ghash-x86_64.o aesni-gcm-x86_64.o +WP_ASM_OBJ= wp_block.o +CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o +MODES_ASM_OBJ= ENGINES_ASM_OBJ= -PERLASM_SCHEME= elf +PERLASM_SCHEME= # KRB5 stuff KRB5_INCLUDES= @@ -177,8 +177,8 @@ LIBS= libcrypto.a libssl.a SHARED_CRYPTO=libcrypto$(SHLIB_EXT) SHARED_SSL=libssl$(SHLIB_EXT) SHARED_LIBS= -SHARED_LIBS_LINK_EXTS=.so.$(SHLIB_MAJOR) .so -SHARED_LDFLAGS=-m64 +SHARED_LIBS_LINK_EXTS= +SHARED_LDFLAGS= GENERAL= Makefile BASENAME= openssl @@ -5,6 +5,11 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 1.0.2p and OpenSSL 1.0.2q [20 Nov 2018] + + o Microarchitecture timing vulnerability in ECC scalar multiplication (CVE-2018-5407) + o Timing vulnerability in DSA signature generation (CVE-2018-0734) + Major changes between OpenSSL 1.0.2o and OpenSSL 1.0.2p [14 Aug 2018] o Client DoS due to large DH parameter (CVE-2018-0732) @@ -1,5 +1,5 @@ - OpenSSL 1.0.2p 14 Aug 2018 + OpenSSL 1.0.2q 20 Nov 2018 Copyright (c) 1998-2018 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson diff --git a/apps/CA.pl.bak b/apps/CA.pl.bak new file mode 100644 index 0000000..43c20b2 --- /dev/null +++ b/apps/CA.pl.bak @@ -0,0 +1,188 @@ +#!/usr/bin/perl +# +# CA - wrapper around ca to make it easier to use ... basically ca requires +# some setup stuff to be done before you can use it and this makes +# things easier between now and when Eric is convinced to fix it :-) +# +# CA -newca ... will setup the right stuff +# CA -newreq[-nodes] ... will generate a certificate request +# CA -sign ... will sign the generated request and output +# +# At the end of that grab newreq.pem and newcert.pem (one has the key +# and the other the certificate) and cat them together and that is what +# you want/need ... I'll make even this a little cleaner later. +# +# +# 12-Jan-96 tjh Added more things ... including CA -signcert which +# converts a certificate to a request and then signs it. +# 10-Jan-96 eay Fixed a few more bugs and added the SSLEAY_CONFIG +# environment variable so this can be driven from +# a script. +# 25-Jul-96 eay Cleaned up filenames some more. +# 11-Jun-96 eay Fixed a few filename missmatches. +# 03-May-96 eay Modified to use 'ssleay cmd' instead of 'cmd'. +# 18-Apr-96 tjh Original hacking +# +# Tim Hudson +# tjh@cryptsoft.com +# + +# 27-Apr-98 snh Translation into perl, fix existing CA bug. +# +# +# Steve Henson +# shenson@bigfoot.com + +# default openssl.cnf file has setup as per the following +# demoCA ... where everything is stored + +my $openssl; +if(defined $ENV{OPENSSL}) { + $openssl = $ENV{OPENSSL}; +} else { + $openssl = "openssl"; + $ENV{OPENSSL} = $openssl; +} + +$SSLEAY_CONFIG=$ENV{"SSLEAY_CONFIG"}; +$DAYS="-days 365"; # 1 year +$CADAYS="-days 1095"; # 3 years +$REQ="$openssl req $SSLEAY_CONFIG"; +$CA="$openssl ca $SSLEAY_CONFIG"; +$VERIFY="$openssl verify"; +$X509="$openssl x509"; +$PKCS12="$openssl pkcs12"; + +$CATOP="./demoCA"; +$CAKEY="cakey.pem"; +$CAREQ="careq.pem"; +$CACERT="cacert.pem"; + +$DIRMODE = 0777; + +$RET = 0; + +foreach (@ARGV) { + if ( /^(-\?|-h|-help)$/ ) { + print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-signcert|-verify\n"; + exit 0; + } elsif (/^-newcert$/) { + # create a certificate + system ("$REQ -new -x509 -keyout newkey.pem -out newcert.pem $DAYS"); + $RET=$?; + print "Certificate is in newcert.pem, private key is in newkey.pem\n" + } elsif (/^-newreq$/) { + # create a certificate request + system ("$REQ -new -keyout newkey.pem -out newreq.pem $DAYS"); + $RET=$?; + print "Request is in newreq.pem, private key is in newkey.pem\n"; + } elsif (/^-newreq-nodes$/) { + # create a certificate request + system ("$REQ -new -nodes -keyout newkey.pem -out newreq.pem $DAYS"); + $RET=$?; + print "Request is in newreq.pem, private key is in newkey.pem\n"; + } elsif (/^-newca$/) { + # if explicitly asked for or it doesn't exist then setup the + # directory structure that Eric likes to manage things + $NEW="1"; + if ( "$NEW" || ! -f "${CATOP}/serial" ) { + # create the directory hierarchy + mkdir $CATOP, $DIRMODE; + mkdir "${CATOP}/certs", $DIRMODE; + mkdir "${CATOP}/crl", $DIRMODE ; + mkdir "${CATOP}/newcerts", $DIRMODE; + mkdir "${CATOP}/private", $DIRMODE; + open OUT, ">${CATOP}/index.txt"; + close OUT; + open OUT, ">${CATOP}/crlnumber"; + print OUT "01\n"; + close OUT; + } + if ( ! -f "${CATOP}/private/$CAKEY" ) { + print "CA certificate filename (or enter to create)\n"; + $FILE = <STDIN>; + + chop $FILE; + + # ask user for existing CA certificate + if ($FILE) { + cp_pem($FILE,"${CATOP}/private/$CAKEY", "PRIVATE"); + cp_pem($FILE,"${CATOP}/$CACERT", "CERTIFICATE"); + $RET=$?; + } else { + print "Making CA certificate ...\n"; + system ("$REQ -new -keyout " . + "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); + system ("$CA -create_serial " . + "-out ${CATOP}/$CACERT $CADAYS -batch " . + "-keyfile ${CATOP}/private/$CAKEY -selfsign " . + "-extensions v3_ca " . + "-infiles ${CATOP}/$CAREQ "); + $RET=$?; + } + } + } elsif (/^-pkcs12$/) { + my $cname = $ARGV[1]; + $cname = "My Certificate" unless defined $cname; + system ("$PKCS12 -in newcert.pem -inkey newkey.pem " . + "-certfile ${CATOP}/$CACERT -out newcert.p12 " . + "-export -name \"$cname\""); + $RET=$?; + print "PKCS #12 file is in newcert.p12\n"; + exit $RET; + } elsif (/^-xsign$/) { + system ("$CA -policy policy_anything -infiles newreq.pem"); + $RET=$?; + } elsif (/^(-sign|-signreq)$/) { + system ("$CA -policy policy_anything -out newcert.pem " . + "-infiles newreq.pem"); + $RET=$?; + print "Signed certificate is in newcert.pem\n"; + } elsif (/^(-signCA)$/) { + system ("$CA -policy policy_anything -out newcert.pem " . + "-extensions v3_ca -infiles newreq.pem"); + $RET=$?; + print "Signed CA certificate is in newcert.pem\n"; + } elsif (/^-signcert$/) { + system ("$X509 -x509toreq -in newreq.pem -signkey newreq.pem " . + "-out tmp.pem"); + system ("$CA -policy policy_anything -out newcert.pem " . + "-infiles tmp.pem"); + $RET = $?; + print "Signed certificate is in newcert.pem\n"; + } elsif (/^-verify$/) { + if (shift) { + foreach $j (@ARGV) { + system ("$VERIFY -CAfile $CATOP/$CACERT $j"); + $RET=$? if ($? != 0); + } + exit $RET; + } else { + system ("$VERIFY -CAfile $CATOP/$CACERT newcert.pem"); + $RET=$?; + exit 0; + } + } else { + print STDERR "Unknown arg $_\n"; + print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify\n"; + exit 1; + } +} + +exit $RET; + +sub cp_pem { +my ($infile, $outfile, $bound) = @_; +open IN, $infile; +open OUT, ">$outfile"; +my $flag = 0; +while (<IN>) { + $flag = 1 if (/^-----BEGIN.*$bound/) ; + print OUT $_ if ($flag); + if (/^-----END.*$bound/) { + close IN; + close OUT; + return; + } +} +} @@ -659,8 +659,7 @@ int MAIN(int argc, char **argv) } } - BIO_printf(bio_err, "Generating a %ld bit %s private key\n", - newkey, keyalgstr); + BIO_printf(bio_err, "Generating a %s private key\n", keyalgstr); EVP_PKEY_CTX_set_cb(genctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(genctx, bio_err); @@ -992,5 +992,6 @@ if [ $? = "0" ]; then fi else echo "This system ($OUT) is not supported. See file INSTALL for details." + exit 1 fi ) diff --git a/crypto/Makefile b/crypto/Makefile index ad1b9f0..180707e 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -36,9 +36,11 @@ TEST=constant_time_test.c LIB= $(TOP)/libcrypto.a SHARED_LIB= libcrypto$(SHLIB_EXT) LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \ - ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c + ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c \ + getenv.c LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o \ - uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ) + uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o getenv.o \ + $(CPUID_OBJ) SRC= $(LIBSRC) @@ -178,6 +180,13 @@ ex_data.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h ex_data.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h ex_data.o: ex_data.c fips_ers.o: ../include/openssl/opensslconf.h fips_ers.c +getenv.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h +getenv.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h +getenv.o: ../include/openssl/err.h ../include/openssl/lhash.h +getenv.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h +getenv.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h +getenv.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h +getenv.o: getenv.c mem.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h mem.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h mem.o: ../include/openssl/err.h ../include/openssl/lhash.h diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c index 5bad0a2..d32b76b 100644 --- a/crypto/bio/b_sock.c +++ b/crypto/bio/b_sock.c @@ -56,6 +56,9 @@ * [including the GNU Public Licence.] */ +#define _DEFAULT_SOURCE +#define _BSD_SOURCE + #include <stdio.h> #include <stdlib.h> #include <errno.h> @@ -83,6 +86,11 @@ NETDB_DEFINE_CONTEXT static int wsa_init_done = 0; # endif +# if defined(__GLIBC__) +# define HAVE_GETHOSTBYNAME_R +# define GETHOSTNAME_R_BUF (2 * 1024) +# endif + /* * WSAAPI specifier is required to make indirect calls to run-time * linked WinSock 2 functions used in this module, to be specific @@ -116,7 +124,12 @@ int BIO_get_host_ip(const char *str, unsigned char *ip) int i; int err = 1; int locked = 0; - struct hostent *he; + struct hostent *he = NULL; +# ifdef HAVE_GETHOSTBYNAME_R + char buf[GETHOSTNAME_R_BUF]; + struct hostent hostent; + int h_errnop; +# endif i = get_ip(str, ip); if (i < 0) { @@ -138,10 +151,18 @@ int BIO_get_host_ip(const char *str, unsigned char *ip) if (i > 0) return (1); + /* if gethostbyname_r is supported, use it. */ +# ifdef HAVE_GETHOSTBYNAME_R + memset(&hostent, 0x00, sizeof(hostent)); + /* gethostbyname_r() sets |he| to NULL on error, we check it further down */ + gethostbyname_r(str, &hostent, buf, sizeof(buf), &he, &h_errnop); +# else /* do a gethostbyname */ CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); locked = 1; he = BIO_gethostbyname(str); +# endif + if (he == NULL) { BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP); goto err; diff --git a/crypto/bn/asm/x86_64-gcc.c b/crypto/bn/asm/x86_64-gcc.c index 1729b47..aa94a13 100644 --- a/crypto/bn/asm/x86_64-gcc.c +++ b/crypto/bn/asm/x86_64-gcc.c @@ -55,12 +55,6 @@ * machine. */ -# if defined(_WIN64) || !defined(__LP64__) -# define BN_ULONG unsigned long long -# else -# define BN_ULONG unsigned long -# endif - # undef mul # undef mul_add diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index d448daa..a1e5e13 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c @@ -1,6 +1,6 @@ /* crypto/bn/bn_blind.c */ /* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -206,10 +206,15 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) goto err; } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) { - if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) - goto err; - if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)) - goto err; + if (b->m_ctx != NULL) { + if (!bn_mul_mont_fixed_top(b->Ai, b->Ai, b->Ai, b->m_ctx, ctx) + || !bn_mul_mont_fixed_top(b->A, b->A, b->A, b->m_ctx, ctx)) + goto err; + } else { + if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx) + || !BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) + goto err; + } } ret = 1; @@ -241,13 +246,13 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) else if (!BN_BLINDING_update(b, ctx)) return (0); - if (r != NULL) { - if (!BN_copy(r, b->Ai)) - ret = 0; - } + if (r != NULL && (BN_copy(r, b->Ai) == NULL)) + return 0; - if (!BN_mod_mul(n, n, b->A, b->mod, ctx)) - ret = 0; + if (b->m_ctx != NULL) + ret = BN_mod_mul_montgomery(n, n, b->A, b->m_ctx, ctx); + else + ret = BN_mod_mul(n, n, b->A, b->mod, ctx); return ret; } @@ -264,14 +269,29 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, bn_check_top(n); - if (r != NULL) - ret = BN_mod_mul(n, n, r, b->mod, ctx); - else { - if (b->Ai == NULL) { - BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); - return (0); + if (r == NULL && (r = b->Ai) == NULL) { + BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); + return 0; + } + + if (b->m_ctx != NULL) { + /* ensure that BN_mod_mul_montgomery takes pre-defined path */ + if (n->dmax >= r->top) { + size_t i, rtop = r->top, ntop = n->top; + BN_ULONG mask; + + for (i = 0; i < rtop; i++) { + mask = (BN_ULONG)0 - ((i - ntop) >> (8 * sizeof(i) - 1)); + n->d[i] &= mask; + } + mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1)); + /* always true, if (rtop >= ntop) n->top = r->top; */ + n->top = (int)(rtop & ~mask) | (ntop & mask); + n->flags |= (BN_FLG_FIXED_TOP & ~mask); } - ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); + ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx); + } else { + ret = BN_mod_mul(n, n, r, b->mod, ctx); } bn_check_top(n); @@ -366,14 +386,19 @@ BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, } while (1); if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { - if (!ret->bn_mod_exp - (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) + if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) goto err; } else { if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) goto err; } + if (ret->m_ctx != NULL) { + if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx) + || !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx)) + goto err; + } + return ret; err: if (b == NULL && ret != NULL) { diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index 03bd8cd..9b95e5f 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -617,26 +617,40 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) { int n; - size_t i, inc, lasti, j; + size_t i, lasti, j, atop, mask; BN_ULONG l; + /* + * In case |a| is fixed-top, BN_num_bytes can return bogus length, + * but it's assumed that fixed-top inputs ought to be "nominated" + * even for padded output, so it works out... + */ n = BN_num_bytes(a); - if (tolen == -1) + if (tolen == -1) { tolen = n; - else if (tolen < n) - return -1; + } else if (tolen < n) { /* uncommon/unlike case */ + BIGNUM temp = *a; - if (n == 0) { + bn_correct_top(&temp); + n = BN_num_bytes(&temp); + if (tolen < n) + return -1; + } + + /* Swipe through whole available data and don't give away padded zero. */ + atop = a->dmax * BN_BYTES; + if (atop == 0) { OPENSSL_cleanse(to, tolen); return tolen; } - lasti = n - 1; - for (i = 0, inc = 1, j = tolen; j > 0;) { + lasti = atop - 1; + atop = a->top * BN_BYTES; + for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) { l = a->d[i / BN_BYTES]; - to[--j] = (unsigned char)(l >> (8 * (i % BN_BYTES)) & (0 - inc)); - inc = (i - lasti) >> (8 * sizeof(i) - 1); - i += inc; /* stay on top limb */ + mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); + *--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); + i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ } return tolen; @@ -889,6 +903,38 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) a->top ^= t; b->top ^= t; + t = (a->neg ^ b->neg) & condition; + a->neg ^= t; + b->neg ^= t; + + /*- + * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention + * is actually to treat it as it's read-only data, and some (if not most) + * of it does reside in read-only segment. In other words observation of + * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal + * condition. It would either cause SEGV or effectively cause data + * corruption. + * + * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be + * preserved. + * + * BN_FLG_SECURE: must be preserved, because it determines how x->d was + * allocated and hence how to free it. + * + * BN_FLG_CONSTTIME: sufficient to mask and swap + * + * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on + * the data, so the d array may be padded with additional 0 values (i.e. + * top could be greater than the minimal value that it could be). We should + * be swapping it + */ + +#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP) + + t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition; + a->flags ^= t; + b->flags ^= t; + #define BN_CONSTTIME_SWAP(ind) \ do { \ t = (a->d[ind] ^ b->d[ind]) & condition; \ diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c index 43da462..255e6e4 100644 --- a/crypto/bn/bn_mod.c +++ b/crypto/bn/bn_mod.c @@ -172,7 +172,7 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, if (mtop > sizeof(storage) / sizeof(storage[0]) && (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL) - return 0; + return 0; ap = a->d != NULL ? a->d : tp; bp = b->d != NULL ? b->d : tp; @@ -197,6 +197,7 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, ((volatile BN_ULONG *)tp)[i] = 0; } r->top = mtop; + r->flags |= BN_FLG_FIXED_TOP; r->neg = 0; if (tp != storage) @@ -225,6 +226,70 @@ int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, } /* + * BN_mod_sub variant that may be used if both a and b are non-negative, + * a is less than m, while b is of same bit width as m. It's implemented + * as subtraction followed by two conditional additions. + * + * 0 <= a < m + * 0 <= b < 2^w < 2*m + * + * after subtraction + * + * -2*m < r = a - b < m + * + * Thus it takes up to two conditional additions to make |r| positive. + */ +int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + size_t i, ai, bi, mtop = m->top; + BN_ULONG borrow, carry, ta, tb, mask, *rp; + const BN_ULONG *ap, *bp; + + if (bn_wexpand(r, m->top) == NULL) + return 0; + + rp = r->d; + ap = a->d != NULL ? a->d : rp; + bp = b->d != NULL ? b->d : rp; + + for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) { + mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); + ta = ap[ai] & mask; + + mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); + tb = bp[bi] & mask; + rp[i] = ta - tb - borrow; + if (ta != tb) + borrow = (ta < tb); + + i++; + ai += (i - a->dmax) >> (8 * sizeof(i) - 1); + bi += (i - b->dmax) >> (8 * sizeof(i) - 1); + } + ap = m->d; + for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { + ta = ((ap[i] & mask) + carry) & BN_MASK2; + carry = (ta < carry); + rp[i] = (rp[i] + ta) & BN_MASK2; + carry += (rp[i] < ta); + } + borrow -= carry; + for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { + ta = ((ap[i] & mask) + carry) & BN_MASK2; + carry = (ta < carry); + rp[i] = (rp[i] + ta) & BN_MASK2; + carry += (rp[i] < ta); + } + + r->top = mtop; + r->flags |= BN_FLG_FIXED_TOP; + r->neg = 0; + + return 1; +} + +/* * BN_mod_sub variant that may be used if both a and b are non-negative and * less than m */ diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c index d41434a..76eca50 100644 --- a/crypto/bn/bn_mont.c +++ b/crypto/bn/bn_mont.c @@ -164,10 +164,10 @@ int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, bn_check_top(tmp); if (a == b) { - if (!BN_sqr(tmp, a, ctx)) + if (!bn_sqr_fixed_top(tmp, a, ctx)) goto err; } else { - if (!BN_mul(tmp, a, b, ctx)) + if (!bn_mul_fixed_top(tmp, a, b, ctx)) goto err; } /* reduce from aRR to aR */ @@ -190,6 +190,7 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) BIGNUM *n; BN_ULONG *ap, *np, *rp, n0, v, carry; int nl, max, i; + unsigned int rtop; n = &(mont->N); nl = n->top; @@ -207,12 +208,10 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) rp = r->d; /* clear the top words of T */ -# if 1 - for (i = r->top; i < max; i++) /* memset? XXX */ - rp[i] = 0; -# else - memset(&(rp[r->top]), 0, (max - r->top) * sizeof(BN_ULONG)); -# endif + for (rtop = r->top, i = 0; i < max; i++) { + v = (BN_ULONG)0 - ((i - rtop) >> (8 * sizeof(rtop) - 1)); + rp[i] &= v; + } r->top = max; r->flags |= BN_FLG_FIXED_TOP; @@ -263,6 +262,18 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) { + int retn; + + retn = bn_from_mont_fixed_top(ret, a, mont, ctx); + bn_correct_top(ret); + bn_check_top(ret); + + return retn; +} + +int bn_from_mont_fixed_top(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) +{ int retn = 0; #ifdef MONT_WORD BIGNUM *t; @@ -270,8 +281,6 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX_start(ctx); if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) { retn = bn_from_montgomery_word(ret, t, mont); - bn_correct_top(ret); - bn_check_top(ret); } BN_CTX_end(ctx); #else /* !MONT_WORD */ diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c index 6b455a7..f44e5e5 100644 --- a/crypto/bn/bn_mul.c +++ b/crypto/bn/bn_mul.c @@ -936,6 +936,16 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + int ret = bn_mul_fixed_top(r, a, b, ctx); + + bn_correct_top(r); + bn_check_top(r); + + return ret; +} + +int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ int ret = 0; int top, al, bl; BIGNUM *rr; @@ -1042,7 +1052,7 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) end: #endif - bn_correct_top(rr); + rr->flags |= BN_FLG_FIXED_TOP; if (r != rr && BN_copy(r, rr) == NULL) goto err; diff --git a/crypto/bn/bn_sqr.c b/crypto/bn/bn_sqr.c index 5e69297..44bc554 100644 --- a/crypto/bn/bn_sqr.c +++ b/crypto/bn/bn_sqr.c @@ -66,6 +66,16 @@ */ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { + int ret = bn_sqr_fixed_top(r, a, ctx); + + bn_correct_top(r); + bn_check_top(r); + + return ret; +} + +int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) +{ int max, al; int ret = 0; BIGNUM *tmp, *rr; @@ -136,7 +146,7 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) rr->neg = 0; rr->top = max; - bn_correct_top(rr); + rr->flags |= BN_FLG_FIXED_TOP; if (r != rr && BN_copy(r, rr) == NULL) goto err; diff --git a/crypto/bn/bn_x931p.c b/crypto/bn/bn_x931p.c index f444af3..e40241f 100644 --- a/crypto/bn/bn_x931p.c +++ b/crypto/bn/bn_x931p.c @@ -4,7 +4,7 @@ * 2005. */ /* ==================================================================== - * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 2005-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -223,8 +223,10 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) for (i = 0; i < 1000; i++) { if (!BN_rand(Xq, nbits, 1, 0)) goto err; + /* Check that |Xp - Xq| > 2^(nbits - 100) */ - BN_sub(t, Xp, Xq); + if (!BN_sub(t, Xp, Xq)) + goto err; if (BN_num_bits(t) > (nbits - 100)) break; } diff --git a/crypto/bn_int.h b/crypto/bn_int.h index 9c42d6f..a552cc2 100644 --- a/crypto/bn_int.h +++ b/crypto/bn_int.h @@ -7,9 +7,15 @@ */ int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx); +int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx); int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); +int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); diff --git a/crypto/conf/Makefile b/crypto/conf/Makefile index d5f5c58..cd436f7 100644 --- a/crypto/conf/Makefile +++ b/crypto/conf/Makefile @@ -80,12 +80,13 @@ clean: # DO NOT DELETE THIS LINE -- make depend depends on it. conf_api.o: ../../e_os.h ../../include/openssl/bio.h -conf_api.o: ../../include/openssl/conf.h ../../include/openssl/conf_api.h -conf_api.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +conf_api.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h +conf_api.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h +conf_api.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h conf_api.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h conf_api.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h conf_api.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h -conf_api.o: ../../include/openssl/symhacks.h conf_api.c +conf_api.o: ../../include/openssl/symhacks.h ../cryptlib.h conf_api.c conf_def.o: ../../e_os.h ../../include/openssl/bio.h conf_def.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h conf_def.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h diff --git a/crypto/conf/conf_api.c b/crypto/conf/conf_api.c index 60c9440..480781d 100644 --- a/crypto/conf/conf_api.c +++ b/crypto/conf/conf_api.c @@ -66,6 +66,7 @@ #include <assert.h> #include <stdlib.h> #include <string.h> +#include "cryptlib.h" #include <openssl/conf.h> #include <openssl/conf_api.h> #include "e_os.h" @@ -141,7 +142,7 @@ char *_CONF_get_string(const CONF *conf, const char *section, if (v != NULL) return (v->value); if (strcmp(section, "ENV") == 0) { - p = getenv(name); + p = ossl_safe_getenv(name); if (p != NULL) return (p); } @@ -154,7 +155,7 @@ char *_CONF_get_string(const CONF *conf, const char *section, else return (NULL); } else - return (getenv(name)); + return (ossl_safe_getenv(name)); } #if 0 /* There's no way to provide error checking diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index e2a9a81..1df463d 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -4,7 +4,7 @@ * 2001. */ /* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -530,7 +530,7 @@ char *CONF_get1_default_config_file(void) char *file; int len; - file = getenv("OPENSSL_CONF"); + file = ossl_safe_getenv("OPENSSL_CONF"); if (file) return BUF_strdup(file); diff --git a/crypto/cryptlib.h b/crypto/cryptlib.h index fba180a..cdbddf1 100644 --- a/crypto/cryptlib.h +++ b/crypto/cryptlib.h @@ -104,6 +104,8 @@ void OPENSSL_showfatal(const char *fmta, ...); void *OPENSSL_stderr(void); extern int OPENSSL_NONPIC_relocated; +char *ossl_safe_getenv(const char *); + #ifdef __cplusplus } #endif diff --git a/crypto/crypto-lib.com b/crypto/crypto-lib.com index 37dc418..efed110 100644 --- a/crypto/crypto-lib.com +++ b/crypto/crypto-lib.com @@ -214,7 +214,8 @@ $! The contents of these variables are copied from the LIBOBJ variable in the $! corresponding Makefile from each corresponding subdirectory, with .o stripped $! and spaces replaced with commas. $ LIB_ = "cryptlib,mem,mem_dbg,cversion,ex_data,cpt_err,ebcdic,"+ - - "uid,o_time,o_str,o_dir,o_fips,o_init,fips_ers,mem_clr" + "uid,o_time,o_str,o_dir,o_fips,o_init,fips_ers,mem_clr,"+ - + "getenv" $ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref" $ LIB_MD2 = "md2_dgst,md2_one" $ LIB_MD4 = "md4_dgst,md4_one" diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index db52a38..e55d585 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -435,6 +435,12 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, EVP_MD_CTX_init(&mctx); + /* make sure L > N, otherwise we'll get trapped in an infinite loop */ + if (L <= N) { + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); + goto err; + } + if (evpmd == NULL) { if (N == 160) evpmd = EVP_sha1(); diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index 2dcfede..c887c3c 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -73,6 +73,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); static int dsa_init(DSA *dsa); static int dsa_finish(DSA *dsa); +static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, + BN_CTX *ctx); static DSA_METHOD openssl_dsa_meth = { "OpenSSL DSA method", @@ -279,7 +281,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, goto err; /* Preallocate space */ - q_bits = BN_num_bits(dsa->q); + q_bits = BN_num_bits(dsa->q) + sizeof(dsa->q->d[0]) * 16; if (!BN_set_bit(&k, q_bits) || !BN_set_bit(&l, q_bits) || !BN_set_bit(&m, q_bits)) @@ -293,9 +295,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { BN_set_flags(&k, BN_FLG_CONSTTIME); + BN_set_flags(&l, BN_FLG_CONSTTIME); } - if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, CRYPTO_LOCK_DSA, dsa->p, ctx)) @@ -333,8 +335,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, if (!BN_mod(r, r, dsa->q, ctx)) goto err; - /* Compute part of 's = inv(k) (m + xr) mod q' */ - if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL) + /* Compute part of 's = inv(k) (m + xr) mod q' */ + if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL) goto err; if (*kinvp != NULL) @@ -468,3 +470,31 @@ static int dsa_finish(DSA *dsa) BN_MONT_CTX_free(dsa->method_mont_p); return (1); } + +/* + * Compute the inverse of k modulo q. + * Since q is prime, Fermat's Little Theorem applies, which reduces this to + * mod-exp operation. Both the exponent and modulus are public information + * so a mod-exp that doesn't leak the base is sufficient. A newly allocated + * BIGNUM is returned which the caller must free. + */ +static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, + BN_CTX *ctx) +{ + BIGNUM *res = NULL; + BIGNUM *r, e; + + if ((r = BN_new()) == NULL) + return NULL; + + BN_init(&e); + + if (BN_set_word(r, 2) + && BN_sub(&e, q, r) + && BN_mod_exp_mont(r, k, &e, q, ctx, NULL)) + res = r; + else + BN_free(r); + BN_free(&e); + return res; +} diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index 969fd14..8665a4c 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -3,7 +3,7 @@ * Originally written by Bodo Moeller for the OpenSSL project. */ /* ==================================================================== - * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -214,7 +214,7 @@ struct ec_group_st { int asn1_flag; /* flag to control the asn1 encoding */ /* * Kludge: upper bit of ans1_flag is used to denote structure - * version. Is set, then last field is present. This is done + * version. If set, then last field is present. This is done * for interoperation with FIPS code. */ #define EC_GROUP_ASN1_FLAG_MASK 0x7fffffff @@ -549,7 +549,6 @@ void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, unsigned char *digit, unsigned char in); #endif -int ec_precompute_mont_data(EC_GROUP *); #ifdef ECP_NISTZ256_ASM /** Returns GFp methods using montgomery multiplication, with x86-64 optimized diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 9337452..df56484 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -70,6 +70,10 @@ const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; +/* local function prototypes */ + +static int ec_precompute_mont_data(EC_GROUP *group); + /* functions for EC_GROUP objects */ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) @@ -318,17 +322,25 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, } else BN_zero(&group->cofactor); - /* - * Some groups have an order with - * factors of two, which makes the Montgomery setup fail. - * |group->mont_data| will be NULL in this case. + /*- + * Access to the `mont_data` field of an EC_GROUP struct should always be + * guarded by an EC_GROUP_VERSION(group) check to avoid OOB accesses, as the + * group might come from the FIPS module, which does not define the + * `mont_data` field inside the EC_GROUP structure. */ - if (BN_is_odd(&group->order)) { - return ec_precompute_mont_data(group); + if (EC_GROUP_VERSION(group)) { + /*- + * Some groups have an order with + * factors of two, which makes the Montgomery setup fail. + * |group->mont_data| will be NULL in this case. + */ + if (BN_is_odd(&group->order)) + return ec_precompute_mont_data(group); + + BN_MONT_CTX_free(group->mont_data); + group->mont_data = NULL; } - BN_MONT_CTX_free(group->mont_data); - group->mont_data = NULL; return 1; } @@ -1098,18 +1110,23 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) * been performed */ } -/* +/*- * ec_precompute_mont_data sets |group->mont_data| from |group->order| and * returns one on success. On error it returns zero. + * + * Note: this function must be called only after verifying that + * EC_GROUP_VERSION(group) returns true. + * The reason for this is that access to the `mont_data` field of an EC_GROUP + * struct should always be guarded by an EC_GROUP_VERSION(group) check to avoid + * OOB accesses, as the group might come from the FIPS module, which does not + * define the `mont_data` field inside the EC_GROUP structure. */ +static int ec_precompute_mont_data(EC_GROUP *group) { BN_CTX *ctx = BN_CTX_new(); int ret = 0; - if (!EC_GROUP_VERSION(group)) - goto err; - if (group->mont_data) { BN_MONT_CTX_free(group->mont_data); group->mont_data = NULL; diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 2231f99..da71526 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -3,7 +3,7 @@ * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. */ /* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -310,6 +310,224 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) return r; } +#define EC_POINT_BN_set_flags(P, flags) do { \ + BN_set_flags(&(P)->X, (flags)); \ + BN_set_flags(&(P)->Y, (flags)); \ + BN_set_flags(&(P)->Z, (flags)); \ +} while(0) + +/*- + * This functions computes (in constant time) a point multiplication over the + * EC group. + * + * At a high level, it is Montgomery ladder with conditional swaps. + * + * It performs either a fixed scalar point multiplication + * (scalar * generator) + * when point is NULL, or a generic scalar point multiplication + * (scalar * point) + * when point is not NULL. + * + * scalar should be in the range [0,n) otherwise all constant time bets are off. + * + * NB: This says nothing about EC_POINT_add and EC_POINT_dbl, + * which of course are not constant time themselves. + * + * The product is stored in r. + * + * Returns 1 on success, 0 otherwise. + */ +static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, const EC_POINT *point, + BN_CTX *ctx) +{ + int i, cardinality_bits, group_top, kbit, pbit, Z_is_one; + EC_POINT *s = NULL; + BIGNUM *k = NULL; + BIGNUM *lambda = NULL; + BIGNUM *cardinality = NULL; + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + + BN_CTX_start(ctx); + + s = EC_POINT_new(group); + if (s == NULL) + goto err; + + if (point == NULL) { + if (!EC_POINT_copy(s, group->generator)) + goto err; + } else { + if (!EC_POINT_copy(s, point)) + goto err; + } + + EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME); + + cardinality = BN_CTX_get(ctx); + lambda = BN_CTX_get(ctx); + k = BN_CTX_get(ctx); + if (k == NULL || !BN_mul(cardinality, &group->order, &group->cofactor, ctx)) + goto err; + + /* + * Group cardinalities are often on a word boundary. + * So when we pad the scalar, some timing diff might + * pop if it needs to be expanded due to carries. + * So expand ahead of time. + */ + cardinality_bits = BN_num_bits(cardinality); + group_top = cardinality->top; + if ((bn_wexpand(k, group_top + 2) == NULL) + || (bn_wexpand(lambda, group_top + 2) == NULL)) + goto err; + + if (!BN_copy(k, scalar)) + goto err; + + BN_set_flags(k, BN_FLG_CONSTTIME); + + if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) { + /*- + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(k, k, cardinality, ctx)) + goto err; + } + + if (!BN_add(lambda, k, cardinality)) + goto err; + BN_set_flags(lambda, BN_FLG_CONSTTIME); + if (!BN_add(k, lambda, cardinality)) + goto err; + /* + * lambda := scalar + cardinality + * k := scalar + 2*cardinality + */ + kbit = BN_is_bit_set(lambda, cardinality_bits); + BN_consttime_swap(kbit, k, lambda, group_top + 2); + + group_top = group->field.top; + if ((bn_wexpand(&s->X, group_top) == NULL) + || (bn_wexpand(&s->Y, group_top) == NULL) + || (bn_wexpand(&s->Z, group_top) == NULL) + || (bn_wexpand(&r->X, group_top) == NULL) + || (bn_wexpand(&r->Y, group_top) == NULL) + || (bn_wexpand(&r->Z, group_top) == NULL)) + goto err; + + /* top bit is a 1, in a fixed pos */ + if (!EC_POINT_copy(r, s)) + goto err; + + EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME); + + if (!EC_POINT_dbl(group, s, s, ctx)) + goto err; + + pbit = 0; + +#define EC_POINT_CSWAP(c, a, b, w, t) do { \ + BN_consttime_swap(c, &(a)->X, &(b)->X, w); \ + BN_consttime_swap(c, &(a)->Y, &(b)->Y, w); \ + BN_consttime_swap(c, &(a)->Z, &(b)->Z, w); \ + t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ + (a)->Z_is_one ^= (t); \ + (b)->Z_is_one ^= (t); \ +} while(0) + + /*- + * The ladder step, with branches, is + * + * k[i] == 0: S = add(R, S), R = dbl(R) + * k[i] == 1: R = add(S, R), S = dbl(S) + * + * Swapping R, S conditionally on k[i] leaves you with state + * + * k[i] == 0: T, U = R, S + * k[i] == 1: T, U = S, R + * + * Then perform the ECC ops. + * + * U = add(T, U) + * T = dbl(T) + * + * Which leaves you with state + * + * k[i] == 0: U = add(R, S), T = dbl(R) + * k[i] == 1: U = add(S, R), T = dbl(S) + * + * Swapping T, U conditionally on k[i] leaves you with state + * + * k[i] == 0: R, S = T, U + * k[i] == 1: R, S = U, T + * + * Which leaves you with state + * + * k[i] == 0: S = add(R, S), R = dbl(R) + * k[i] == 1: R = add(S, R), S = dbl(S) + * + * So we get the same logic, but instead of a branch it's a + * conditional swap, followed by ECC ops, then another conditional swap. + * + * Optimization: The end of iteration i and start of i-1 looks like + * + * ... + * CSWAP(k[i], R, S) + * ECC + * CSWAP(k[i], R, S) + * (next iteration) + * CSWAP(k[i-1], R, S) + * ECC + * CSWAP(k[i-1], R, S) + * ... + * + * So instead of two contiguous swaps, you can merge the condition + * bits and do a single swap. + * + * k[i] k[i-1] Outcome + * 0 0 No Swap + * 0 1 Swap + * 1 0 Swap + * 1 1 No Swap + * + * This is XOR. pbit tracks the previous bit of k. + */ + + for (i = cardinality_bits - 1; i >= 0; i--) { + kbit = BN_is_bit_set(k, i) ^ pbit; + EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one); + if (!EC_POINT_add(group, s, r, s, ctx)) + goto err; + if (!EC_POINT_dbl(group, r, r, ctx)) + goto err; + /* + * pbit logic merges this cswap with that of the + * next iteration + */ + pbit ^= kbit; + } + /* one final cswap to move the right value into r */ + EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one); +#undef EC_POINT_CSWAP + + ret = 1; + + err: + EC_POINT_free(s); + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + + return ret; +} + +#undef EC_POINT_BN_set_flags + /* * TODO: table should be optimised for the wNAF-based implementation, * sometimes smaller windows will give better performance (thus the @@ -369,6 +587,34 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, return EC_POINT_set_to_infinity(group, r); } + if (!BN_is_zero(&group->order) && !BN_is_zero(&group->cofactor)) { + /*- + * Handle the common cases where the scalar is secret, enforcing a constant + * time scalar multiplication algorithm. + */ + if ((scalar != NULL) && (num == 0)) { + /*- + * In this case we want to compute scalar * GeneratorPoint: this + * codepath is reached most prominently by (ephemeral) key generation + * of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH + * keygen/first half), where the scalar is always secret. This is why + * we ignore if BN_FLG_CONSTTIME is actually set and we always call the + * constant time version. + */ + return ec_mul_consttime(group, r, scalar, NULL, ctx); + } + if ((scalar == NULL) && (num == 1)) { + /*- + * In this case we want to compute scalar * GenericPoint: this codepath + * is reached most prominently by the second half of ECDH, where the + * secret scalar is multiplied by the peer's public point. To protect + * the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and + * we always call the constant time version. + */ + return ec_mul_consttime(group, r, scalars[0], points[0], ctx); + } + } + for (i = 0; i < num; i++) { if (group->meth != points[i]->meth) { ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); diff --git a/crypto/engine/eng_list.c b/crypto/engine/eng_list.c index 83c95d5..5d7eee4 100644 --- a/crypto/engine/eng_list.c +++ b/crypto/engine/eng_list.c @@ -4,7 +4,7 @@ * 2000. */ /* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -62,6 +62,7 @@ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +#include "cryptlib.h" #include "eng_int.h" /* @@ -369,10 +370,10 @@ ENGINE *ENGINE_by_id(const char *id) */ if (strcmp(id, "dynamic")) { # ifdef OPENSSL_SYS_VMS - if ((load_dir = getenv("OPENSSL_ENGINES")) == 0) + if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0) load_dir = "SSLROOT:[ENGINES]"; # else - if ((load_dir = getenv("OPENSSL_ENGINES")) == 0) + if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0) load_dir = ENGINESDIR; # endif iterator = ENGINE_by_id("dynamic"); diff --git a/crypto/getenv.c b/crypto/getenv.c new file mode 100644 index 0000000..53f1dfd --- /dev/null +++ b/crypto/getenv.c @@ -0,0 +1,31 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <stdlib.h> +#include "cryptlib.h" + +char *ossl_safe_getenv(const char *name) +{ +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 17) +# define SECURE_GETENV + return secure_getenv(name); +# endif +#endif + +#ifndef SECURE_GETENV + if (OPENSSL_issetugid()) + return NULL; + return getenv(name); +#endif +} diff --git a/crypto/opensslconf.h b/crypto/opensslconf.h index f533508..ac0ad50 100644 --- a/crypto/opensslconf.h +++ b/crypto/opensslconf.h @@ -53,6 +53,9 @@ extern "C" { #endif /* OPENSSL_DOING_MAKEDEPEND */ +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif #ifndef OPENSSL_NO_DYNAMIC_ENGINE # define OPENSSL_NO_DYNAMIC_ENGINE #endif @@ -106,6 +109,8 @@ extern "C" { # endif #endif +#define OPENSSL_CPUID_OBJ + /* crypto/opensslconf.h.in */ /* Generate 80386 code? */ @@ -152,7 +157,7 @@ extern "C" { * This enables code handling data aligned at natural CPU word * boundary. See crypto/rc4/rc4_enc.c for further details. */ -#undef RC4_CHUNK +#define RC4_CHUNK unsigned long #endif #endif @@ -160,7 +165,7 @@ extern "C" { /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a * %20 speed up (longs are 8 bytes, int's are 4). */ #ifndef DES_LONG -#define DES_LONG unsigned long +#define DES_LONG unsigned int #endif #endif @@ -171,9 +176,9 @@ extern "C" { /* Should we define BN_DIV2W here? */ /* Only one for the following should be defined */ -#undef SIXTY_FOUR_BIT_LONG +#define SIXTY_FOUR_BIT_LONG #undef SIXTY_FOUR_BIT -#define THIRTY_TWO_BIT +#undef THIRTY_TWO_BIT #endif #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) @@ -215,7 +220,7 @@ extern "C" { /* Unroll the inner loop, this sometimes helps, sometimes hinders. * Very mucy CPU dependant */ #ifndef DES_UNROLL -#undef DES_UNROLL +#define DES_UNROLL #endif /* These default values were supplied by diff --git a/crypto/opensslconf.h.bak b/crypto/opensslconf.h.bak new file mode 100644 index 0000000..9cb0f3f --- /dev/null +++ b/crypto/opensslconf.h.bak @@ -0,0 +1,265 @@ +/* opensslconf.h */ +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ + +#ifdef __cplusplus +extern "C" { +#endif +/* OpenSSL was configured with the following options: */ +#ifndef OPENSSL_DOING_MAKEDEPEND + + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_GMP +# define OPENSSL_NO_GMP +#endif +#ifndef OPENSSL_NO_JPAKE +# define OPENSSL_NO_JPAKE +#endif +#ifndef OPENSSL_NO_KRB5 +# define OPENSSL_NO_KRB5 +#endif +#ifndef OPENSSL_NO_LIBUNBOUND +# define OPENSSL_NO_LIBUNBOUND +#endif +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL2 +# define OPENSSL_NO_SSL2 +#endif +#ifndef OPENSSL_NO_STORE +# define OPENSSL_NO_STORE +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif + +#endif /* OPENSSL_DOING_MAKEDEPEND */ + +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define OPENSSL_NO_DYNAMIC_ENGINE +#endif + +/* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ +#ifdef OPENSSL_ALGORITHM_DEFINES +# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128) +# define NO_EC_NISTP_64_GCC_128 +# endif +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) +# define NO_GMP +# endif +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) +# define NO_JPAKE +# endif +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) +# define NO_KRB5 +# endif +# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND) +# define NO_LIBUNBOUND +# endif +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) +# define NO_MD2 +# endif +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) +# define NO_RC5 +# endif +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) +# define NO_RFC3779 +# endif +# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP) +# define NO_SCTP +# endif +# if defined(OPENSSL_NO_SSL_TRACE) && !defined(NO_SSL_TRACE) +# define NO_SSL_TRACE +# endif +# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) +# define NO_SSL2 +# endif +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) +# define NO_STORE +# endif +# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST) +# define NO_UNIT_TEST +# endif +# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS) +# define NO_WEAK_SSL_CIPHERS +# endif +#endif + +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "/usr/local/ssl/lib/engines" +#define OPENSSLDIR "/usr/local/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD <unistd.h> + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman <pgut001@cs.auckland.ac.nz> + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ +#ifdef __cplusplus +} +#endif diff --git a/crypto/opensslv.h b/crypto/opensslv.h index 76a7b00..73d22b3 100644 --- a/crypto/opensslv.h +++ b/crypto/opensslv.h @@ -30,11 +30,11 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x1000210fL +# define OPENSSL_VERSION_NUMBER 0x1000211fL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2p-fips 14 Aug 2018" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q-fips 20 Nov 2018" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2p 14 Aug 2018" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q 20 Nov 2018" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/crypto/pkcs12/p12_init.c b/crypto/pkcs12/p12_init.c index 0322df9..a074b94 100644 --- a/crypto/pkcs12/p12_init.c +++ b/crypto/pkcs12/p12_init.c @@ -4,7 +4,7 @@ * 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -70,7 +70,8 @@ PKCS12 *PKCS12_init(int mode) PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); return NULL; } - ASN1_INTEGER_set(pkcs12->version, 3); + if (!ASN1_INTEGER_set(pkcs12->version, 3)) + goto err; pkcs12->authsafes->type = OBJ_nid2obj(mode); switch (mode) { case NID_pkcs7_data: diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c index 0c5fcaa..866a863 100644 --- a/crypto/pkcs7/pk7_lib.c +++ b/crypto/pkcs7/pk7_lib.c @@ -185,7 +185,6 @@ int PKCS7_set_type(PKCS7 *p7, int type) if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new()) == NULL) goto err; - ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1); if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) goto err; p7->d.signed_and_enveloped->enc_data->content_type diff --git a/crypto/rand/Makefile b/crypto/rand/Makefile index df44369..1643a74 100644 --- a/crypto/rand/Makefile +++ b/crypto/rand/Makefile @@ -157,10 +157,11 @@ rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h rand_win.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h rand_win.o: rand_win.c -randfile.o: ../../e_os.h ../../include/openssl/buffer.h -randfile.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h -randfile.o: ../../include/openssl/opensslconf.h +randfile.o: ../../e_os.h ../../include/openssl/bio.h +randfile.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +randfile.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +randfile.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h randfile.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h randfile.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h randfile.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -randfile.o: randfile.c +randfile.o: ../cryptlib.h randfile.c diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index a7af9f9..2983a3f 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -345,7 +345,6 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) static volatile int stirred_pool = 0; int i, j, k; size_t num_ceil, st_idx, st_num; - int ok; long md_c[2]; unsigned char local_md[MD_DIGEST_LENGTH]; EVP_MD_CTX m; @@ -400,14 +399,13 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) if (!initialized) { RAND_poll(); - initialized = 1; + initialized = (entropy >= ENTROPY_NEEDED); } if (!stirred_pool) do_stir_pool = 1; - ok = (entropy >= ENTROPY_NEEDED); - if (!ok) { + if (!initialized) { /* * If the PRNG state is not yet unpredictable, then seeing the PRNG * output may help attackers to determine the new state; thus we have @@ -446,7 +444,7 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0); n -= MD_DIGEST_LENGTH; } - if (ok) + if (initialized) stirred_pool = 1; } @@ -539,7 +537,7 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); EVP_MD_CTX_cleanup(&m); - if (ok) + if (initialized) return (1); else if (pseudo) return 0; @@ -555,6 +553,18 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) return (0); } +/* + * Returns ssleay_rand_bytes(), enforcing a reseeding from the + * system entropy sources using RAND_poll() before generating +`* the random bytes. + */ + +int ssleay_rand_bytes_from_system(unsigned char *buf, int num) +{ + initialized = 0; + return ssleay_rand_bytes(buf, num, 0, 0); +} + static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num) { return ssleay_rand_bytes(buf, num, 0, 1); @@ -600,10 +610,10 @@ static int ssleay_rand_status(void) if (!initialized) { RAND_poll(); - initialized = 1; + initialized = (entropy >= ENTROPY_NEEDED); } - ret = entropy >= ENTROPY_NEEDED; + ret = initialized; if (!do_not_lock) { /* before unlocking, we must clear 'crypto_lock_rand' */ diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h index f9fda3e..7b4dbcf 100644 --- a/crypto/rand/rand_lcl.h +++ b/crypto/rand/rand_lcl.h @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -154,5 +154,5 @@ # endif int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock); - +int ssleay_rand_bytes_from_system(unsigned char *buf, int num); #endif diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 88a78d3..6094c83 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -185,7 +185,7 @@ int RAND_status(void) /* * Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather - * entropy internally through RAND_poll(). + * entropy internally through RAND_poll()). */ static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout, @@ -196,6 +196,24 @@ static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout, *pout = OPENSSL_malloc(min_len); if (!*pout) return 0; + + /* Enforces a reseed of the SSLEAY PRNG before generating random bytes */ + if (ssleay_rand_bytes_from_system(*pout, min_len) <= 0) { + OPENSSL_free(*pout); + *pout = NULL; + return 0; + } + return min_len; +} + +static size_t drbg_get_nonce(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) +{ + /* Round up request to multiple of block size */ + min_len = ((min_len + 19) / 20) * 20; + *pout = OPENSSL_malloc(min_len); + if (!*pout) + return 0; if (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0) { OPENSSL_free(*pout); *pout = NULL; @@ -281,7 +299,7 @@ int RAND_init_fips(void) FIPS_drbg_set_callbacks(dctx, drbg_get_entropy, drbg_free_entropy, 20, - drbg_get_entropy, drbg_free_entropy); + drbg_get_nonce, drbg_free_entropy); FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0, drbg_rand_seed, drbg_rand_add); /* Personalisation string: a string followed by date time vector */ diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index 728fd0a..c93812c 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -61,6 +61,7 @@ #include <stdlib.h> #include <string.h> +#include "cryptlib.h" #include "e_os.h" #include <openssl/crypto.h> #include <openssl/rand.h> @@ -327,14 +328,12 @@ const char *RAND_file_name(char *buf, size_t size) struct stat sb; #endif - if (OPENSSL_issetugid() == 0) - s = getenv("RANDFILE"); + s = ossl_safe_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 = ossl_safe_getenv("HOME"); #ifdef DEFAULT_HOME if (s == NULL) { s = DEFAULT_HOME; diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c index 7ba24e3..be948a4 100644 --- a/crypto/rsa/rsa_eay.c +++ b/crypto/rsa/rsa_eay.c @@ -224,8 +224,8 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from, } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, @@ -432,8 +432,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, d = rsa->d; if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, @@ -554,8 +554,8 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, d = rsa->d; if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) @@ -660,8 +660,8 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, @@ -708,7 +708,7 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BIGNUM *r1, *m1, *vrfy; BIGNUM local_dmp1, local_dmq1, local_c, local_r1; BIGNUM *dmp1, *dmq1, *c, *pr1; - int ret = 0; + int ret = 0, smooth = 0; BN_CTX_start(ctx); r1 = BN_CTX_get(ctx); @@ -737,20 +737,64 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) } if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { - if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx)) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, + p, ctx)) goto err; - if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx)) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, + q, ctx)) goto err; + + smooth = (rsa->meth->bn_mod_exp == BN_mod_exp_mont) + && (BN_num_bits(q) == BN_num_bits(p)); } } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) + goto err; + + if (smooth) { + /* + * Conversion from Montgomery domain, a.k.a. Montgomery reduction, + * accepts values in [0-m*2^w) range. w is m's bit width rounded up + * to limb width. So that at the very least if |I| is fully reduced, + * i.e. less than p*q, we can count on from-to round to perform + * below modulo operations on |I|. Unlike BN_mod it's constant time. + */ + if (/* m1 = I moq q */ + !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) + || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) + /* m1 = m1^dmq1 mod q */ + || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, + rsa->_method_mod_q) + /* r1 = I mod p */ + || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) + || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) + /* r1 = r1^dmp1 mod p */ + || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, + rsa->_method_mod_p) + /* r1 = (r1 - m1) mod p */ + /* + * bn_mod_sub_fixed_top is not regular modular subtraction, + * it can tolerate subtrahend to be larger than modulus, but + * not bit-wise wider. This makes up for uncommon q>p case, + * when |m1| can be larger than |rsa->p|. + */ + || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) + + /* r1 = r1 * iqmp mod p */ + || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) + || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, + ctx) + /* r0 = r1 * q + m1 */ + || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) + || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) goto err; + goto tail; + } + /* compute I mod q */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { c = &local_c; @@ -828,10 +872,18 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (!BN_add(r0, r1, m1)) goto err; + tail: if (rsa->e && rsa->n) { - if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; + if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) { + if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } else { + bn_correct_top(r0); + if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } /* * If 'I' was greater than (or equal to) rsa->n, the operation will * be equivalent to using 'I mod n'. However, the result of the @@ -840,6 +892,11 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) */ if (!BN_sub(vrfy, vrfy, I)) goto err; + if (BN_is_zero(vrfy)) { + bn_correct_top(r0); + ret = 1; + goto err; /* not actually error */ + } if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err; if (BN_is_negative(vrfy)) @@ -865,6 +922,15 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) goto err; } } + /* + * It's unfortunate that we have to bn_correct_top(r0). What hopefully + * saves the day is that correction is highly unlike, and private key + * operations are customarily performed on blinded message. Which means + * that attacker won't observe correlation with chosen plaintext. + * Secondly, remaining code would still handle it in same computational + * time and even conceal memory access pattern around corrected top. + */ + bn_correct_top(r0); ret = 1; err: BN_CTX_end(ctx); diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c index 1ad0cfc..4b4eb81 100644 --- a/crypto/ui/ui_openssl.c +++ b/crypto/ui/ui_openssl.c @@ -509,6 +509,24 @@ static int open_console(UI *ui) is_a_tty = 0; else # endif +# ifdef ENXIO + /* + * Solaris can return ENXIO. + * This should be ok + */ + if (errno == ENXIO) + is_a_tty = 0; + else +# endif +# ifdef EIO + /* + * Linux can return EIO. + * This should be ok + */ + if (errno == EIO) + is_a_tty = 0; + else +# endif # ifdef ENODEV /* * MacOS X returns ENODEV (Operation not supported by device), diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 6f0209a..9212076 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -128,7 +128,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, switch (cmd) { case X509_L_ADD_DIR: if (argl == X509_FILETYPE_DEFAULT) { - dir = (char *)getenv(X509_get_default_cert_dir_env()); + dir = (char *)ossl_safe_getenv(X509_get_default_cert_dir_env()); if (dir) ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); else diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 82ce4e8..e6d0e6e 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -97,7 +97,8 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, switch (cmd) { case X509_L_FILE_LOAD: if (argl == X509_FILETYPE_DEFAULT) { - file = getenv(X509_get_default_cert_file_env()); + file = ossl_safe_getenv(X509_get_default_cert_file_env()); + if (file) ok = (X509_load_cert_crl_file(ctx, file, X509_FILETYPE_PEM) != 0); diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 869460d..da778d4 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -621,7 +621,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) * A hack to keep people who don't want to modify their software * happy */ - if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) + if (ossl_safe_getenv("OPENSSL_ALLOW_PROXY_CERTS")) allow_proxy_certs = 1; purpose = ctx->param->purpose; } @@ -694,10 +694,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) goto end; } } - /* Check pathlen if not self issued */ - if ((i > 1) && !(x->ex_flags & EXFLAG_SI) - && (x->ex_pathlen != -1) - && (plen > (x->ex_pathlen + proxy_path_length + 1))) { + /* Check pathlen */ + if ((i > 1) && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length))) { ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; ctx->error_depth = i; ctx->current_cert = x; @@ -705,8 +704,8 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) if (!ok) goto end; } - /* Increment path length if not self issued */ - if (!(x->ex_flags & EXFLAG_SI)) + /* Increment path length if not a self issued intermediate CA */ + if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0) plen++; /* * If this certificate is a proxy certificate, the next certificate diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c index 7080a51..6d3aa8f 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509v3/v3_purp.c @@ -396,12 +396,8 @@ static void x509v3_cache_extensions(X509 *x) ASN1_BIT_STRING *ns; EXTENDED_KEY_USAGE *extusage; X509_EXTENSION *ex; - int i; - if (x->ex_flags & EXFLAG_SET) - return; - CRYPTO_w_lock(CRYPTO_LOCK_X509); if (x->ex_flags & EXFLAG_SET) { CRYPTO_w_unlock(CRYPTO_LOCK_X509); diff --git a/doc/apps/crl.pod b/doc/apps/crl.pod index cdced1c..92efbf4 100644 --- a/doc/apps/crl.pod +++ b/doc/apps/crl.pod @@ -115,7 +115,7 @@ Convert a CRL file from PEM to DER: Output the text form of a DER encoded certificate: - openssl crl -in crl.der -text -noout + openssl crl -in crl.der -inform DER -text -noout =head1 BUGS diff --git a/doc/apps/req.pod b/doc/apps/req.pod index 20b2f39..01c1c2e 100644 --- a/doc/apps/req.pod +++ b/doc/apps/req.pod @@ -393,8 +393,7 @@ option. For compatibility B<encrypt_rsa_key> is an equivalent option. =item B<default_md> This option specifies the digest algorithm to use. Possible values -include B<md5 sha1 mdc2>. If not present then MD5 is used. This -option can be overridden on the command line. +include B<md5 sha1 mdc2>. This option can be overridden on the command line. =item B<string_mask> diff --git a/doc/apps/s_server.pod b/doc/apps/s_server.pod index 9916fc3..84777ee 100644 --- a/doc/apps/s_server.pod +++ b/doc/apps/s_server.pod @@ -49,6 +49,7 @@ B<openssl> B<s_server> [B<-no_ssl3>] [B<-no_tls1>] [B<-no_dhe>] +[B<-no_ecdhe>] [B<-bugs>] [B<-hack>] [B<-www>] @@ -144,6 +145,11 @@ a static set of parameters hard coded into the s_server program will be used. 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 no ECDH parameters will be selected, effectively +disabling the ephemeral ECDH cipher suites. + =item B<-no_tmp_rsa> certain export cipher suites sometimes use a temporary RSA key, this option diff --git a/doc/crypto/EVP_DigestSignInit.pod b/doc/crypto/EVP_DigestSignInit.pod index 83e6589..7a3e84d 100644 --- a/doc/crypto/EVP_DigestSignInit.pod +++ b/doc/crypto/EVP_DigestSignInit.pod @@ -19,9 +19,12 @@ The EVP signature routines are a high level interface to digital signatures. EVP_DigestSignInit() sets up signing context B<ctx> to use digest B<type> from ENGINE B<impl> and private key B<pkey>. B<ctx> must be initialized with -EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the +EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL, the EVP_PKEY_CTX of the signing operation will be written to B<*pctx>: this can -be used to set alternative signing options. +be used to set alternative signing options. Note that any existing value in +B<*pctx> is overwritten. The EVP_PKEY_CTX value returned must not be freed +directly by the application (it will be freed automatically when the EVP_MD_CTX +is freed). The digest B<type> may be NULL if the signing algorithm supports it. EVP_DigestSignUpdate() hashes B<cnt> bytes of data at B<d> into the signature context B<ctx>. This function can be called several times on the diff --git a/doc/crypto/EVP_DigestVerifyInit.pod b/doc/crypto/EVP_DigestVerifyInit.pod index 347c511..2e2c0fd 100644 --- a/doc/crypto/EVP_DigestVerifyInit.pod +++ b/doc/crypto/EVP_DigestVerifyInit.pod @@ -19,9 +19,12 @@ The EVP signature routines are a high level interface to digital signatures. EVP_DigestVerifyInit() sets up verification context B<ctx> to use digest B<type> from ENGINE B<impl> and public key B<pkey>. B<ctx> must be initialized -with EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL the +with EVP_MD_CTX_init() before calling this function. If B<pctx> is not NULL, the EVP_PKEY_CTX of the verification operation will be written to B<*pctx>: this -can be used to set alternative verification options. +can be used to set alternative verification options. Note that any existing +value in B<*pctx> is overwritten. The EVP_PKEY_CTX value returned must not be +freed directly by the application (it will be freed automatically when the +EVP_MD_CTX is freed). EVP_DigestVerifyUpdate() hashes B<cnt> bytes of data at B<d> into the verification context B<ctx>. This function can be called several times on the diff --git a/doc/crypto/OPENSSL_VERSION_NUMBER.pod b/doc/crypto/OPENSSL_VERSION_NUMBER.pod index f7ca7cb..02eabd7 100644 --- a/doc/crypto/OPENSSL_VERSION_NUMBER.pod +++ b/doc/crypto/OPENSSL_VERSION_NUMBER.pod @@ -2,12 +2,14 @@ =head1 NAME -OPENSSL_VERSION_NUMBER, SSLeay, SSLeay_version - get OpenSSL version number +OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT, SSLeay, SSLeay_version +- get OpenSSL version number =head1 SYNOPSIS #include <openssl/opensslv.h> #define OPENSSL_VERSION_NUMBER 0xnnnnnnnnnL + #define OPENSSL_VERSION_TEXT "OpenSSL x.y.z xx XXX xxxx" #include <openssl/crypto.h> long SSLeay(void); @@ -43,9 +45,12 @@ Version 0.9.5a had an interim interpretation that is like the current one, except the patch level got the highest bit set, to keep continuity. The number was therefore 0x0090581f. - For backward compatibility, SSLEAY_VERSION_NUMBER is also defined. +OPENSSL_VERSION_TEXT is the text variant of the version number and the +release date. For example, +"OpenSSL 1.0.1a 15 Oct 2015". + SSLeay() returns this number. The return value can be compared to the macro to make sure that the correct version of the library has been loaded, especially when using DLLs on Windows systems. diff --git a/engines/e_capi.c b/engines/e_capi.c index 8c08872..7ec6de6 100644 --- a/engines/e_capi.c +++ b/engines/e_capi.c @@ -4,7 +4,7 @@ * project. */ /* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * Copyright (c) 2008-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -900,6 +900,8 @@ int capi_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *tmpbuf; CAPI_KEY *capi_key; CAPI_CTX *ctx; + DWORD flags = 0; + ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n"); @@ -910,12 +912,23 @@ int capi_rsa_priv_dec(int flen, const unsigned char *from, return -1; } - if (padding != RSA_PKCS1_PADDING) { - char errstr[10]; - BIO_snprintf(errstr, 10, "%d", padding); - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); - ERR_add_error_data(2, "padding=", errstr); - return -1; + switch (padding) { + case RSA_PKCS1_PADDING: + /* Nothing to do */ + break; +#ifdef CRYPT_DECRYPT_RSA_NO_PADDING_CHECK + case RSA_NO_PADDING: + flags = CRYPT_DECRYPT_RSA_NO_PADDING_CHECK; + break; +#endif + default: + { + char errstr[10]; + BIO_snprintf(errstr, 10, "%d", padding); + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); + ERR_add_error_data(2, "padding=", errstr); + return -1; + } } /* Create temp reverse order version of input */ @@ -927,14 +940,17 @@ int capi_rsa_priv_dec(int flen, const unsigned char *from, tmpbuf[flen - i - 1] = from[i]; /* Finally decrypt it */ - if (!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen)) { + if (!CryptDecrypt(capi_key->key, 0, TRUE, flags, tmpbuf, &flen)) { CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR); capi_addlasterror(); + OPENSSL_cleanse(tmpbuf, flen); OPENSSL_free(tmpbuf); return -1; - } else + } else { memcpy(to, tmpbuf, flen); + } + OPENSSL_cleanse(tmpbuf, flen); OPENSSL_free(tmpbuf); return flen; diff --git a/openssl.spec b/openssl.spec index 7f40595..f1061be 100644 --- a/openssl.spec +++ b/openssl.spec @@ -7,7 +7,7 @@ Release: 1 Summary: Secure Sockets Layer and cryptography libraries and tools Name: openssl -Version: 1.0.2p +Version: 1.0.2q Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz License: OpenSSL Group: System Environment/Libraries diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index f5deddf..23aa9db 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -293,14 +293,12 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) 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); + /* Must be a duplicate so ignore it */ if (rdata->rbuf.buf != NULL) OPENSSL_free(rdata->rbuf.buf); OPENSSL_free(rdata); pitem_free(item); - return (-1); } return (1); diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index ccdf00f..58dcddf 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -1406,11 +1406,17 @@ static int ssl_cipher_process_rulestr(const char *rule_str, static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, const char **prule_str) { - unsigned int suiteb_flags = 0, suiteb_comb2 = 0; + unsigned int suiteb_flags = 0; +# ifndef OPENSSL_NO_ECDH + unsigned int suiteb_comb2 = 0; +#endif + if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) { suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY; } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) { +# ifndef OPENSSL_NO_ECDH suiteb_comb2 = 1; +# endif suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) { suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index aa0cbdb..cfcfe76 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2259,10 +2259,10 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) int rsa_tmp_export, dh_tmp_export, kl; unsigned long mask_k, mask_a, emask_k, emask_a; #ifndef OPENSSL_NO_ECDSA - int have_ecc_cert, ecdsa_ok, ecc_pkey_size; + int have_ecc_cert, ecdsa_ok; #endif #ifndef OPENSSL_NO_ECDH - int have_ecdh_tmp, ecdh_ok; + int have_ecdh_tmp, ecdh_ok, ecc_pkey_size; #endif #ifndef OPENSSL_NO_EC X509 *x = NULL; @@ -2405,7 +2405,9 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) if (!(cpk->valid_flags & CERT_PKEY_SIGN)) ecdsa_ok = 0; ecc_pkey = X509_get_pubkey(x); +# ifndef OPENSSL_NO_ECDH ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; +# endif EVP_PKEY_free(ecc_pkey); if ((x->sig_alg) && (x->sig_alg->algorithm)) { signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); @@ -2467,7 +2469,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_ECDH int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) { diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 8cb8816..55f918d 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -500,7 +500,11 @@ static int tls1_get_curvelist(SSL *s, int sess, } else # endif { - if (!s->server || s->cert->ecdh_tmp_auto) { + if (!s->server +# ifndef OPENSSL_NO_ECDH + || s->cert->ecdh_tmp_auto +# endif + ) { *pcurves = eccurves_auto; pcurveslen = sizeof(eccurves_auto); } else { diff --git a/test/maketests.com b/test/maketests.com index f4e418b..c0e1730 100644 --- a/test/maketests.com +++ b/test/maketests.com @@ -151,7 +151,7 @@ $ TEST_FILES = "BNTEST,ECTEST,ECDSATEST,ECDHTEST,IDEATEST,"+ - "ASN1TEST,V3NAMETEST,HEARTBEAT_TEST,"+ - "CONSTANT_TIME_TEST,VERIFY_EXTRA_TEST,"+ - "CLIENTHELLOTEST,SSLV2CONFTEST,DTLSTEST,"+ - - "BAD_DTLS_TEST,FATALERRTEST" + "BAD_DTLS_TEST,FATALERRTEST,X509_TIME_TEST" $! $! Additional directory information. $ T_D_BNTEST := [-.crypto.bn] diff --git a/test/tests.com b/test/tests.com index 27b01b6..21867bf 100644 --- a/test/tests.com +++ b/test/tests.com @@ -58,7 +58,7 @@ $ tests := - 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_fatalerr + test_dtls,test_bad_dtls,test_fatalerr,test_x509_time $ endif $ tests = f$edit(tests,"COLLAPSE") $ @@ -107,6 +107,7 @@ $ BADDTLSTEST := bad_dtls_test $ SSLV2CONFTEST := sslv2conftest $ DTLSTEST := dtlstest $ FATALERRTEST := fatalerrtest +$ X509TIMETEST := x509_time_test $! $ tests_i = 0 $ loop_tests: @@ -415,6 +416,11 @@ $ write sys$output "''START' test_fatalerrtest" $ mcr 'texe_dir''fatalerrtest' 'ROOT'.APPS]server.pem 'ROOT'.APPS]server.pem $ return $ +$ test_x509_time: +$ write sys$output "''START' test_x509_time" +$ mcr 'texe_dir''x509timetest' +$ return +$ $ test_sslv2conftest: $ write sys$output "''START' test_sslv2conftest" $ mcr 'texe_dir''sslv2conftest' diff --git a/tools/c_rehash.bak b/tools/c_rehash.bak new file mode 100644 index 0000000..6a27c02 --- /dev/null +++ b/tools/c_rehash.bak @@ -0,0 +1,210 @@ +#!/usr/bin/perl + +# Perl c_rehash script, scan all files in a directory +# and add symbolic links to their hash values. + +my $dir = "/usr/local/ssl"; +my $prefix = "/usr/local/ssl"; + +my $openssl = $ENV{OPENSSL} || "openssl"; +my $pwd; +my $x509hash = "-subject_hash"; +my $crlhash = "-hash"; +my $verbose = 0; +my $symlink_exists=eval {symlink("",""); 1}; +my $removelinks = 1; + +## Parse flags. +while ( $ARGV[0] =~ /^-/ ) { + my $flag = shift @ARGV; + last if ( $flag eq '--'); + if ( $flag eq '-old') { + $x509hash = "-subject_hash_old"; + $crlhash = "-hash_old"; + } elsif ( $flag eq '-h') { + help(); + } elsif ( $flag eq '-n' ) { + $removelinks = 0; + } elsif ( $flag eq '-v' ) { + $verbose++; + } + else { + print STDERR "Usage error; try -help.\n"; + exit 1; + } +} + +sub help { + print "Usage: c_rehash [-old] [-h] [-v] [dirs...]\n"; + print " -old use old-style digest\n"; + print " -h print this help text\n"; + print " -v print files removed and linked\n"; + exit 0; +} + +eval "require Cwd"; +if (defined(&Cwd::getcwd)) { + $pwd=Cwd::getcwd(); +} else { + $pwd=`pwd`; + chomp($pwd); +} + +# DOS/Win32 or Unix delimiter? Prefix our installdir, then search. +my $path_delim = ($pwd =~ /^[a-z]\:/i) ? ';' : ':'; +$ENV{PATH} = "$prefix/bin" . ($ENV{PATH} ? $path_delim . $ENV{PATH} : ""); + +if(! -x $openssl) { + my $found = 0; + foreach (split /$path_delim/, $ENV{PATH}) { + if(-x "$_/$openssl") { + $found = 1; + $openssl = "$_/$openssl"; + last; + } + } + if($found == 0) { + print STDERR "c_rehash: rehashing skipped ('openssl' program not available)\n"; + exit 0; + } +} + +if(@ARGV) { + @dirlist = @ARGV; +} elsif($ENV{SSL_CERT_DIR}) { + @dirlist = split /$path_delim/, $ENV{SSL_CERT_DIR}; +} else { + $dirlist[0] = "$dir/certs"; +} + +if (-d $dirlist[0]) { + chdir $dirlist[0]; + $openssl="$pwd/$openssl" if (!-x $openssl); + chdir $pwd; +} + +foreach (@dirlist) { + if(-d $_ and -w $_) { + hash_dir($_); + } +} + +sub hash_dir { + my %hashlist; + print "Doing $_[0]\n"; + chdir $_[0]; + opendir(DIR, "."); + my @flist = readdir(DIR); + closedir DIR; + if ( $removelinks ) { + # Delete any existing symbolic links + foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) { + if(-l $_) { + unlink $_; + print "unlink $_" if $verbose; + } + } + } + FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) { + # Check to see if certificates and/or CRLs present. + my ($cert, $crl) = check_file($fname); + if(!$cert && !$crl) { + print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n"; + next; + } + link_hash_cert($fname) if($cert); + link_hash_crl($fname) if($crl); + } +} + +sub check_file { + my ($is_cert, $is_crl) = (0,0); + my $fname = $_[0]; + open IN, $fname; + while(<IN>) { + if(/^-----BEGIN (.*)-----/) { + my $hdr = $1; + if($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) { + $is_cert = 1; + last if($is_crl); + } elsif($hdr eq "X509 CRL") { + $is_crl = 1; + last if($is_cert); + } + } + } + close IN; + return ($is_cert, $is_crl); +} + + +# Link a certificate to its subject name hash value, each hash is of +# the form <hash>.<n> where n is an integer. If the hash value already exists +# then we need to up the value of n, unless its a duplicate in which +# case we skip the link. We check for duplicates by comparing the +# certificate fingerprints + +sub link_hash_cert { + my $fname = $_[0]; + $fname =~ s/'/'\\''/g; + my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`; + chomp $hash; + chomp $fprint; + $fprint =~ s/^.*=//; + $fprint =~ tr/://d; + my $suffix = 0; + # Search for an unused hash filename + while(exists $hashlist{"$hash.$suffix"}) { + # Hash matches: if fingerprint matches its a duplicate cert + if($hashlist{"$hash.$suffix"} eq $fprint) { + print STDERR "WARNING: Skipping duplicate certificate $fname\n"; + return; + } + $suffix++; + } + $hash .= ".$suffix"; + if ($symlink_exists) { + symlink $fname, $hash; + print "link $fname -> $hash\n" if $verbose; + } else { + open IN,"<$fname" or die "can't open $fname for read"; + open OUT,">$hash" or die "can't open $hash for write"; + print OUT <IN>; # does the job for small text files + close OUT; + close IN; + print "copy $fname -> $hash\n" if $verbose; + } + $hashlist{$hash} = $fprint; +} + +# Same as above except for a CRL. CRL links are of the form <hash>.r<n> + +sub link_hash_crl { + my $fname = $_[0]; + $fname =~ s/'/'\\''/g; + my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`; + chomp $hash; + chomp $fprint; + $fprint =~ s/^.*=//; + $fprint =~ tr/://d; + my $suffix = 0; + # Search for an unused hash filename + while(exists $hashlist{"$hash.r$suffix"}) { + # Hash matches: if fingerprint matches its a duplicate cert + if($hashlist{"$hash.r$suffix"} eq $fprint) { + print STDERR "WARNING: Skipping duplicate CRL $fname\n"; + return; + } + $suffix++; + } + $hash .= ".r$suffix"; + if ($symlink_exists) { + symlink $fname, $hash; + print "link $fname -> $hash\n" if $verbose; + } else { + system ("cp", $fname, $hash); + print "cp $fname -> $hash\n" if $verbose; + } + $hashlist{$hash} = $fprint; +} + @@ -11,7 +11,6 @@ if [ "$1" = "-MD" ]; then MAKEDEPEND="$MAKEDEPEND $1" shift done - shift fi if [ "$MAKEDEPEND" = "" ]; then MAKEDEPEND=makedepend; fi diff --git a/util/libeay.num b/util/libeay.num index f5b4f21..2e52214 100755 --- a/util/libeay.num +++ b/util/libeay.num @@ -4431,3 +4431,4 @@ EVP_PKEY_meth_get_decrypt 4785 EXIST::FUNCTION: EVP_PKEY_meth_get_cleanup 4786 EXIST::FUNCTION: EVP_PKEY_meth_get_encrypt 4787 EXIST::FUNCTION: EVP_PKEY_meth_get_copy 4788 EXIST::FUNCTION: +ossl_safe_getenv 4789 EXIST::FUNCTION: |