Module Name: src
Committed By: snj
Date: Sun Oct 19 20:11:09 UTC 2014
Modified Files:
src/crypto/dist/openssl/apps [netbsd-5-2]: s_client.c
src/crypto/dist/openssl/crypto [netbsd-5-2]: LPdir_vms.c LPdir_win.c
Makefile
src/crypto/dist/openssl/crypto/bn [netbsd-5-2]: bn_exp.c exptest.c
src/crypto/dist/openssl/crypto/bn/asm [netbsd-5-2]: x86_64-gcc.c
src/crypto/dist/openssl/crypto/dsa [netbsd-5-2]: dsa_ameth.c
src/crypto/dist/openssl/crypto/ec [netbsd-5-2]: ec.h ec_ameth.c
ec_asn1.c ec_key.c ecp_smpl.c
src/crypto/dist/openssl/crypto/err [netbsd-5-2]: openssl.ec
src/crypto/dist/openssl/crypto/evp [netbsd-5-2]: Makefile evp_enc.c
src/crypto/dist/openssl/crypto/pkcs7 [netbsd-5-2]: pkcs7.h
src/crypto/dist/openssl/crypto/rsa [netbsd-5-2]: Makefile rsa.h
rsa_err.c rsa_oaep.c rsa_pk1.c rsa_sign.c
src/crypto/dist/openssl/doc/apps [netbsd-5-2]: s_client.pod
src/crypto/dist/openssl/doc/crypto [netbsd-5-2]: BIO_s_accept.pod
EVP_DigestInit.pod EVP_DigestVerifyInit.pod EVP_EncryptInit.pod
EVP_PKEY_set1_RSA.pod EVP_PKEY_sign.pod
src/crypto/dist/openssl/doc/ssl [netbsd-5-2]: SSL_CTX_set_mode.pod
SSL_CTX_set_tmp_dh_callback.pod
src/crypto/dist/openssl/ssl [netbsd-5-2]: Makefile s23_clnt.c
s23_srvr.c s2_lib.c s3_clnt.c s3_enc.c s3_lib.c s3_pkt.c s3_srvr.c
ssl-lib.com ssl.h ssl3.h ssl_err.c ssl_lib.c t1_enc.c t1_lib.c
tls1.h
src/crypto/dist/openssl/test [netbsd-5-2]: Makefile
Added Files:
src/crypto/dist/openssl/crypto [netbsd-5-2]: constant_time_locl.h
constant_time_test.c
src/crypto/dist/openssl/doc/crypto [netbsd-5-2]: CMS_add1_signer.pod
src/crypto/dist/openssl/test [netbsd-5-2]: constant_time_test.c
Log Message:
Apply patch (requested by spz in ticket #1927):
Apply OpenSSL security fixes derived from the diff between
OpenSSL 1.0.0n and 1.0.0o, fixing CVE-2014-3567, CVE-2014-3568,
and adding POODLE mitigation via support for TLS_FALLBACK_SCSV.
To generate a diff of this commit:
cvs rdiff -u -r1.1.1.11 -r1.1.1.11.2.1 \
src/crypto/dist/openssl/apps/s_client.c
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.38.1 \
src/crypto/dist/openssl/crypto/LPdir_vms.c
cvs rdiff -u -r1.1.1.2 -r1.1.1.2.2.1 \
src/crypto/dist/openssl/crypto/LPdir_win.c
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.2.1 src/crypto/dist/openssl/crypto/Makefile
cvs rdiff -u -r0 -r1.1.6.2 \
src/crypto/dist/openssl/crypto/constant_time_locl.h \
src/crypto/dist/openssl/crypto/constant_time_test.c
cvs rdiff -u -r1.3 -r1.3.2.1 src/crypto/dist/openssl/crypto/bn/bn_exp.c
cvs rdiff -u -r1.4 -r1.4.2.1 src/crypto/dist/openssl/crypto/bn/exptest.c
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.36.1 \
src/crypto/dist/openssl/crypto/bn/asm/x86_64-gcc.c
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.6.1 \
src/crypto/dist/openssl/crypto/dsa/dsa_ameth.c
cvs rdiff -u -r1.6 -r1.6.2.1 src/crypto/dist/openssl/crypto/ec/ec.h
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.6.1 \
src/crypto/dist/openssl/crypto/ec/ec_ameth.c
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.30.1 \
src/crypto/dist/openssl/crypto/ec/ec_asn1.c
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.38.1 \
src/crypto/dist/openssl/crypto/ec/ec_key.c
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.38.1 \
src/crypto/dist/openssl/crypto/ec/ecp_smpl.c
cvs rdiff -u -r1.1.1.7 -r1.1.1.7.2.1 \
src/crypto/dist/openssl/crypto/err/openssl.ec
cvs rdiff -u -r1.1.1.5 -r1.1.1.5.2.1 \
src/crypto/dist/openssl/crypto/evp/Makefile
cvs rdiff -u -r1.1.1.8 -r1.1.1.8.30.1 \
src/crypto/dist/openssl/crypto/evp/evp_enc.c
cvs rdiff -u -r1.8 -r1.8.2.1 src/crypto/dist/openssl/crypto/pkcs7/pkcs7.h
cvs rdiff -u -r1.1.1.4 -r1.1.1.4.2.1 \
src/crypto/dist/openssl/crypto/rsa/Makefile
cvs rdiff -u -r1.14 -r1.14.2.1 src/crypto/dist/openssl/crypto/rsa/rsa.h
cvs rdiff -u -r1.7 -r1.7.2.1 src/crypto/dist/openssl/crypto/rsa/rsa_err.c
cvs rdiff -u -r1.1.1.7 -r1.1.1.7.38.1 \
src/crypto/dist/openssl/crypto/rsa/rsa_oaep.c
cvs rdiff -u -r1.1.1.3 -r1.1.1.3.50.1 \
src/crypto/dist/openssl/crypto/rsa/rsa_pk1.c
cvs rdiff -u -r1.5 -r1.5.2.1 src/crypto/dist/openssl/crypto/rsa/rsa_sign.c
cvs rdiff -u -r1.8 -r1.8.2.1 src/crypto/dist/openssl/doc/apps/s_client.pod
cvs rdiff -u -r1.1.1.2 -r1.1.1.2.50.1 \
src/crypto/dist/openssl/doc/crypto/BIO_s_accept.pod
cvs rdiff -u -r0 -r1.1.6.2 \
src/crypto/dist/openssl/doc/crypto/CMS_add1_signer.pod
cvs rdiff -u -r1.6 -r1.6.38.1 \
src/crypto/dist/openssl/doc/crypto/EVP_DigestInit.pod \
src/crypto/dist/openssl/doc/crypto/EVP_EncryptInit.pod
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.6.1 \
src/crypto/dist/openssl/doc/crypto/EVP_DigestVerifyInit.pod \
src/crypto/dist/openssl/doc/crypto/EVP_PKEY_sign.pod
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.50.1 \
src/crypto/dist/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod
cvs rdiff -u -r1.1.1.2 -r1.1.1.2.50.1 \
src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_mode.pod
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.54.1 \
src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
cvs rdiff -u -r1.3 -r1.3.2.1 src/crypto/dist/openssl/ssl/Makefile
cvs rdiff -u -r1.1.1.10 -r1.1.1.10.2.1 src/crypto/dist/openssl/ssl/s23_clnt.c
cvs rdiff -u -r1.6.2.1 -r1.6.2.2 src/crypto/dist/openssl/ssl/s23_srvr.c
cvs rdiff -u -r1.12 -r1.12.2.1 src/crypto/dist/openssl/ssl/s2_lib.c
cvs rdiff -u -r1.12.4.3.4.2 -r1.12.4.3.4.3 \
src/crypto/dist/openssl/ssl/s3_clnt.c
cvs rdiff -u -r1.1.1.12.4.2 -r1.1.1.12.4.2.2.1 \
src/crypto/dist/openssl/ssl/s3_enc.c
cvs rdiff -u -r1.14.4.1 -r1.14.4.1.6.1 src/crypto/dist/openssl/ssl/s3_lib.c
cvs rdiff -u -r1.9.4.3.6.1 -r1.9.4.3.6.2 src/crypto/dist/openssl/ssl/s3_pkt.c
cvs rdiff -u -r1.15.4.4.4.1 -r1.15.4.4.4.2 \
src/crypto/dist/openssl/ssl/s3_srvr.c
cvs rdiff -u -r1.1.1.6 -r1.1.1.6.38.1 src/crypto/dist/openssl/ssl/ssl-lib.com
cvs rdiff -u -r1.18.4.1 -r1.18.4.1.6.1 src/crypto/dist/openssl/ssl/ssl.h
cvs rdiff -u -r1.8.2.1 -r1.8.2.2 src/crypto/dist/openssl/ssl/ssl3.h
cvs rdiff -u -r1.12.4.1 -r1.12.4.1.6.1 src/crypto/dist/openssl/ssl/ssl_err.c
cvs rdiff -u -r1.5 -r1.5.2.1 src/crypto/dist/openssl/ssl/ssl_lib.c
cvs rdiff -u -r1.1.1.12.4.1 -r1.1.1.12.4.1.6.1 \
src/crypto/dist/openssl/ssl/t1_enc.c
cvs rdiff -u -r1.2.4.3.2.1 -r1.2.4.3.2.2 src/crypto/dist/openssl/ssl/t1_lib.c
cvs rdiff -u -r1.1.1.8 -r1.1.1.8.2.1 src/crypto/dist/openssl/ssl/tls1.h
cvs rdiff -u -r1.1.1.7 -r1.1.1.7.2.1 src/crypto/dist/openssl/test/Makefile
cvs rdiff -u -r0 -r1.1.6.2 src/crypto/dist/openssl/test/constant_time_test.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/crypto/dist/openssl/apps/s_client.c
diff -u src/crypto/dist/openssl/apps/s_client.c:1.1.1.11 src/crypto/dist/openssl/apps/s_client.c:1.1.1.11.2.1
--- src/crypto/dist/openssl/apps/s_client.c:1.1.1.11 Fri May 9 21:34:13 2008
+++ src/crypto/dist/openssl/apps/s_client.c Sun Oct 19 20:11:08 2014
@@ -314,6 +314,7 @@ static void sc_usage(void)
BIO_printf(bio_err," -ssl3 - just use SSLv3\n");
BIO_printf(bio_err," -tls1 - just use TLSv1\n");
BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
+ BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
BIO_printf(bio_err," -mtu - set the MTU\n");
BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
@@ -422,6 +423,7 @@ int MAIN(int argc, char **argv)
char *sess_out = NULL;
struct sockaddr peer;
int peerlen = sizeof(peer);
+ int fallback_scsv = 0;
int enable_timeouts = 0 ;
long socket_mtu = 0;
@@ -595,6 +597,10 @@ int MAIN(int argc, char **argv)
socket_mtu = atol(*(++argv));
}
#endif
+ else if (strcmp(*argv,"-fallback_scsv") == 0)
+ {
+ fallback_scsv = 1;
+ }
else if (strcmp(*argv,"-bugs") == 0)
bugs=1;
else if (strcmp(*argv,"-keyform") == 0)
@@ -848,6 +854,10 @@ bad:
SSL_set_session(con, sess);
SSL_SESSION_free(sess);
}
+
+ if (fallback_scsv)
+ SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
+
#ifndef OPENSSL_NO_TLSEXT
if (servername != NULL)
{
Index: src/crypto/dist/openssl/crypto/LPdir_vms.c
diff -u src/crypto/dist/openssl/crypto/LPdir_vms.c:1.1.1.1 src/crypto/dist/openssl/crypto/LPdir_vms.c:1.1.1.1.38.1
--- src/crypto/dist/openssl/crypto/LPdir_vms.c:1.1.1.1 Fri Nov 25 03:03:55 2005
+++ src/crypto/dist/openssl/crypto/LPdir_vms.c Sun Oct 19 20:11:08 2014
@@ -1,4 +1,3 @@
-/* $LP: LPlib/source/LPdir_vms.c,v 1.20 2004/08/26 13:36:05 _cvs_levitte Exp $ */
/*
* Copyright (c) 2004, Richard Levitte <[email protected]>
* All rights reserved.
@@ -82,6 +81,12 @@ const char *LP_find_file(LP_DIR_CTX **ct
size_t filespeclen = strlen(directory);
char *filespec = NULL;
+ if (filespeclen == 0)
+ {
+ errno = ENOENT;
+ return 0;
+ }
+
/* MUST be a VMS directory specification! Let's estimate if it is. */
if (directory[filespeclen-1] != ']'
&& directory[filespeclen-1] != '>'
Index: src/crypto/dist/openssl/crypto/LPdir_win.c
diff -u src/crypto/dist/openssl/crypto/LPdir_win.c:1.1.1.2 src/crypto/dist/openssl/crypto/LPdir_win.c:1.1.1.2.2.1
--- src/crypto/dist/openssl/crypto/LPdir_win.c:1.1.1.2 Fri May 9 21:34:14 2008
+++ src/crypto/dist/openssl/crypto/LPdir_win.c Sun Oct 19 20:11:08 2014
@@ -1,4 +1,3 @@
-/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
/*
* Copyright (c) 2004, Richard Levitte <[email protected]>
* All rights reserved.
@@ -63,6 +62,16 @@ const char *LP_find_file(LP_DIR_CTX **ct
errno = 0;
if (*ctx == NULL)
{
+ const char *extdir = directory;
+ char *extdirbuf = NULL;
+ size_t dirlen = strlen (directory);
+
+ if (dirlen == 0)
+ {
+ errno = ENOENT;
+ return 0;
+ }
+
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
if (*ctx == NULL)
{
@@ -71,15 +80,35 @@ const char *LP_find_file(LP_DIR_CTX **ct
}
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
+ if (directory[dirlen-1] != '*')
+ {
+ extdirbuf = (char *)malloc(dirlen + 3);
+ if (extdirbuf == NULL)
+ {
+ free(*ctx);
+ *ctx = NULL;
+ errno = ENOMEM;
+ return 0;
+ }
+ if (directory[dirlen-1] != '/' && directory[dirlen-1] != '\\')
+ extdir = strcat(strcpy (extdirbuf,directory),"/*");
+ else
+ extdir = strcat(strcpy (extdirbuf,directory),"*");
+ }
+
if (sizeof(TCHAR) != sizeof(char))
{
TCHAR *wdir = NULL;
/* len_0 denotes string length *with* trailing 0 */
- size_t index = 0,len_0 = strlen(directory) + 1;
+ size_t index = 0,len_0 = strlen(extdir) + 1;
- wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
+ wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
if (wdir == NULL)
{
+ if (extdirbuf != NULL)
+ {
+ free (extdirbuf);
+ }
free(*ctx);
*ctx = NULL;
errno = ENOMEM;
@@ -87,17 +116,23 @@ const char *LP_find_file(LP_DIR_CTX **ct
}
#ifdef LP_MULTIBYTE_AVAILABLE
- if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, len_0))
+ if (!MultiByteToWideChar(CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
#endif
for (index = 0; index < len_0; index++)
- wdir[index] = (TCHAR)directory[index];
+ wdir[index] = (TCHAR)extdir[index];
(*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
free(wdir);
}
else
- (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
+ {
+ (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
+ }
+ if (extdirbuf != NULL)
+ {
+ free (extdirbuf);
+ }
if ((*ctx)->handle == INVALID_HANDLE_VALUE)
{
@@ -114,7 +149,6 @@ const char *LP_find_file(LP_DIR_CTX **ct
return 0;
}
}
-
if (sizeof(TCHAR) != sizeof(char))
{
TCHAR *wdir = (*ctx)->ctx.cFileName;
Index: src/crypto/dist/openssl/crypto/Makefile
diff -u src/crypto/dist/openssl/crypto/Makefile:1.1.1.4 src/crypto/dist/openssl/crypto/Makefile:1.1.1.4.2.1
--- src/crypto/dist/openssl/crypto/Makefile:1.1.1.4 Fri May 9 21:34:14 2008
+++ src/crypto/dist/openssl/crypto/Makefile Sun Oct 19 20:11:08 2014
@@ -31,6 +31,7 @@ CPUID_OBJ=mem_clr.o
LIBS=
GENERAL=Makefile README crypto-lib.com install.com
+TEST=constant_time_test.c
LIB= $(TOP)/libcrypto.a
SHARED_LIB= libcrypto$(SHLIB_EXT)
@@ -41,7 +42,8 @@ SRC= $(LIBSRC)
EXHEADER= crypto.h opensslv.h opensslconf.h ebcdic.h symhacks.h \
ossl_typ.h
-HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h $(EXHEADER)
+HEADER= cryptlib.h buildinf.h md32_common.h o_time.h o_str.h o_dir.h \
+ constant_time_locl.h $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
Index: src/crypto/dist/openssl/crypto/bn/bn_exp.c
diff -u src/crypto/dist/openssl/crypto/bn/bn_exp.c:1.3 src/crypto/dist/openssl/crypto/bn/bn_exp.c:1.3.2.1
--- src/crypto/dist/openssl/crypto/bn/bn_exp.c:1.3 Fri May 9 21:49:39 2008
+++ src/crypto/dist/openssl/crypto/bn/bn_exp.c Sun Oct 19 20:11:08 2014
@@ -766,7 +766,14 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_
bits = BN_num_bits(p);
if (bits == 0)
{
- ret = BN_one(rr);
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m))
+ {
+ ret = 1;
+ BN_zero(rr);
+ }
+ else
+ ret = BN_one(rr);
return ret;
}
if (a == 0)
Index: src/crypto/dist/openssl/crypto/bn/exptest.c
diff -u src/crypto/dist/openssl/crypto/bn/exptest.c:1.4 src/crypto/dist/openssl/crypto/bn/exptest.c:1.4.2.1
--- src/crypto/dist/openssl/crypto/bn/exptest.c:1.4 Fri May 9 21:49:39 2008
+++ src/crypto/dist/openssl/crypto/bn/exptest.c Sun Oct 19 20:11:08 2014
@@ -71,6 +71,43 @@
static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+/* test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success. */
+static int test_exp_mod_zero() {
+ BIGNUM a, p, m;
+ BIGNUM r;
+ BN_CTX *ctx = BN_CTX_new();
+ int ret = 1;
+
+ BN_init(&m);
+ BN_one(&m);
+
+ BN_init(&a);
+ BN_one(&a);
+
+ BN_init(&p);
+ BN_zero(&p);
+
+ BN_init(&r);
+ BN_mod_exp(&r, &a, &p, &m, ctx);
+ BN_CTX_free(ctx);
+
+ if (BN_is_zero(&r))
+ ret = 0;
+ else
+ {
+ printf("1**0 mod 1 = ");
+ BN_print_fp(stdout, &r);
+ printf(", should be 0\n");
+ }
+
+ BN_free(&r);
+ BN_free(&a);
+ BN_free(&p);
+ BN_free(&m);
+
+ return ret;
+}
+
int main(int argc, char *argv[])
{
BN_CTX *ctx;
@@ -196,7 +233,13 @@ int main(int argc, char *argv[])
ERR_remove_thread_state(NULL);
CRYPTO_mem_leaks(out);
BIO_free(out);
- printf(" done\n");
+ printf("\n");
+
+ if (test_exp_mod_zero() != 0)
+ goto err;
+
+ printf("done\n");
+
EXIT(0);
err:
ERR_load_crypto_strings();
Index: src/crypto/dist/openssl/crypto/bn/asm/x86_64-gcc.c
diff -u src/crypto/dist/openssl/crypto/bn/asm/x86_64-gcc.c:1.1.1.4 src/crypto/dist/openssl/crypto/bn/asm/x86_64-gcc.c:1.1.1.4.36.1
--- src/crypto/dist/openssl/crypto/bn/asm/x86_64-gcc.c:1.1.1.4 Mon Nov 13 21:17:38 2006
+++ src/crypto/dist/openssl/crypto/bn/asm/x86_64-gcc.c Sun Oct 19 20:11:08 2014
@@ -180,7 +180,7 @@ BN_ULONG bn_add_words (BN_ULONG *rp, BN_
if (n <= 0) return 0;
- asm (
+ asm volatile (
" subq %2,%2 \n"
".align 16 \n"
"1: movq (%4,%2,8),%0 \n"
@@ -191,7 +191,7 @@ BN_ULONG bn_add_words (BN_ULONG *rp, BN_
" sbbq %0,%0 \n"
: "=&a"(ret),"+c"(n),"=&r"(i)
: "r"(rp),"r"(ap),"r"(bp)
- : "cc"
+ : "cc", "memory"
);
return ret&1;
@@ -203,7 +203,7 @@ BN_ULONG bn_sub_words (BN_ULONG *rp, BN_
if (n <= 0) return 0;
- asm (
+ asm volatile (
" subq %2,%2 \n"
".align 16 \n"
"1: movq (%4,%2,8),%0 \n"
@@ -214,7 +214,7 @@ BN_ULONG bn_sub_words (BN_ULONG *rp, BN_
" sbbq %0,%0 \n"
: "=&a"(ret),"+c"(n),"=&r"(i)
: "r"(rp),"r"(ap),"r"(bp)
- : "cc"
+ : "cc", "memory"
);
return ret&1;
Index: src/crypto/dist/openssl/crypto/dsa/dsa_ameth.c
diff -u src/crypto/dist/openssl/crypto/dsa/dsa_ameth.c:1.1.1.1 src/crypto/dist/openssl/crypto/dsa/dsa_ameth.c:1.1.1.1.6.1
--- src/crypto/dist/openssl/crypto/dsa/dsa_ameth.c:1.1.1.1 Fri May 9 21:34:25 2008
+++ src/crypto/dist/openssl/crypto/dsa/dsa_ameth.c Sun Oct 19 20:11:08 2014
@@ -299,6 +299,12 @@ static int dsa_priv_encode(PKCS8_PRIV_KE
unsigned char *dp = NULL;
int dplen;
+ if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key)
+ {
+ DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_MISSING_PARAMETERS);
+ goto err;
+ }
+
params = ASN1_STRING_new();
if (!params)
@@ -646,4 +652,3 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth
old_dsa_priv_encode
}
};
-
Index: src/crypto/dist/openssl/crypto/ec/ec.h
diff -u src/crypto/dist/openssl/crypto/ec/ec.h:1.6 src/crypto/dist/openssl/crypto/ec/ec.h:1.6.2.1
--- src/crypto/dist/openssl/crypto/ec/ec.h:1.6 Fri May 9 21:49:40 2008
+++ src/crypto/dist/openssl/crypto/ec/ec.h Sun Oct 19 20:11:08 2014
@@ -609,7 +609,7 @@ int EC_POINT_cmp(const EC_GROUP *group,
int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
-/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
+/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i]
* \param group underlying EC_GROUP object
* \param r EC_POINT object for the result
* \param n BIGNUM with the multiplier for the group generator (optional)
Index: src/crypto/dist/openssl/crypto/ec/ec_ameth.c
diff -u src/crypto/dist/openssl/crypto/ec/ec_ameth.c:1.1.1.1 src/crypto/dist/openssl/crypto/ec/ec_ameth.c:1.1.1.1.6.1
--- src/crypto/dist/openssl/crypto/ec/ec_ameth.c:1.1.1.1 Fri May 9 21:34:26 2008
+++ src/crypto/dist/openssl/crypto/ec/ec_ameth.c Sun Oct 19 20:11:08 2014
@@ -452,14 +452,16 @@ static int do_EC_KEY_print(BIO *bp, cons
if (ktype > 0)
{
public_key = EC_KEY_get0_public_key(x);
- if ((pub_key = EC_POINT_point2bn(group, public_key,
- EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
+ if (public_key != NULL)
{
- reason = ERR_R_EC_LIB;
- goto err;
- }
- if (pub_key)
+ if ((pub_key = EC_POINT_point2bn(group, public_key,
+ EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
+ {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
buf_len = (size_t)BN_num_bytes(pub_key);
+ }
}
if (ktype == 2)
Index: src/crypto/dist/openssl/crypto/ec/ec_asn1.c
diff -u src/crypto/dist/openssl/crypto/ec/ec_asn1.c:1.1.1.4 src/crypto/dist/openssl/crypto/ec/ec_asn1.c:1.1.1.4.30.1
--- src/crypto/dist/openssl/crypto/ec/ec_asn1.c:1.1.1.4 Tue Mar 6 21:14:52 2007
+++ src/crypto/dist/openssl/crypto/ec/ec_asn1.c Sun Oct 19 20:11:08 2014
@@ -1167,29 +1167,46 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, con
goto err;
}
+ if (ret->pub_key)
+ EC_POINT_clear_free(ret->pub_key);
+ ret->pub_key = EC_POINT_new(ret->group);
+ if (ret->pub_key == NULL)
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+
if (priv_key->publicKey)
{
const unsigned char *pub_oct;
- size_t pub_oct_len;
+ int pub_oct_len;
- if (ret->pub_key)
- EC_POINT_clear_free(ret->pub_key);
- ret->pub_key = EC_POINT_new(ret->group);
- if (ret->pub_key == NULL)
+ pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
+ pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
+ /* The first byte - point conversion form - must be present. */
+ if (pub_oct_len <= 0)
{
- ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
goto err;
}
- pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
- pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
- /* save the point conversion form */
+ /* Save the point conversion form. */
ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
if (!EC_POINT_oct2point(ret->group, ret->pub_key,
- pub_oct, pub_oct_len, NULL))
+ pub_oct, (size_t)(pub_oct_len), NULL))
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+ else
+ {
+ if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL))
{
ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
goto err;
}
+ /* Remember the original private-key-only encoding. */
+ ret->enc_flag |= EC_PKEY_NO_PUBKEY;
}
ok = 1;
@@ -1214,7 +1231,8 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned
size_t buf_len=0, tmp_len;
EC_PRIVATEKEY *priv_key=NULL;
- if (a == NULL || a->group == NULL || a->priv_key == NULL)
+ if (a == NULL || a->group == NULL || a->priv_key == NULL ||
+ (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL))
{
ECerr(EC_F_I2D_ECPRIVATEKEY,
ERR_R_PASSED_NULL_PARAMETER);
Index: src/crypto/dist/openssl/crypto/ec/ec_key.c
diff -u src/crypto/dist/openssl/crypto/ec/ec_key.c:1.1.1.1 src/crypto/dist/openssl/crypto/ec/ec_key.c:1.1.1.1.38.1
--- src/crypto/dist/openssl/crypto/ec/ec_key.c:1.1.1.1 Fri Nov 25 03:05:38 2005
+++ src/crypto/dist/openssl/crypto/ec/ec_key.c Sun Oct 19 20:11:08 2014
@@ -64,7 +64,6 @@
#include <string.h>
#include "ec_lcl.h"
#include <openssl/err.h>
-#include <string.h>
EC_KEY *EC_KEY_new(void)
{
Index: src/crypto/dist/openssl/crypto/ec/ecp_smpl.c
diff -u src/crypto/dist/openssl/crypto/ec/ecp_smpl.c:1.1.1.4 src/crypto/dist/openssl/crypto/ec/ecp_smpl.c:1.1.1.4.38.1
--- src/crypto/dist/openssl/crypto/ec/ecp_smpl.c:1.1.1.4 Sat Jun 3 01:42:02 2006
+++ src/crypto/dist/openssl/crypto/ec/ecp_smpl.c Sun Oct 19 20:11:08 2014
@@ -1695,8 +1695,8 @@ int ec_GFp_simple_points_make_affine(con
/* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */
for (i = pow2/2 - 1; i > 0; i--)
{
- if (heap[i] != NULL)
- BN_clear_free(heap[i]);
+ if (heap[i] == NULL) break;
+ BN_clear_free(heap[i]);
}
OPENSSL_free(heap);
}
Index: src/crypto/dist/openssl/crypto/err/openssl.ec
diff -u src/crypto/dist/openssl/crypto/err/openssl.ec:1.1.1.7 src/crypto/dist/openssl/crypto/err/openssl.ec:1.1.1.7.2.1
--- src/crypto/dist/openssl/crypto/err/openssl.ec:1.1.1.7 Fri May 9 21:34:27 2008
+++ src/crypto/dist/openssl/crypto/err/openssl.ec Sun Oct 19 20:11:08 2014
@@ -70,6 +70,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION
R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070
R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
+R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086
R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
Index: src/crypto/dist/openssl/crypto/evp/Makefile
diff -u src/crypto/dist/openssl/crypto/evp/Makefile:1.1.1.5 src/crypto/dist/openssl/crypto/evp/Makefile:1.1.1.5.2.1
--- src/crypto/dist/openssl/crypto/evp/Makefile:1.1.1.5 Fri May 9 21:34:28 2008
+++ src/crypto/dist/openssl/crypto/evp/Makefile Sun Oct 19 20:11:08 2014
@@ -327,7 +327,8 @@ evp_enc.o: ../../include/openssl/obj_mac
evp_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
evp_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-evp_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_enc.c evp_locl.h
+evp_enc.o: ../../include/openssl/symhacks.h ../constant_time_locl.h
+evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
Index: src/crypto/dist/openssl/crypto/evp/evp_enc.c
diff -u src/crypto/dist/openssl/crypto/evp/evp_enc.c:1.1.1.8 src/crypto/dist/openssl/crypto/evp/evp_enc.c:1.1.1.8.30.1
--- src/crypto/dist/openssl/crypto/evp/evp_enc.c:1.1.1.8 Tue Mar 6 21:15:22 2007
+++ src/crypto/dist/openssl/crypto/evp/evp_enc.c Sun Oct 19 20:11:08 2014
@@ -64,6 +64,7 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
+#include "constant_time_locl.h"
#include "evp_locl.h"
const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
@@ -432,11 +433,11 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
{
- int i,n;
- unsigned int b;
+ unsigned int i, b;
+ unsigned char pad, padding_good;
*outl=0;
- b=ctx->cipher->block_size;
+ b=(unsigned int)(ctx->cipher->block_size);
if (ctx->flags & EVP_CIPH_NO_PADDING)
{
if(ctx->buf_len)
@@ -455,28 +456,34 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *
return(0);
}
OPENSSL_assert(b <= sizeof ctx->final);
- n=ctx->final[b-1];
- if (n == 0 || n > (int)b)
- {
- EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
- return(0);
- }
- for (i=0; i<n; i++)
+ pad=ctx->final[b-1];
+
+ padding_good = (unsigned char)(~constant_time_is_zero_8(pad));
+ padding_good &= constant_time_ge_8(b, pad);
+
+ for (i = 1; i < b; ++i)
{
- if (ctx->final[--b] != n)
- {
- EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
- return(0);
- }
- }
- n=ctx->cipher->block_size-n;
- for (i=0; i<n; i++)
- out[i]=ctx->final[i];
- *outl=n;
+ unsigned char is_pad_index = constant_time_lt_8(i, pad);
+ unsigned char pad_byte_good = constant_time_eq_8(ctx->final[b-i-1], pad);
+ padding_good &= constant_time_select_8(is_pad_index, pad_byte_good, 0xff);
+ }
+
+ /*
+ * At least 1 byte is always padding, so we always write b - 1
+ * bytes to avoid a timing leak. The caller is required to have |b|
+ * bytes space in |out| by the API contract.
+ */
+ for (i = 0; i < b - 1; ++i)
+ out[i] = ctx->final[i] & padding_good;
+ /* Safe cast: for a good padding, EVP_MAX_IV_LENGTH >= b >= pad */
+ *outl = padding_good & ((unsigned char)(b - pad));
+ return padding_good & 1;
}
else
- *outl=0;
- return(1);
+ {
+ *outl = 0;
+ return 1;
+ }
}
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
@@ -560,4 +567,3 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_C
return 0;
return 1;
}
-
Index: src/crypto/dist/openssl/crypto/pkcs7/pkcs7.h
diff -u src/crypto/dist/openssl/crypto/pkcs7/pkcs7.h:1.8 src/crypto/dist/openssl/crypto/pkcs7/pkcs7.h:1.8.2.1
--- src/crypto/dist/openssl/crypto/pkcs7/pkcs7.h:1.8 Fri May 9 21:49:41 2008
+++ src/crypto/dist/openssl/crypto/pkcs7/pkcs7.h Sun Oct 19 20:11:08 2014
@@ -233,10 +233,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
-#define PKCS7_type_is_encrypted(a) \
- (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
-
-#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
#define PKCS7_set_detached(p,v) \
PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
Index: src/crypto/dist/openssl/crypto/rsa/Makefile
diff -u src/crypto/dist/openssl/crypto/rsa/Makefile:1.1.1.4 src/crypto/dist/openssl/crypto/rsa/Makefile:1.1.1.4.2.1
--- src/crypto/dist/openssl/crypto/rsa/Makefile:1.1.1.4 Fri May 9 21:34:34 2008
+++ src/crypto/dist/openssl/crypto/rsa/Makefile Sun Oct 19 20:11:08 2014
@@ -187,7 +187,7 @@ rsa_oaep.o: ../../include/openssl/openss
rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
rsa_oaep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_oaep.o: ../cryptlib.h rsa_oaep.c
+rsa_oaep.o: ../constant_time_locl.h ../cryptlib.h rsa_oaep.c
rsa_pk1.o: ../../e_os.h ../../include/openssl/asn1.h
rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -196,7 +196,8 @@ rsa_pk1.o: ../../include/openssl/lhash.h
rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
+rsa_pk1.o: ../../include/openssl/symhacks.h ../constant_time_locl.h
+rsa_pk1.o: ../cryptlib.h rsa_pk1.c
rsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
rsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
rsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
Index: src/crypto/dist/openssl/crypto/rsa/rsa.h
diff -u src/crypto/dist/openssl/crypto/rsa/rsa.h:1.14 src/crypto/dist/openssl/crypto/rsa/rsa.h:1.14.2.1
--- src/crypto/dist/openssl/crypto/rsa/rsa.h:1.14 Fri May 9 21:49:41 2008
+++ src/crypto/dist/openssl/crypto/rsa/rsa.h Sun Oct 19 20:11:08 2014
@@ -484,6 +484,7 @@ void ERR_load_RSA_strings(void);
#define RSA_R_OAEP_DECODING_ERROR 121
#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148
#define RSA_R_PADDING_CHECK_FAILED 114
+#define RSA_R_PKCS_DECODING_ERROR 159
#define RSA_R_P_NOT_PRIME 128
#define RSA_R_Q_NOT_PRIME 129
#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130
Index: src/crypto/dist/openssl/crypto/rsa/rsa_err.c
diff -u src/crypto/dist/openssl/crypto/rsa/rsa_err.c:1.7 src/crypto/dist/openssl/crypto/rsa/rsa_err.c:1.7.2.1
--- src/crypto/dist/openssl/crypto/rsa/rsa_err.c:1.7 Fri May 9 21:49:41 2008
+++ src/crypto/dist/openssl/crypto/rsa/rsa_err.c Sun Oct 19 20:11:08 2014
@@ -162,6 +162,7 @@ static ERR_STRING_DATA RSA_str_reasons[]
{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
{ERR_REASON(RSA_R_PADDING_CHECK_FAILED) ,"padding check failed"},
+{ERR_REASON(RSA_R_PKCS_DECODING_ERROR) ,"pkcs decoding error"},
{ERR_REASON(RSA_R_P_NOT_PRIME) ,"p not prime"},
{ERR_REASON(RSA_R_Q_NOT_PRIME) ,"q not prime"},
{ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},
Index: src/crypto/dist/openssl/crypto/rsa/rsa_oaep.c
diff -u src/crypto/dist/openssl/crypto/rsa/rsa_oaep.c:1.1.1.7 src/crypto/dist/openssl/crypto/rsa/rsa_oaep.c:1.1.1.7.38.1
--- src/crypto/dist/openssl/crypto/rsa/rsa_oaep.c:1.1.1.7 Fri Nov 25 03:07:07 2005
+++ src/crypto/dist/openssl/crypto/rsa/rsa_oaep.c Sun Oct 19 20:11:08 2014
@@ -18,6 +18,7 @@
* an equivalent notion.
*/
+#include "constant_time_locl.h"
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
#include <stdio.h>
@@ -92,82 +93,115 @@ int RSA_padding_check_PKCS1_OAEP(unsigne
const unsigned char *from, int flen, int num,
const unsigned char *param, int plen)
{
- int i, dblen, mlen = -1;
- const unsigned char *maskeddb;
- int lzero;
- unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
- int bad = 0;
-
- if (--num < 2 * SHA_DIGEST_LENGTH + 1)
- /* 'num' is the length of the modulus, i.e. does not depend on the
- * particular ciphertext. */
- goto decoding_err;
+ int i, dblen, mlen = -1, one_index = 0, msg_index;
+ unsigned int good, found_one_byte;
+ const unsigned char *maskedseed, *maskeddb;
+ /* |em| is the encoded message, zero-padded to exactly |num| bytes:
+ * em = Y || maskedSeed || maskedDB */
+ unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],
+ phash[EVP_MAX_MD_SIZE];
- lzero = num - flen;
- if (lzero < 0)
- {
- /* lzero == -1 */
+ if (tlen <= 0 || flen <= 0)
+ return -1;
- /* signalling this error immediately after detection might allow
- * for side-channel attacks (e.g. timing if 'plen' is huge
- * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
- * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
- * so we use a 'bad' flag */
- bad = 1;
- lzero = 0;
- }
- maskeddb = from - lzero + SHA_DIGEST_LENGTH;
+ /*
+ * |num| is the length of the modulus; |flen| is the length of the
+ * encoded message. Therefore, for any |from| that was obtained by
+ * decrypting a ciphertext, we must have |flen| <= |num|. Similarly,
+ * num < 2 * SHA_DIGEST_LENGTH + 2 must hold for the modulus
+ * irrespective of the ciphertext, see PKCS #1 v2.2, section 7.1.2.
+ * This does not leak any side-channel information.
+ */
+ if (num < flen || num < 2 * SHA_DIGEST_LENGTH + 2)
+ goto decoding_err;
- dblen = num - SHA_DIGEST_LENGTH;
+ dblen = num - SHA_DIGEST_LENGTH - 1;
db = OPENSSL_malloc(dblen);
- if (db == NULL)
+ em = OPENSSL_malloc(num);
+ if (db == NULL || em == NULL)
{
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
- return -1;
+ goto cleanup;
}
- MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
- for (i = lzero; i < SHA_DIGEST_LENGTH; i++)
- seed[i] ^= from[i - lzero];
+ /*
+ * Always do this zero-padding copy (even when num == flen) to avoid
+ * leaking that information. The copy still leaks some side-channel
+ * information, but it's impossible to have a fixed memory access
+ * pattern since we can't read out of the bounds of |from|.
+ *
+ * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+ */
+ memset(em, 0, num);
+ memcpy(em + num - flen, from, flen);
+
+ /*
+ * The first byte must be zero, however we must not leak if this is
+ * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA
+ * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
+ */
+ good = constant_time_is_zero(em[0]);
+
+ maskedseed = em + 1;
+ maskeddb = em + 1 + SHA_DIGEST_LENGTH;
+
+ if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
+ goto cleanup;
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++)
+ seed[i] ^= maskedseed[i];
- MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
+ if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
+ goto cleanup;
for (i = 0; i < dblen; i++)
db[i] ^= maskeddb[i];
EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
- if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+ good &= constant_time_is_zero(memcmp(db, phash, SHA_DIGEST_LENGTH));
+
+ found_one_byte = 0;
+ for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
+ {
+ /* Padding consists of a number of 0-bytes, followed by a 1. */
+ unsigned int equals1 = constant_time_eq(db[i], 1);
+ unsigned int equals0 = constant_time_is_zero(db[i]);
+ one_index = constant_time_select_int(~found_one_byte & equals1,
+ i, one_index);
+ found_one_byte |= equals1;
+ good &= (found_one_byte | equals0);
+ }
+
+ good &= found_one_byte;
+
+ /*
+ * At this point |good| is zero unless the plaintext was valid,
+ * so plaintext-awareness ensures timing side-channels are no longer a
+ * concern.
+ */
+ if (!good)
goto decoding_err;
+
+ msg_index = one_index + 1;
+ mlen = dblen - msg_index;
+
+ if (tlen < mlen)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
+ mlen = -1;
+ }
else
{
- for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
- if (db[i] != 0x00)
- break;
- if (db[i] != 0x01 || i++ >= dblen)
- goto decoding_err;
- else
- {
- /* everything looks OK */
-
- mlen = dblen - i;
- if (tlen < mlen)
- {
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
- mlen = -1;
- }
- else
- memcpy(to, db + i, mlen);
- }
+ memcpy(to, db + msg_index, mlen);
+ goto cleanup;
}
- OPENSSL_free(db);
- return mlen;
decoding_err:
- /* to avoid chosen ciphertext attacks, the error message should not reveal
+ /* To avoid chosen ciphertext attacks, the error message should not reveal
* which kind of decoding error happened */
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
- if (db != NULL) OPENSSL_free(db);
- return -1;
+cleanup:
+ if (em != NULL) OPENSSL_free(em);
+ return mlen;
}
int PKCS1_MGF1(unsigned char *mask, long len,
Index: src/crypto/dist/openssl/crypto/rsa/rsa_pk1.c
diff -u src/crypto/dist/openssl/crypto/rsa/rsa_pk1.c:1.1.1.3 src/crypto/dist/openssl/crypto/rsa/rsa_pk1.c:1.1.1.3.50.1
--- src/crypto/dist/openssl/crypto/rsa/rsa_pk1.c:1.1.1.3 Thu Jul 24 08:28:11 2003
+++ src/crypto/dist/openssl/crypto/rsa/rsa_pk1.c Sun Oct 19 20:11:08 2014
@@ -56,6 +56,8 @@
* [including the GNU Public Licence.]
*/
+#include "constant_time_locl.h"
+
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/bn.h>
@@ -181,44 +183,87 @@ int RSA_padding_add_PKCS1_type_2(unsigne
int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
const unsigned char *from, int flen, int num)
{
- int i,j;
- const unsigned char *p;
-
- p=from;
- if ((num != (flen+1)) || (*(p++) != 02))
- {
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BLOCK_TYPE_IS_NOT_02);
- return(-1);
- }
-#ifdef PKCS1_CHECK
- return(num-11);
-#endif
-
- /* scan over padding data */
- j=flen-1; /* one for type. */
- for (i=0; i<j; i++)
- if (*(p++) == 0) break;
-
- if (i == j)
- {
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING);
- return(-1);
- }
-
- if (i < 8)
- {
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BAD_PAD_BYTE_COUNT);
- return(-1);
- }
- i++; /* Skip over the '\0' */
- j-=i;
- if (j > tlen)
- {
- RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE);
- return(-1);
- }
- memcpy(to,p,(unsigned int)j);
-
- return(j);
+ int i;
+ /* |em| is the encoded message, zero-padded to exactly |num| bytes */
+ unsigned char *em = NULL;
+ unsigned int good, found_zero_byte;
+ int zero_index = 0, msg_index, mlen = -1;
+
+ if (tlen < 0 || flen < 0)
+ return -1;
+
+ /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
+ * Standard", section 7.2.2. */
+
+ if (flen > num)
+ goto err;
+
+ if (num < 11)
+ goto err;
+
+ em = OPENSSL_malloc(num);
+ if (em == NULL)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ memset(em, 0, num);
+ /*
+ * Always do this zero-padding copy (even when num == flen) to avoid
+ * leaking that information. The copy still leaks some side-channel
+ * information, but it's impossible to have a fixed memory access
+ * pattern since we can't read out of the bounds of |from|.
+ *
+ * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+ */
+ memcpy(em + num - flen, from, flen);
+
+ good = constant_time_is_zero(em[0]);
+ good &= constant_time_eq(em[1], 2);
+
+ found_zero_byte = 0;
+ for (i = 2; i < num; i++)
+ {
+ unsigned int equals0 = constant_time_is_zero(em[i]);
+ zero_index = constant_time_select_int(~found_zero_byte & equals0, i, zero_index);
+ found_zero_byte |= equals0;
+ }
+
+ /*
+ * PS must be at least 8 bytes long, and it starts two bytes into |em|.
+ * If we never found a 0-byte, then |zero_index| is 0 and the check
+ * also fails.
+ */
+ good &= constant_time_ge((unsigned int)(zero_index), 2 + 8);
+
+ /* Skip the zero byte. This is incorrect if we never found a zero-byte
+ * but in this case we also do not copy the message out. */
+ msg_index = zero_index + 1;
+ mlen = num - msg_index;
+
+ /* For good measure, do this check in constant time as well; it could
+ * leak something if |tlen| was assuming valid padding. */
+ good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen));
+
+ /*
+ * We can't continue in constant-time because we need to copy the result
+ * and we cannot fake its length. This unavoidably leaks timing
+ * information at the API boundary.
+ * TODO(emilia): this could be addressed at the call site,
+ * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26.
+ */
+ if (!good)
+ {
+ mlen = -1;
+ goto err;
+ }
+
+ memcpy(to, em + msg_index, mlen);
+
+err:
+ if (em != NULL)
+ OPENSSL_free(em);
+ if (mlen == -1)
+ RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR);
+ return mlen;
}
-
Index: src/crypto/dist/openssl/crypto/rsa/rsa_sign.c
diff -u src/crypto/dist/openssl/crypto/rsa/rsa_sign.c:1.5 src/crypto/dist/openssl/crypto/rsa/rsa_sign.c:1.5.2.1
--- src/crypto/dist/openssl/crypto/rsa/rsa_sign.c:1.5 Fri May 9 21:49:41 2008
+++ src/crypto/dist/openssl/crypto/rsa/rsa_sign.c Sun Oct 19 20:11:08 2014
@@ -143,6 +143,25 @@ int RSA_sign(int type, const unsigned ch
return(ret);
}
+/*
+ * Check DigestInfo structure does not contain extraneous data by reencoding
+ * using DER and checking encoding against original.
+ */
+static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, int dinfolen)
+ {
+ unsigned char *der = NULL;
+ int derlen;
+ int ret = 0;
+ derlen = i2d_X509_SIG(sig, &der);
+ if (derlen <= 0)
+ return 0;
+ if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
+ ret = 1;
+ OPENSSL_cleanse(der, derlen);
+ OPENSSL_free(der);
+ return ret;
+ }
+
int int_rsa_verify(int dtype, const unsigned char *m,
unsigned int m_len,
unsigned char *rm, size_t *prm_len,
@@ -195,7 +214,7 @@ int int_rsa_verify(int dtype, const unsi
if (sig == NULL) goto err;
/* Excess data can be used to create forgeries */
- if(p != s+i)
+ if(p != s+i || !rsa_check_digestinfo(sig, s, i))
{
RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
goto err;
Index: src/crypto/dist/openssl/doc/apps/s_client.pod
diff -u src/crypto/dist/openssl/doc/apps/s_client.pod:1.8 src/crypto/dist/openssl/doc/apps/s_client.pod:1.8.2.1
--- src/crypto/dist/openssl/doc/apps/s_client.pod:1.8 Fri May 9 21:49:42 2008
+++ src/crypto/dist/openssl/doc/apps/s_client.pod Sun Oct 19 20:11:08 2014
@@ -34,6 +34,7 @@ B<openssl> B<s_client>
[B<-no_ssl2>]
[B<-no_ssl3>]
[B<-no_tls1>]
+[B<-fallback_scsv>]
[B<-bugs>]
[B<-cipher cipherlist>]
[B<-starttls protocol>]
@@ -177,10 +178,13 @@ these options disable the use of certain
the initial handshake uses a method which should be compatible with all
servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
-Unfortunately there are a lot of ancient and broken servers in use which
+Unfortunately there are still ancient and broken servers in use which
cannot handle this technique and will fail to connect. Some servers only
-work if TLS is turned off with the B<-no_tls> option others will only
-support SSL v2 and may need the B<-ssl2> option.
+work if TLS is turned off.
+
+=item B<-fallback_scsv>
+
+Send TLS_FALLBACK_SCSV in the ClientHello.
=item B<-bugs>
Index: src/crypto/dist/openssl/doc/crypto/BIO_s_accept.pod
diff -u src/crypto/dist/openssl/doc/crypto/BIO_s_accept.pod:1.1.1.2 src/crypto/dist/openssl/doc/crypto/BIO_s_accept.pod:1.1.1.2.50.1
--- src/crypto/dist/openssl/doc/crypto/BIO_s_accept.pod:1.1.1.2 Thu Jul 24 08:28:50 2003
+++ src/crypto/dist/openssl/doc/crypto/BIO_s_accept.pod Sun Oct 19 20:11:08 2014
@@ -59,8 +59,8 @@ the accept socket. See L<BIO_s_fd(3)|BIO
BIO_set_accept_port() uses the string B<name> to set the accept
port. The port is represented as a string of the form "host:port",
where "host" is the interface to use and "port" is the port.
-Either or both values can be "*" which is interpreted as meaning
-any interface or port respectively. "port" has the same syntax
+The host can be can be "*" which is interpreted as meaning
+any interface; "port" has the same syntax
as the port specified in BIO_set_conn_port() for connect BIOs,
that is it can be a numerical port string or a string to lookup
using getservbyname() and a string table.
Index: src/crypto/dist/openssl/doc/crypto/EVP_DigestInit.pod
diff -u src/crypto/dist/openssl/doc/crypto/EVP_DigestInit.pod:1.6 src/crypto/dist/openssl/doc/crypto/EVP_DigestInit.pod:1.6.38.1
--- src/crypto/dist/openssl/doc/crypto/EVP_DigestInit.pod:1.6 Fri Nov 25 19:14:14 2005
+++ src/crypto/dist/openssl/doc/crypto/EVP_DigestInit.pod Sun Oct 19 20:11:08 2014
@@ -25,13 +25,13 @@ EVP digest routines
int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
- int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);
+ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,
unsigned int *s);
- int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);
+ int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in);
#define EVP_MAX_MD_SIZE (16+20) /* The SSLv3 md5+sha1 type */
Index: src/crypto/dist/openssl/doc/crypto/EVP_EncryptInit.pod
diff -u src/crypto/dist/openssl/doc/crypto/EVP_EncryptInit.pod:1.6 src/crypto/dist/openssl/doc/crypto/EVP_EncryptInit.pod:1.6.38.1
--- src/crypto/dist/openssl/doc/crypto/EVP_EncryptInit.pod:1.6 Fri Nov 25 19:14:14 2005
+++ src/crypto/dist/openssl/doc/crypto/EVP_EncryptInit.pod Sun Oct 19 20:11:08 2014
@@ -384,27 +384,7 @@ for certain common S/MIME ciphers (RC2,
=head1 EXAMPLES
-Get the number of rounds used in RC5:
-
- int nrounds;
- EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC5_ROUNDS, 0, &nrounds);
-
-Get the RC2 effective key length:
-
- int key_bits;
- EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC2_KEY_BITS, 0, &key_bits);
-
-Set the number of rounds used in RC5:
-
- int nrounds;
- EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, nrounds, NULL);
-
-Set the effective key length used in RC2:
-
- int key_bits;
- EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
-
-Encrypt a string using blowfish:
+Encrypt a string using IDEA:
int do_crypt(char *outfile)
{
@@ -418,8 +398,9 @@ Encrypt a string using blowfish:
char intext[] = "Some Crypto Text";
EVP_CIPHER_CTX ctx;
FILE *out;
+
EVP_CIPHER_CTX_init(&ctx);
- EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, key, iv);
+ EVP_EncryptInit_ex(&ctx, EVP_idea_cbc(), NULL, key, iv);
if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, intext, strlen(intext)))
{
@@ -448,28 +429,34 @@ Encrypt a string using blowfish:
}
The ciphertext from the above example can be decrypted using the B<openssl>
-utility with the command line:
+utility with the command line (shown on two lines for clarity):
- S<openssl bf -in cipher.bin -K 000102030405060708090A0B0C0D0E0F -iv 0102030405060708 -d>
+ openssl idea -d <filename
+ -K 000102030405060708090A0B0C0D0E0F -iv 0102030405060708
-General encryption, decryption function example using FILE I/O and RC2 with an
-80 bit key:
+General encryption and decryption function example using FILE I/O and AES128
+with a 128-bit key:
int do_crypt(FILE *in, FILE *out, int do_encrypt)
{
/* Allow enough space in output buffer for additional block */
- inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
+ unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
int inlen, outlen;
+ EVP_CIPHER_CTX ctx;
/* Bogus key and IV: we'd normally set these from
* another source.
*/
- unsigned char key[] = "0123456789";
- unsigned char iv[] = "12345678";
- /* Don't set key or IV because we will modify the parameters */
+ unsigned char key[] = "0123456789abcdeF";
+ unsigned char iv[] = "1234567887654321";
+
+ /* Don't set key or IV right away; we want to check lengths */
EVP_CIPHER_CTX_init(&ctx);
- EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);
- EVP_CIPHER_CTX_set_key_length(&ctx, 10);
- /* We finished modifying parameters so now we can set key and IV */
+ EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL,
+ do_encrypt);
+ OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == 16);
+ OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == 16);
+
+ /* Now we can set key and IV */
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
for(;;)
@@ -508,4 +495,7 @@ EVP_DecryptInit_ex(), EVP_DecryptFinal_e
EVP_CipherFinal_ex() and EVP_CIPHER_CTX_set_padding() appeared in
OpenSSL 0.9.7.
+IDEA appeared in OpenSSL 0.9.7 but was often disabled due to
+patent concerns; the last patents expired in 2012.
+
=cut
Index: src/crypto/dist/openssl/doc/crypto/EVP_DigestVerifyInit.pod
diff -u src/crypto/dist/openssl/doc/crypto/EVP_DigestVerifyInit.pod:1.1.1.1 src/crypto/dist/openssl/doc/crypto/EVP_DigestVerifyInit.pod:1.1.1.1.6.1
--- src/crypto/dist/openssl/doc/crypto/EVP_DigestVerifyInit.pod:1.1.1.1 Fri May 9 21:34:09 2008
+++ src/crypto/dist/openssl/doc/crypto/EVP_DigestVerifyInit.pod Sun Oct 19 20:11:08 2014
@@ -38,7 +38,7 @@ or a negative value for failure. In part
the operation is not supported by the public key algorithm.
Unlike other functions the return value 0 from EVP_DigestVerifyFinal() only
-indicates that the signature did not not verify successfully (that is tbs did
+indicates that the signature did not verify successfully (that is tbs did
not match the original data or the signature was of invalid form) it is not an
indication of a more serious error.
@@ -59,7 +59,7 @@ For some key types and parameters the ra
or the operation will fail.
The call to EVP_DigestVerifyFinal() internally finalizes a copy of the digest
-context. This means that calls to EVP_VerifyUpdate() and EVP_VerifyFinal() can
+context. This means that EVP_VerifyUpdate() and EVP_VerifyFinal() can
be called later to digest and verify additional data.
Since only a copy of the digest context is ever finalized the context must
Index: src/crypto/dist/openssl/doc/crypto/EVP_PKEY_sign.pod
diff -u src/crypto/dist/openssl/doc/crypto/EVP_PKEY_sign.pod:1.1.1.1 src/crypto/dist/openssl/doc/crypto/EVP_PKEY_sign.pod:1.1.1.1.6.1
--- src/crypto/dist/openssl/doc/crypto/EVP_PKEY_sign.pod:1.1.1.1 Fri May 9 21:34:09 2008
+++ src/crypto/dist/openssl/doc/crypto/EVP_PKEY_sign.pod Sun Oct 19 20:11:08 2014
@@ -28,9 +28,14 @@ B<sig> and the amount of data written to
=head1 NOTES
+EVP_PKEY_sign() does not hash the data to be signed, and therefore is
+normally used to sign digests. For signing arbitrary messages, see the
+L<EVP_DigestSignInit(3)|EVP_DigestSignInit(3)> and
+L<EVP_SignInit(3)|EVP_SignInit(3)> signing interfaces instead.
+
After the call to EVP_PKEY_sign_init() algorithm specific control
operations can be performed to set any appropriate parameters for the
-operation.
+operation (see L<EVP_PKEY_CTX_ctrl(3)|EVP_PKEY_CTX_ctrl(3)>).
The function EVP_PKEY_sign() can be called more than once on the same
context if several operations are performed using the same parameters.
@@ -49,13 +54,17 @@ Sign data using RSA with PKCS#1 padding
#include <openssl/rsa.h>
EVP_PKEY_CTX *ctx;
+ /* md is a SHA-256 digest in this example. */
unsigned char *md, *sig;
- size_t mdlen, siglen;
+ size_t mdlen = 32, siglen;
EVP_PKEY *signing_key;
- /* NB: assumes signing_key, md and mdlen are already set up
- * and that signing_key is an RSA private key
+
+ /*
+ * NB: assumes signing_key and md are set up before the next
+ * step. signing_key must be an RSA private key and md must
+ * point to the SHA-256 digest to be signed.
*/
- ctx = EVP_PKEY_CTX_new(signing_key);
+ ctx = EVP_PKEY_CTX_new(signing_key, NULL /* no engine */);
if (!ctx)
/* Error occurred */
if (EVP_PKEY_sign_init(ctx) <= 0)
@@ -83,6 +92,7 @@ Sign data using RSA with PKCS#1 padding
=head1 SEE ALSO
L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_CTX_ctrl(3)|EVP_PKEY_CTX_ctrl(3)>,
L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
Index: src/crypto/dist/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod
diff -u src/crypto/dist/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod:1.1.1.1 src/crypto/dist/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod:1.1.1.1.50.1
--- src/crypto/dist/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod:1.1.1.1 Thu Jul 24 08:28:55 2003
+++ src/crypto/dist/openssl/doc/crypto/EVP_PKEY_set1_RSA.pod Sun Oct 19 20:11:08 2014
@@ -37,7 +37,7 @@ EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA()
EVP_PKEY_get1_EC_KEY() return the referenced key in B<pkey> or
B<NULL> if the key is not of the correct type.
-EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
+EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
and EVP_PKEY_assign_EC_KEY() also set the referenced key to B<key>
however these use the supplied B<key> internally and so B<key>
will be freed when the parent B<pkey> is freed.
@@ -54,8 +54,8 @@ In accordance with the OpenSSL naming co
from or assigned to the B<pkey> using the B<1> functions must be
freed as well as B<pkey>.
-EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
-EVP_PKEY_assign_EC_KEY() are implemented as macros.
+EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
+and EVP_PKEY_assign_EC_KEY() are implemented as macros.
=head1 RETURN VALUES
@@ -66,7 +66,7 @@ EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA()
EVP_PKEY_get1_EC_KEY() return the referenced key or B<NULL> if
an error occurred.
-EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
+EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH()
and EVP_PKEY_assign_EC_KEY() return 1 for success and 0 for failure.
=head1 SEE ALSO
Index: src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_mode.pod
diff -u src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_mode.pod:1.1.1.2 src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_mode.pod:1.1.1.2.50.1
--- src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_mode.pod:1.1.1.2 Sun Jun 9 15:23:59 2002
+++ src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_mode.pod Sun Oct 19 20:11:09 2014
@@ -61,6 +61,12 @@ deal with read/write operations returnin
flag SSL_MODE_AUTO_RETRY will cause read/write operations to only
return after the handshake and successful completion.
+=item SSL_MODE_FALLBACK_SCSV
+
+Send TLS_FALLBACK_SCSV in the ClientHello.
+To be set by applications that reconnect with a downgraded protocol
+version; see draft-ietf-tls-downgrade-scsv-00 for details.
+
=back
=head1 RETURN VALUES
Index: src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod
diff -u src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod:1.1.1.1 src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod:1.1.1.1.54.1
--- src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod:1.1.1.1 Sun Jun 9 15:23:59 2002
+++ src/crypto/dist/openssl/doc/ssl/SSL_CTX_set_tmp_dh_callback.pod Sun Oct 19 20:11:09 2014
@@ -50,12 +50,13 @@ even if he gets hold of the normal (cert
only used for signing.
In order to perform a DH key exchange the server must use a DH group
-(DH parameters) and generate a DH key. The server will always generate a new
-DH key during the negotiation, when the DH parameters are supplied via
-callback and/or when the SSL_OP_SINGLE_DH_USE option of
-L<SSL_CTX_set_options(3)|SSL_CTX_set_options(3)> is set. It will
-immediately create a DH key, when DH parameters are supplied via
-SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set. In this case,
+(DH parameters) and generate a DH key.
+The server will always generate a new DH key during the negotiation
+if either the DH parameters are supplied via callback or the
+SSL_OP_SINGLE_DH_USE option of SSL_CTX_set_options(3) is set (or both).
+It will immediately create a DH key if DH parameters are supplied via
+SSL_CTX_set_tmp_dh() and SSL_OP_SINGLE_DH_USE is not set.
+In this case,
it may happen that a key is generated on initialization without later
being needed, while on the other hand the computer time during the
negotiation is being saved.
@@ -141,7 +142,7 @@ partly left out.)
dh_tmp = dh_512;
break;
case 1024:
- if (!dh_1024)
+ if (!dh_1024)
dh_1024 = get_dh1024();
dh_tmp = dh_1024;
break;
Index: src/crypto/dist/openssl/ssl/Makefile
diff -u src/crypto/dist/openssl/ssl/Makefile:1.3 src/crypto/dist/openssl/ssl/Makefile:1.3.2.1
--- src/crypto/dist/openssl/ssl/Makefile:1.3 Fri May 9 21:49:42 2008
+++ src/crypto/dist/openssl/ssl/Makefile Sun Oct 19 20:11:09 2014
@@ -604,6 +604,7 @@ s3_pkt.o: ../include/openssl/ssl3.h ../i
s3_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
s3_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_pkt.c
s3_pkt.o: ssl_locl.h
+s3_srvr.o: ../crypto/constant_time_locl.h
s3_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
s3_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
Index: src/crypto/dist/openssl/ssl/s23_clnt.c
diff -u src/crypto/dist/openssl/ssl/s23_clnt.c:1.1.1.10 src/crypto/dist/openssl/ssl/s23_clnt.c:1.1.1.10.2.1
--- src/crypto/dist/openssl/ssl/s23_clnt.c:1.1.1.10 Fri May 9 21:34:43 2008
+++ src/crypto/dist/openssl/ssl/s23_clnt.c Sun Oct 19 20:11:09 2014
@@ -125,9 +125,11 @@ static const SSL_METHOD *ssl23_get_clien
if (ver == SSL2_VERSION)
return(SSLv2_client_method());
#endif
+#ifndef OPENSSL_NO_SSL3
if (ver == SSL3_VERSION)
return(SSLv3_client_method());
- else if (ver == TLS1_VERSION)
+#endif
+ if (ver == TLS1_VERSION)
return(TLSv1_client_method());
else
return(NULL);
@@ -586,13 +588,16 @@ static int ssl23_get_server_hello(SSL *s
{
/* we have sslv3 or tls1 (server hello or alert) */
+#ifndef OPENSSL_NO_SSL3
if ((p[2] == SSL3_VERSION_MINOR) &&
!(s->options & SSL_OP_NO_SSLv3))
{
s->version=SSL3_VERSION;
s->method=SSLv3_client_method();
}
- else if ((p[2] == TLS1_VERSION_MINOR) &&
+ else
+#endif
+ if ((p[2] == TLS1_VERSION_MINOR) &&
!(s->options & SSL_OP_NO_TLSv1))
{
s->version=TLS1_VERSION;
@@ -604,6 +609,9 @@ static int ssl23_get_server_hello(SSL *s
goto err;
}
+ /* ensure that TLS_MAX_VERSION is up-to-date */
+ OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
{
/* fatal alert */
Index: src/crypto/dist/openssl/ssl/s23_srvr.c
diff -u src/crypto/dist/openssl/ssl/s23_srvr.c:1.6.2.1 src/crypto/dist/openssl/ssl/s23_srvr.c:1.6.2.2
--- src/crypto/dist/openssl/ssl/s23_srvr.c:1.6.2.1 Wed Aug 27 13:30:49 2014
+++ src/crypto/dist/openssl/ssl/s23_srvr.c Sun Oct 19 20:11:09 2014
@@ -124,9 +124,11 @@ static const SSL_METHOD *ssl23_get_serve
if (ver == SSL2_VERSION)
return(SSLv2_server_method());
#endif
+#ifndef OPENSSL_NO_SSL3
if (ver == SSL3_VERSION)
return(SSLv3_server_method());
- else if (ver == TLS1_VERSION)
+#endif
+ if (ver == TLS1_VERSION)
return(TLSv1_server_method());
else
return(NULL);
@@ -384,6 +386,9 @@ int ssl23_get_client_hello(SSL *s)
}
}
+ /* ensure that TLS_MAX_VERSION is up-to-date */
+ OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
{
/* we have SSLv3/TLSv1 in an SSLv2 header
@@ -551,6 +556,12 @@ int ssl23_get_client_hello(SSL *s)
if ((type == 2) || (type == 3))
{
/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+ s->method = ssl23_get_server_method(s->version);
+ if (s->method == NULL)
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+ goto err;
+ }
if (!ssl_init_wbio_buffer(s,1)) goto err;
@@ -574,11 +585,6 @@ int ssl23_get_client_hello(SSL *s)
s->s3->rbuf.left=0;
s->s3->rbuf.offset=0;
}
-
- if (s->version == TLS1_VERSION)
- s->method = TLSv1_server_method();
- else
- s->method = SSLv3_server_method();
#if 0 /* ssl3_get_client_hello does this */
s->client_version=(v[0]<<8)|v[1];
#endif
Index: src/crypto/dist/openssl/ssl/s2_lib.c
diff -u src/crypto/dist/openssl/ssl/s2_lib.c:1.12 src/crypto/dist/openssl/ssl/s2_lib.c:1.12.2.1
--- src/crypto/dist/openssl/ssl/s2_lib.c:1.12 Fri May 9 21:49:42 2008
+++ src/crypto/dist/openssl/ssl/s2_lib.c Sun Oct 19 20:11:09 2014
@@ -391,6 +391,8 @@ long ssl2_ctrl(SSL *s, int cmd, long lar
case SSL_CTRL_GET_SESSION_REUSED:
ret=s->hit;
break;
+ case SSL_CTRL_CHECK_PROTO_VERSION:
+ return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
default:
break;
}
@@ -439,7 +441,7 @@ int ssl2_put_cipher_by_char(const SSL_CI
if (p != NULL)
{
l=c->id;
- if ((l & 0xff000000) != 0x02000000) return(0);
+ if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0);
p[0]=((unsigned char)(l>>16L))&0xFF;
p[1]=((unsigned char)(l>> 8L))&0xFF;
p[2]=((unsigned char)(l ))&0xFF;
Index: src/crypto/dist/openssl/ssl/s3_clnt.c
diff -u src/crypto/dist/openssl/ssl/s3_clnt.c:1.12.4.3.4.2 src/crypto/dist/openssl/ssl/s3_clnt.c:1.12.4.3.4.3
--- src/crypto/dist/openssl/ssl/s3_clnt.c:1.12.4.3.4.2 Wed Aug 27 13:30:49 2014
+++ src/crypto/dist/openssl/ssl/s3_clnt.c Sun Oct 19 20:11:09 2014
@@ -1109,8 +1109,8 @@ int ssl3_get_key_exchange(SSL *s)
#endif
EVP_MD_CTX md_ctx;
unsigned char *param,*p;
- int al,i,j,param_len,ok;
- long n,alg_k,alg_a;
+ int al,j,ok;
+ long i,param_len,n,alg_k,alg_a;
EVP_PKEY *pkey=NULL;
#ifndef OPENSSL_NO_RSA
RSA *rsa=NULL;
@@ -1185,36 +1185,48 @@ int ssl3_get_key_exchange(SSL *s)
s->session->sess_cert=ssl_sess_cert_new();
}
+ /* Total length of the parameters including the length prefix */
param_len=0;
+
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
alg_a=s->s3->tmp.new_cipher->algorithm_auth;
EVP_MD_CTX_init(&md_ctx);
+ al=SSL_AD_DECODE_ERROR;
+
#ifndef OPENSSL_NO_PSK
if (alg_k & SSL_kPSK)
{
char tmp_id_hint[PSK_MAX_IDENTITY_LEN+1];
- al=SSL_AD_HANDSHAKE_FAILURE;
+ param_len = 2;
+ if (param_len > n)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
n2s(p,i);
- param_len=i+2;
+
/* Store PSK identity hint for later use, hint is used
* in ssl3_send_client_key_exchange. Assume that the
* maximum length of a PSK identity hint can be as
* long as the maximum length of a PSK identity. */
if (i > PSK_MAX_IDENTITY_LEN)
{
+ al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
goto f_err;
}
- if (param_len > n)
+ if (i > n - param_len)
{
- al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
goto f_err;
}
+ param_len += i;
+
/* If received PSK identity hint contains NULL
* characters, the hint is truncated from the first
* NULL. p may not be ending with NULL, so create a
@@ -1226,6 +1238,7 @@ int ssl3_get_key_exchange(SSL *s)
s->ctx->psk_identity_hint = BUF_strdup(tmp_id_hint);
if (s->ctx->psk_identity_hint == NULL)
{
+ al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto f_err;
}
@@ -1243,14 +1256,23 @@ int ssl3_get_key_exchange(SSL *s)
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
goto err;
}
- n2s(p,i);
- param_len=i+2;
+
+ param_len = 2;
if (param_len > n)
{
- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ n2s(p,i);
+
+ if (i > n - param_len)
+ {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH);
goto f_err;
}
+ param_len += i;
+
if (!(rsa->n=BN_bin2bn(p,i,rsa->n)))
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1258,14 +1280,23 @@ int ssl3_get_key_exchange(SSL *s)
}
p+=i;
+ if (2 > n - param_len)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ param_len += 2;
+
n2s(p,i);
- param_len+=i+2;
- if (param_len > n)
+
+ if (i > n - param_len)
{
- al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH);
goto f_err;
}
+ param_len += i;
+
if (!(rsa->e=BN_bin2bn(p,i,rsa->e)))
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1297,14 +1328,23 @@ int ssl3_get_key_exchange(SSL *s)
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB);
goto err;
}
- n2s(p,i);
- param_len=i+2;
+
+ param_len = 2;
if (param_len > n)
{
- al=SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ n2s(p,i);
+
+ if (i > n - param_len)
+ {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH);
goto f_err;
}
+ param_len += i;
+
if (!(dh->p=BN_bin2bn(p,i,NULL)))
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1312,14 +1352,23 @@ int ssl3_get_key_exchange(SSL *s)
}
p+=i;
+ if (2 > n - param_len)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ param_len += 2;
+
n2s(p,i);
- param_len+=i+2;
- if (param_len > n)
+
+ if (i > n - param_len)
{
- al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH);
goto f_err;
}
+ param_len += i;
+
if (!(dh->g=BN_bin2bn(p,i,NULL)))
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1327,14 +1376,23 @@ int ssl3_get_key_exchange(SSL *s)
}
p+=i;
+ if (2 > n - param_len)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ param_len += 2;
+
n2s(p,i);
- param_len+=i+2;
- if (param_len > n)
+
+ if (i > n - param_len)
{
- al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH);
goto f_err;
}
+ param_len += i;
+
if (!(dh->pub_key=BN_bin2bn(p,i,NULL)))
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1386,12 +1444,19 @@ int ssl3_get_key_exchange(SSL *s)
*/
/* XXX: For now we only support named (not generic) curves
- * and the ECParameters in this case is just three bytes.
+ * and the ECParameters in this case is just three bytes. We
+ * also need one byte for the length of the encoded point
*/
- param_len=3;
- if ((param_len > n) ||
- (*p != NAMED_CURVE_TYPE) ||
- ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0))
+ param_len=4;
+ if (param_len > n)
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+ SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+
+ if ((*p != NAMED_CURVE_TYPE) ||
+ ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0))
{
al=SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
@@ -1433,15 +1498,15 @@ int ssl3_get_key_exchange(SSL *s)
encoded_pt_len = *p; /* length of encoded point */
p+=1;
- param_len += (1 + encoded_pt_len);
- if ((param_len > n) ||
+
+ if ((encoded_pt_len > n - param_len) ||
(EC_POINT_oct2point(group, srvr_ecpoint,
p, encoded_pt_len, bn_ctx) == 0))
{
- al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT);
goto f_err;
}
+ param_len += encoded_pt_len;
n-=param_len;
p+=encoded_pt_len;
@@ -1486,10 +1551,10 @@ int ssl3_get_key_exchange(SSL *s)
n-=2;
j=EVP_PKEY_size(pkey);
+ /* Check signature length. If n is 0 then signature is empty */
if ((i != n) || (n > j) || (n <= 0))
{
/* wrong packet length */
- al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH);
goto f_err;
}
@@ -1498,6 +1563,7 @@ int ssl3_get_key_exchange(SSL *s)
if (pkey->type == EVP_PKEY_RSA)
{
int num;
+ unsigned int size;
j=0;
q=md_buf;
@@ -1508,9 +1574,9 @@ int ssl3_get_key_exchange(SSL *s)
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
EVP_DigestUpdate(&md_ctx,param,param_len);
- EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i);
- q+=i;
- j+=i;
+ EVP_DigestFinal_ex(&md_ctx,q,&size);
+ q+=size;
+ j+=size;
}
i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
pkey->pkey.rsa);
@@ -1582,7 +1648,6 @@ int ssl3_get_key_exchange(SSL *s)
/* still data left over */
if (n != 0)
{
- al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);
goto f_err;
}
@@ -2487,7 +2552,11 @@ int ssl3_send_client_key_exchange(SSL *s
#ifndef OPENSSL_NO_PSK
else if (alg_k & SSL_kPSK)
{
- char identity[PSK_MAX_IDENTITY_LEN];
+ /* The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes
+ * to return a \0-terminated identity. The last byte
+ * is for us for simulating strnlen. */
+ char identity[PSK_MAX_IDENTITY_LEN + 2];
+ size_t identity_len;
unsigned char *t = NULL;
unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4];
unsigned int pre_ms_len = 0, psk_len = 0;
@@ -2501,8 +2570,9 @@ int ssl3_send_client_key_exchange(SSL *s
goto err;
}
+ memset(identity, 0, sizeof(identity));
psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
- identity, PSK_MAX_IDENTITY_LEN,
+ identity, sizeof(identity) - 1,
psk_or_pre_ms, sizeof(psk_or_pre_ms));
if (psk_len > PSK_MAX_PSK_LEN)
{
@@ -2516,7 +2586,14 @@ int ssl3_send_client_key_exchange(SSL *s
SSL_R_PSK_IDENTITY_NOT_FOUND);
goto psk_err;
}
-
+ identity[PSK_MAX_IDENTITY_LEN + 1] = '\0';
+ identity_len = strlen(identity);
+ if (identity_len > PSK_MAX_IDENTITY_LEN)
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto psk_err;
+ }
/* create PSK pre_master_secret */
pre_ms_len = 2+psk_len+2+psk_len;
t = psk_or_pre_ms;
@@ -2550,14 +2627,13 @@ int ssl3_send_client_key_exchange(SSL *s
s->session->master_key_length =
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
- psk_or_pre_ms, pre_ms_len);
- n = strlen(identity);
- s2n(n, p);
- memcpy(p, identity, n);
- n+=2;
+ psk_or_pre_ms, pre_ms_len);
+ s2n(identity_len, p);
+ memcpy(p, identity, identity_len);
+ n = 2 + identity_len;
psk_err = 0;
psk_err:
- OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
+ OPENSSL_cleanse(identity, sizeof(identity));
OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
if (psk_err != 0)
{
Index: src/crypto/dist/openssl/ssl/s3_enc.c
diff -u src/crypto/dist/openssl/ssl/s3_enc.c:1.1.1.12.4.2 src/crypto/dist/openssl/ssl/s3_enc.c:1.1.1.12.4.2.2.1
--- src/crypto/dist/openssl/ssl/s3_enc.c:1.1.1.12.4.2 Wed Jan 25 20:34:57 2012
+++ src/crypto/dist/openssl/ssl/s3_enc.c Sun Oct 19 20:11:09 2014
@@ -817,7 +817,7 @@ int ssl3_alert_code(int code)
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+ case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
default: return(-1);
}
}
-
Index: src/crypto/dist/openssl/ssl/s3_lib.c
diff -u src/crypto/dist/openssl/ssl/s3_lib.c:1.14.4.1 src/crypto/dist/openssl/ssl/s3_lib.c:1.14.4.1.6.1
--- src/crypto/dist/openssl/ssl/s3_lib.c:1.14.4.1 Tue Jan 12 09:07:51 2010
+++ src/crypto/dist/openssl/ssl/s3_lib.c Sun Oct 19 20:11:09 2014
@@ -2477,6 +2477,29 @@ long ssl3_ctrl(SSL *s, int cmd, long lar
break;
#endif /* !OPENSSL_NO_TLSEXT */
+
+ case SSL_CTRL_CHECK_PROTO_VERSION:
+ /* For library-internal use; checks that the current protocol
+ * is the highest enabled version (according to s->ctx->method,
+ * as version negotiation may have changed s->method). */
+ if (s->version == s->ctx->method->version)
+ return 1;
+ /* Apparently we're using a version-flexible SSL_METHOD
+ * (not at its highest protocol version). */
+ if (s->ctx->method->version == SSLv23_method()->version)
+ {
+#if TLS_MAX_VERSION != TLS1_VERSION
+# error Code needs update for SSLv23_method() support beyond TLS1_VERSION.
+#endif
+ if (!(s->options & SSL_OP_NO_TLSv1))
+ return s->version == TLS1_VERSION;
+ if (!(s->options & SSL_OP_NO_SSLv3))
+ return s->version == SSL3_VERSION;
+ if (!(s->options & SSL_OP_NO_SSLv2))
+ return s->version == SSL2_VERSION;
+ }
+ return 0; /* Unexpected state; fail closed. */
+
default:
break;
}
@@ -2778,6 +2801,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx
break;
#endif
+
default:
return(0);
}
@@ -3320,4 +3344,3 @@ need to go to SSL_ST_ACCEPT.
}
return(ret);
}
-
Index: src/crypto/dist/openssl/ssl/s3_pkt.c
diff -u src/crypto/dist/openssl/ssl/s3_pkt.c:1.9.4.3.6.1 src/crypto/dist/openssl/ssl/s3_pkt.c:1.9.4.3.6.2
--- src/crypto/dist/openssl/ssl/s3_pkt.c:1.9.4.3.6.1 Fri Jun 6 06:42:08 2014
+++ src/crypto/dist/openssl/ssl/s3_pkt.c Sun Oct 19 20:11:09 2014
@@ -247,6 +247,12 @@ int ssl3_read_n(SSL *s, int n, int max,
return(n);
}
+/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will
+ * be processed per call to ssl3_get_record. Without this limit an attacker
+ * could send empty records at a faster rate than we can process and cause
+ * ssl3_get_record to loop forever. */
+#define MAX_EMPTY_RECORDS 32
+
/* Call this to get a new input record.
* It will return <= 0 if more data is needed, normally due to an error
* or non-blocking IO.
@@ -268,6 +274,7 @@ static int ssl3_get_record(SSL *s)
unsigned int mac_size;
int clear=0;
size_t extra;
+ unsigned empty_record_count = 0;
int decryption_failed_or_bad_record_mac = 0;
unsigned char *mac = NULL;
@@ -491,7 +498,17 @@ printf("\n");
s->packet_length=0;
/* just read a 0 length packet */
- if (rr->length == 0) goto again;
+ if (rr->length == 0)
+ {
+ empty_record_count++;
+ if (empty_record_count > MAX_EMPTY_RECORDS)
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_RECORD_TOO_SMALL);
+ goto f_err;
+ }
+ goto again;
+ }
#if 0
fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
Index: src/crypto/dist/openssl/ssl/s3_srvr.c
diff -u src/crypto/dist/openssl/ssl/s3_srvr.c:1.15.4.4.4.1 src/crypto/dist/openssl/ssl/s3_srvr.c:1.15.4.4.4.2
--- src/crypto/dist/openssl/ssl/s3_srvr.c:1.15.4.4.4.1 Fri Jun 6 06:42:08 2014
+++ src/crypto/dist/openssl/ssl/s3_srvr.c Sun Oct 19 20:11:09 2014
@@ -154,6 +154,7 @@
#include <stdio.h>
#include "ssl_locl.h"
#include "kssl_lcl.h"
+#include "../crypto/constant_time_locl.h"
#include <openssl/buffer.h>
#include <openssl/rand.h>
#include <openssl/objects.h>
@@ -1833,6 +1834,10 @@ int ssl3_get_client_key_exchange(SSL *s)
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
+ unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
+ int decrypt_len;
+ unsigned char decrypt_good, version_good;
+
/* FIX THIS UP EAY EAY EAY EAY */
if (s->s3->tmp.use_rsa_tmp)
{
@@ -1880,54 +1885,61 @@ int ssl3_get_client_key_exchange(SSL *s)
n=i;
}
- i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
-
- al = -1;
-
- if (i != SSL_MAX_MASTER_KEY_LENGTH)
- {
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
- }
-
- if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
+ /* We must not leak whether a decryption failure occurs because
+ * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
+ * RFC 2246, section 7.4.7.1). The code follows that advice of
+ * the TLS RFC and generates a random premaster secret for the
+ * case that the decrypt fails. See
+ * https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
+
+ /* should be RAND_bytes, but we cannot work around a failure. */
+ if (RAND_pseudo_bytes(rand_premaster_secret,
+ sizeof(rand_premaster_secret)) <= 0)
+ goto err;
+ decrypt_len = RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
+ ERR_clear_error();
+
+ /* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH.
+ * decrypt_good will be 0xff if so and zero otherwise. */
+ decrypt_good = constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
+
+ /* If the version in the decrypted pre-master secret is correct
+ * then version_good will be 0xff, otherwise it'll be zero.
+ * The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+ * (http://eprint.iacr.org/2003/052/) exploits the version
+ * number check as a "bad version oracle". Thus version checks
+ * are done in constant time and are treated like any other
+ * decryption error. */
+ version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8));
+ version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff));
+
+ /* The premaster secret must contain the same version number as
+ * the ClientHello to detect version rollback attacks
+ * (strangely, the protocol does not offer such protection for
+ * DH ciphersuites). However, buggy clients exist that send the
+ * negotiated protocol version instead if the server does not
+ * support the requested protocol version. If
+ * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
+ if (s->options & SSL_OP_TLS_ROLLBACK_BUG)
+ {
+ unsigned char workaround_good;
+ workaround_good = constant_time_eq_8(p[0], (unsigned)(s->version>>8));
+ workaround_good &= constant_time_eq_8(p[1], (unsigned)(s->version&0xff));
+ version_good |= workaround_good;
+ }
+
+ /* Both decryption and version must be good for decrypt_good
+ * to remain non-zero (0xff). */
+ decrypt_good &= version_good;
+
+ /* Now copy rand_premaster_secret over p using
+ * decrypt_good_mask. */
+ for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
{
- /* The premaster secret must contain the same version number as the
- * ClientHello to detect version rollback attacks (strangely, the
- * protocol does not offer such protection for DH ciphersuites).
- * However, buggy clients exist that send the negotiated protocol
- * version instead if the server does not support the requested
- * protocol version.
- * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
- if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
- (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
- {
- al=SSL_AD_DECODE_ERROR;
- /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
-
- /* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
- * (http://eprint.iacr.org/2003/052/) exploits the version
- * number check as a "bad version oracle" -- an alert would
- * reveal that the plaintext corresponding to some ciphertext
- * made up by the adversary is properly formatted except
- * that the version number is wrong. To avoid such attacks,
- * we should treat this just like any other decryption error. */
- }
+ p[i] = constant_time_select_8(decrypt_good, p[i],
+ rand_premaster_secret[i]);
}
- if (al != -1)
- {
- /* Some decryption failure -- use random value instead as countermeasure
- * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
- * (see RFC 2246, section 7.4.7.1). */
- ERR_clear_error();
- i = SSL_MAX_MASTER_KEY_LENGTH;
- p[0] = s->client_version >> 8;
- p[1] = s->client_version & 0xff;
- if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
- goto err;
- }
-
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
Index: src/crypto/dist/openssl/ssl/ssl-lib.com
diff -u src/crypto/dist/openssl/ssl/ssl-lib.com:1.1.1.6 src/crypto/dist/openssl/ssl/ssl-lib.com:1.1.1.6.38.1
--- src/crypto/dist/openssl/ssl/ssl-lib.com:1.1.1.6 Fri Nov 25 03:09:55 2005
+++ src/crypto/dist/openssl/ssl/ssl-lib.com Sun Oct 19 20:11:09 2014
@@ -195,7 +195,7 @@ $ NEXT_FILE:
$!
$! O.K, Extract The File Name From The File List.
$!
-$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_SSL)
+$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",LIB_SSL),"COLLAPSE")
$!
$! Check To See If We Are At The End Of The File List.
$!
Index: src/crypto/dist/openssl/ssl/ssl.h
diff -u src/crypto/dist/openssl/ssl/ssl.h:1.18.4.1 src/crypto/dist/openssl/ssl/ssl.h:1.18.4.1.6.1
--- src/crypto/dist/openssl/ssl/ssl.h:1.18.4.1 Sun Jul 5 00:34:52 2009
+++ src/crypto/dist/openssl/ssl/ssl.h Sun Oct 19 20:11:09 2014
@@ -590,6 +590,10 @@ typedef struct ssl_session_st
#define SSL_MODE_AUTO_RETRY 0x00000004L
/* Don't attempt to automatically build certificate chain */
#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+/* Send TLS_FALLBACK_SCSV in the ClientHello.
+ * To be set by applications that reconnect with a downgraded protocol
+ * version; see draft-ietf-tls-downgrade-scsv-00 for details. */
+#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
@@ -1276,6 +1280,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
+#define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */
#define SSL_ERROR_NONE 0
#define SSL_ERROR_SSL 1
@@ -1359,6 +1364,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
+
+#define SSL_CTRL_CHECK_PROTO_VERSION 119
#endif
#define SSL_session_reused(ssl) \
@@ -2006,6 +2013,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_HTTPS_PROXY_REQUEST 155
#define SSL_R_HTTP_REQUEST 156
#define SSL_R_ILLEGAL_PADDING 283
+#define SSL_R_INAPPROPRIATE_FALLBACK 373
#define SSL_R_INVALID_CHALLENGE_LENGTH 158
#define SSL_R_INVALID_COMMAND 280
#define SSL_R_INVALID_PURPOSE 278
@@ -2098,6 +2106,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216
#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217
#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218
+#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345
#define SSL_R_SERVERHELLO_TLSEXT 275
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
#define SSL_R_SHORT_READ 219
@@ -2133,6 +2142,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021
#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051
#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
+#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086
#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
Index: src/crypto/dist/openssl/ssl/ssl3.h
diff -u src/crypto/dist/openssl/ssl/ssl3.h:1.8.2.1 src/crypto/dist/openssl/ssl/ssl3.h:1.8.2.2
--- src/crypto/dist/openssl/ssl/ssl3.h:1.8.2.1 Fri Jun 6 06:42:08 2014
+++ src/crypto/dist/openssl/ssl/ssl3.h Sun Oct 19 20:11:09 2014
@@ -128,6 +128,14 @@
extern "C" {
#endif
+/* Signalling cipher suite value from RFC 5746
+ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */
+#define SSL3_CK_SCSV 0x030000FF
+
+/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
+ * (TLS_FALLBACK_SCSV) */
+#define SSL3_CK_FALLBACK_SCSV 0x03005600
+
#define SSL3_CK_RSA_NULL_MD5 0x03000001
#define SSL3_CK_RSA_NULL_SHA 0x03000002
#define SSL3_CK_RSA_RC4_40_MD5 0x03000003
@@ -505,6 +513,21 @@ typedef struct ssl3_state_st
int cert_request;
} tmp;
+ /* Connection binding to prevent renegotiation attacks */
+ unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
+ unsigned char previous_client_finished_len;
+ unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
+ unsigned char previous_server_finished_len;
+ int send_connection_binding; /* TODOEKR */
+
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+ /* This is set to true if we believe that this is a version of Safari
+ * running on OS X 10.6 or newer. We wish to know this because Safari
+ * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */
+ char is_probably_safari;
+#endif /* !OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_TLSEXT */
} SSL3_STATE;
Index: src/crypto/dist/openssl/ssl/ssl_err.c
diff -u src/crypto/dist/openssl/ssl/ssl_err.c:1.12.4.1 src/crypto/dist/openssl/ssl/ssl_err.c:1.12.4.1.6.1
--- src/crypto/dist/openssl/ssl/ssl_err.c:1.12.4.1 Sun Jul 5 00:34:52 2009
+++ src/crypto/dist/openssl/ssl/ssl_err.c Sun Oct 19 20:11:09 2014
@@ -341,6 +341,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
{ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"},
{ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"},
{ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"},
+{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK),"inappropriate fallback"},
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
{ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"},
@@ -468,6 +469,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"},
{ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"},
{ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),"tlsv1 alert inappropriate fallback"},
{ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"},
{ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"},
{ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"},
Index: src/crypto/dist/openssl/ssl/ssl_lib.c
diff -u src/crypto/dist/openssl/ssl/ssl_lib.c:1.5 src/crypto/dist/openssl/ssl/ssl_lib.c:1.5.2.1
--- src/crypto/dist/openssl/ssl/ssl_lib.c:1.5 Fri May 9 21:49:42 2008
+++ src/crypto/dist/openssl/ssl/ssl_lib.c Sun Oct 19 20:11:09 2014
@@ -1321,6 +1321,8 @@ int ssl_cipher_list_to_bytes(SSL *s,STAC
if (sk == NULL) return(0);
q=p;
+ if (put_cb == NULL)
+ put_cb = s->method->put_cipher_by_char;
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
{
@@ -1336,9 +1338,33 @@ int ssl_cipher_list_to_bytes(SSL *s,STAC
s->psk_client_callback == NULL)
continue;
#endif /* OPENSSL_NO_PSK */
- j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
+ j = put_cb(c,p);
p+=j;
}
+ /* If p == q, no ciphers; caller indicates an error.
+ * Otherwise, add applicable SCSVs. */
+ if (p != q)
+ {
+ if (!s->new_session)
+ {
+ static SSL_CIPHER scsv =
+ {
+ 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ j = put_cb(&scsv,p);
+ p+=j;
+ }
+ if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV)
+ {
+ static SSL_CIPHER scsv =
+ {
+ 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ j = put_cb(&scsv,p);
+ p+=j;
+ }
+ }
+
return(p-q);
}
@@ -1349,8 +1375,11 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe
STACK_OF(SSL_CIPHER) *sk;
int i,n;
+ if (s->s3)
+ s->s3->send_connection_binding = 0;
+
n=ssl_put_cipher_by_char(s,NULL,NULL);
- if ((num%n) != 0)
+ if (n == 0 || (num%n) != 0)
{
SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
return(NULL);
@@ -1377,6 +1406,62 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_ciphe
}
}
+ if ((skp == NULL) || (*skp == NULL))
+ sk=sk_SSL_CIPHER_new_null(); /* change perhaps later */
+ else
+ {
+ sk= *skp;
+ sk_SSL_CIPHER_zero(sk);
+ }
+
+ for (i=0; i<num; i+=n)
+ {
+ /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
+ if (s->s3 && (n != 3 || !p[0]) &&
+ (p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
+ (p[n-1] == (SSL3_CK_SCSV & 0xff)))
+ {
+ /* SCSV fatal if renegotiating */
+ if (s->new_session)
+ {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+ goto err;
+ }
+ s->s3->send_connection_binding = 1;
+ p += n;
+ continue;
+ }
+
+ /* Check for TLS_FALLBACK_SCSV */
+ if ((n != 3 || !p[0]) &&
+ (p[n-2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
+ (p[n-1] == (SSL3_CK_FALLBACK_SCSV & 0xff)))
+ {
+ /* The SCSV indicates that the client previously tried a higher version.
+ * Fail if the current version is an unexpected downgrade. */
+ if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL))
+ {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_INAPPROPRIATE_FALLBACK);
+ if (s->s3)
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
+ goto err;
+ }
+ continue;
+ }
+
+ c=ssl_get_cipher_by_char(s,p);
+ p+=n;
+ if (c != NULL)
+ {
+ if (!sk_SSL_CIPHER_push(sk,c))
+ {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ }
+
if (skp != NULL)
*skp=sk;
return(sk);
Index: src/crypto/dist/openssl/ssl/t1_enc.c
diff -u src/crypto/dist/openssl/ssl/t1_enc.c:1.1.1.12.4.1 src/crypto/dist/openssl/ssl/t1_enc.c:1.1.1.12.4.1.6.1
--- src/crypto/dist/openssl/ssl/t1_enc.c:1.1.1.12.4.1 Mon Apr 12 00:40:12 2010
+++ src/crypto/dist/openssl/ssl/t1_enc.c Sun Oct 19 20:11:09 2014
@@ -984,6 +984,7 @@ int tls1_alert_code(int code)
case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+ case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
#if 0 /* not appropriate for TLS, not used for DTLS */
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
Index: src/crypto/dist/openssl/ssl/t1_lib.c
diff -u src/crypto/dist/openssl/ssl/t1_lib.c:1.2.4.3.2.1 src/crypto/dist/openssl/ssl/t1_lib.c:1.2.4.3.2.2
--- src/crypto/dist/openssl/ssl/t1_lib.c:1.2.4.3.2.1 Wed Aug 27 13:30:49 2014
+++ src/crypto/dist/openssl/ssl/t1_lib.c Sun Oct 19 20:11:09 2014
@@ -938,15 +938,15 @@ int ssl_parse_serverhello_tlsext(SSL *s,
return 0;
}
if (!s->hit) {
- s->session->tlsext_ecpointformatlist_length = 0;
- if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
- if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
- {
- *al = TLS1_AD_INTERNAL_ERROR;
- return 0;
- }
- s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
- memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
+ s->session->tlsext_ecpointformatlist_length = 0;
+ if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
+ if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
+ {
+ *al = TLS1_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length;
+ memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length);
}
#if 0
fprintf(stderr,"ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist ");
@@ -1517,7 +1517,10 @@ static int tls_decrypt_ticket(SSL *s, co
HMAC_Final(&hctx, tick_hmac, NULL);
HMAC_CTX_cleanup(&hctx);
if (memcmp(tick_hmac, etick + eticklen, mlen))
+ {
+ EVP_CIPHER_CTX_cleanup(&ctx);
goto tickerr;
+ }
/* Attempt to decrypt session data */
/* Move p after IV to start of encrypted ticket, update length */
p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
Index: src/crypto/dist/openssl/ssl/tls1.h
diff -u src/crypto/dist/openssl/ssl/tls1.h:1.1.1.8 src/crypto/dist/openssl/ssl/tls1.h:1.1.1.8.2.1
--- src/crypto/dist/openssl/ssl/tls1.h:1.1.1.8 Fri May 9 21:34:46 2008
+++ src/crypto/dist/openssl/ssl/tls1.h Sun Oct 19 20:11:09 2014
@@ -163,6 +163,8 @@ extern "C" {
#define TLS1_VERSION_MAJOR 0x03
#define TLS1_VERSION_MINOR 0x01
+#define TLS_MAX_VERSION TLS1_VERSION
+
#define TLS1_AD_DECRYPTION_FAILED 21
#define TLS1_AD_RECORD_OVERFLOW 22
#define TLS1_AD_UNKNOWN_CA 48 /* fatal */
@@ -173,6 +175,7 @@ extern "C" {
#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */
#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */
#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */
+#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
#define TLS1_AD_USER_CANCELLED 90
#define TLS1_AD_NO_RENEGOTIATION 100
/* codes 110-114 are from RFC3546 */
Index: src/crypto/dist/openssl/test/Makefile
diff -u src/crypto/dist/openssl/test/Makefile:1.1.1.7 src/crypto/dist/openssl/test/Makefile:1.1.1.7.2.1
--- src/crypto/dist/openssl/test/Makefile:1.1.1.7 Fri May 9 21:34:46 2008
+++ src/crypto/dist/openssl/test/Makefile Sun Oct 19 20:11:09 2014
@@ -298,6 +298,10 @@ test_ige: $(IGETEST)$(EXE_EXT)
@echo "Test IGE mode"
../util/shlib_wrap.sh ./$(IGETEST)
+test_constant_time: $(CONSTTIMETEST)$(EXE_EXT)
+ @echo "Test constant time utilites"
+ ../util/shlib_wrap.sh ./$(CONSTTIMETEST)
+
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
@@ -428,6 +432,9 @@ $(ECDHTEST)$(EXE_EXT): $(ECDHTEST).o $(D
$(IGETEST)$(EXE_EXT): $(IGETEST).o $(DLIBCRYPTO)
@target=$(IGETEST); $(BUILD_CMD)
+$(CONSTTIMETEST)$(EXE_EXT): $(CONSTTIMETEST).o
+ @target=$(CONSTTIMETEST) $(BUILD_CMD)
+
#$(AESTEST).o: $(AESTEST).c
# $(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
@@ -461,6 +468,9 @@ bntest.o: ../include/openssl/stack.h ../
bntest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bntest.c
casttest.o: ../e_os.h ../include/openssl/cast.h ../include/openssl/e_os2.h
casttest.o: ../include/openssl/opensslconf.h casttest.c
+constant_time_test.o: ../crypto/constant_time_locl.h ../e_os.h
+constant_time_test.o: ../include/openssl/e_os2.h
+constant_time_test.o: ../include/openssl/opensslconf.h constant_time_test.c
destest.o: ../include/openssl/des.h ../include/openssl/des_old.h
destest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
destest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
Added files:
Index: src/crypto/dist/openssl/crypto/constant_time_locl.h
diff -u /dev/null src/crypto/dist/openssl/crypto/constant_time_locl.h:1.1.6.2
--- /dev/null Sun Oct 19 20:11:09 2014
+++ src/crypto/dist/openssl/crypto/constant_time_locl.h Sun Oct 19 20:11:08 2014
@@ -0,0 +1,216 @@
+/* crypto/constant_time_locl.h */
+/*
+ * Utilities for constant-time cryptography.
+ *
+ * Author: Emilia Kasper ([email protected])
+ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
+ * (Google).
+ * ====================================================================
+ * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young ([email protected])"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson ([email protected])"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CONSTANT_TIME_LOCL_H
+#define HEADER_CONSTANT_TIME_LOCL_H
+
+#include "e_os.h" /* For 'inline' */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
+ * and 0 for false. This is useful for choosing a value based on the result
+ * of a conditional in constant time. For example,
+ *
+ * if (a < b) {
+ * c = a;
+ * } else {
+ * c = b;
+ * }
+ *
+ * can be written as
+ *
+ * unsigned int lt = constant_time_lt(a, b);
+ * c = constant_time_select(lt, a, b);
+ */
+
+/*
+ * Returns the given value with the MSB copied to all the other
+ * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to
+ * replace this with something else on odd CPUs.
+ */
+static inline unsigned int constant_time_msb(unsigned int a);
+
+/*
+ * Returns 0xff..f if a < b and 0 otherwise.
+ */
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b);
+
+/*
+ * Returns 0xff..f if a >= b and 0 otherwise.
+ */
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b);
+
+/*
+ * Returns 0xff..f if a == 0 and 0 otherwise.
+ */
+static inline unsigned int constant_time_is_zero(unsigned int a);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_is_zero_8(unsigned int a);
+
+
+/*
+ * Returns 0xff..f if a == b and 0 otherwise.
+ */
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b);
+/* Signed integers. */
+static inline unsigned int constant_time_eq_int(int a, int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_int_8(int a, int b);
+
+
+/*
+ * Returns (mask & a) | (~mask & b).
+ *
+ * When |mask| is all 1s or all 0s (as returned by the methods above),
+ * the select methods return either |a| (if |mask| is nonzero) or |b|
+ * (if |mask| is zero).
+ */
+static inline unsigned int constant_time_select(unsigned int mask,
+ unsigned int a, unsigned int b);
+/* Convenience method for unsigned chars. */
+static inline unsigned char constant_time_select_8(unsigned char mask,
+ unsigned char a, unsigned char b);
+/* Convenience method for signed integers. */
+static inline int constant_time_select_int(unsigned int mask, int a, int b);
+
+static inline unsigned int constant_time_msb(unsigned int a)
+ {
+ return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
+ }
+
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
+ {
+ unsigned int lt;
+ /* Case 1: msb(a) == msb(b). a < b iff the MSB of a - b is set.*/
+ lt = ~(a ^ b) & (a - b);
+ /* Case 2: msb(a) != msb(b). a < b iff the MSB of b is set. */
+ lt |= ~a & b;
+ return constant_time_msb(lt);
+ }
+
+static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
+ {
+ return (unsigned char)(constant_time_lt(a, b));
+ }
+
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
+ {
+ unsigned int ge;
+ /* Case 1: msb(a) == msb(b). a >= b iff the MSB of a - b is not set.*/
+ ge = ~((a ^ b) | (a - b));
+ /* Case 2: msb(a) != msb(b). a >= b iff the MSB of a is set. */
+ ge |= a & ~b;
+ return constant_time_msb(ge);
+ }
+
+static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
+ {
+ return (unsigned char)(constant_time_ge(a, b));
+ }
+
+static inline unsigned int constant_time_is_zero(unsigned int a)
+ {
+ return constant_time_msb(~a & (a - 1));
+ }
+
+static inline unsigned char constant_time_is_zero_8(unsigned int a)
+ {
+ return (unsigned char)(constant_time_is_zero(a));
+ }
+
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b)
+ {
+ return constant_time_is_zero(a ^ b);
+ }
+
+static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b)
+ {
+ return (unsigned char)(constant_time_eq(a, b));
+ }
+
+static inline unsigned int constant_time_eq_int(int a, int b)
+ {
+ return constant_time_eq((unsigned)(a), (unsigned)(b));
+ }
+
+static inline unsigned char constant_time_eq_int_8(int a, int b)
+ {
+ return constant_time_eq_8((unsigned)(a), (unsigned)(b));
+ }
+
+static inline unsigned int constant_time_select(unsigned int mask,
+ unsigned int a, unsigned int b)
+ {
+ return (mask & a) | (~mask & b);
+ }
+
+static inline unsigned char constant_time_select_8(unsigned char mask,
+ unsigned char a, unsigned char b)
+ {
+ return (unsigned char)(constant_time_select(mask, a, b));
+ }
+
+inline int constant_time_select_int(unsigned int mask, int a, int b)
+ {
+ return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_CONSTANT_TIME_LOCL_H */
Index: src/crypto/dist/openssl/crypto/constant_time_test.c
diff -u /dev/null src/crypto/dist/openssl/crypto/constant_time_test.c:1.1.6.2
--- /dev/null Sun Oct 19 20:11:09 2014
+++ src/crypto/dist/openssl/crypto/constant_time_test.c Sun Oct 19 20:11:08 2014
@@ -0,0 +1,330 @@
+/* crypto/constant_time_test.c */
+/*
+ * Utilities for constant-time cryptography.
+ *
+ * Author: Emilia Kasper ([email protected])
+ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
+ * (Google).
+ * ====================================================================
+ * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young ([email protected])"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson ([email protected])"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "../crypto/constant_time_locl.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const unsigned int CONSTTIME_TRUE = (unsigned)(~0);
+static const unsigned int CONSTTIME_FALSE = 0;
+static const unsigned char CONSTTIME_TRUE_8 = 0xff;
+static const unsigned char CONSTTIME_FALSE_8 = 0;
+
+static int test_binary_op(unsigned int (*op)(unsigned int a, unsigned int b),
+ const char* op_name, unsigned int a, unsigned int b, int is_true)
+ {
+ unsigned c = op(a, b);
+ if (is_true && c != CONSTTIME_TRUE)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %du "
+ "(TRUE), got %du\n", op_name, a, b, CONSTTIME_TRUE, c);
+ return 1;
+ }
+ else if (!is_true && c != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %du "
+ "(FALSE), got %du\n", op_name, a, b, CONSTTIME_FALSE,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_binary_op_8(unsigned char (*op)(unsigned int a, unsigned int b),
+ const char* op_name, unsigned int a, unsigned int b, int is_true)
+ {
+ unsigned char c = op(a, b);
+ if (is_true && c != CONSTTIME_TRUE_8)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %u "
+ "(TRUE), got %u\n", op_name, a, b, CONSTTIME_TRUE_8, c);
+ return 1;
+ }
+ else if (!is_true && c != CONSTTIME_FALSE_8)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %u "
+ "(FALSE), got %u\n", op_name, a, b, CONSTTIME_FALSE_8,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_is_zero(unsigned int a)
+ {
+ unsigned int c = constant_time_is_zero(a);
+ if (a == 0 && c != CONSTTIME_TRUE)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %du (TRUE), got %du\n", a, CONSTTIME_TRUE, c);
+ return 1;
+ }
+ else if (a != 0 && c != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %du (FALSE), got %du\n", a, CONSTTIME_FALSE,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_is_zero_8(unsigned int a)
+ {
+ unsigned char c = constant_time_is_zero_8(a);
+ if (a == 0 && c != CONSTTIME_TRUE_8)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %u (TRUE), got %u\n", a, CONSTTIME_TRUE_8, c);
+ return 1;
+ }
+ else if (a != 0 && c != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %u (FALSE), got %u\n", a, CONSTTIME_FALSE_8,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_select(unsigned int a, unsigned int b)
+ {
+ unsigned int selected = constant_time_select(CONSTTIME_TRUE, a, b);
+ if (selected != a)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
+ "%du): expected %du(first value), got %du\n",
+ CONSTTIME_TRUE, a, b, a, selected);
+ return 1;
+ }
+ selected = constant_time_select(CONSTTIME_FALSE, a, b);
+ if (selected != b)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
+ "%du): expected %du(second value), got %du\n",
+ CONSTTIME_FALSE, a, b, b, selected);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_select_8(unsigned char a, unsigned char b)
+ {
+ unsigned char selected = constant_time_select_8(CONSTTIME_TRUE_8, a, b);
+ if (selected != a)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
+ "%u): expected %u(first value), got %u\n",
+ CONSTTIME_TRUE, a, b, a, selected);
+ return 1;
+ }
+ selected = constant_time_select_8(CONSTTIME_FALSE_8, a, b);
+ if (selected != b)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
+ "%u): expected %u(second value), got %u\n",
+ CONSTTIME_FALSE, a, b, b, selected);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_select_int(int a, int b)
+ {
+ int selected = constant_time_select_int(CONSTTIME_TRUE, a, b);
+ if (selected != a)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
+ "%d): expected %d(first value), got %d\n",
+ CONSTTIME_TRUE, a, b, a, selected);
+ return 1;
+ }
+ selected = constant_time_select_int(CONSTTIME_FALSE, a, b);
+ if (selected != b)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
+ "%d): expected %d(second value), got %d\n",
+ CONSTTIME_FALSE, a, b, b, selected);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_eq_int(int a, int b)
+ {
+ unsigned int equal = constant_time_eq_int(a, b);
+ if (a == b && equal != CONSTTIME_TRUE)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
+ "expected %du(TRUE), got %du\n",
+ a, b, CONSTTIME_TRUE, equal);
+ return 1;
+ }
+ else if (a != b && equal != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
+ "expected %du(FALSE), got %du\n",
+ a, b, CONSTTIME_FALSE, equal);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_eq_int_8(int a, int b)
+ {
+ unsigned char equal = constant_time_eq_int_8(a, b);
+ if (a == b && equal != CONSTTIME_TRUE_8)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
+ "expected %u(TRUE), got %u\n",
+ a, b, CONSTTIME_TRUE_8, equal);
+ return 1;
+ }
+ else if (a != b && equal != CONSTTIME_FALSE_8)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
+ "expected %u(FALSE), got %u\n",
+ a, b, CONSTTIME_FALSE_8, equal);
+ return 1;
+ }
+ return 0;
+ }
+
+static unsigned int test_values[] = {0, 1, 1024, 12345, 32000, UINT_MAX/2-1,
+ UINT_MAX/2, UINT_MAX/2+1, UINT_MAX-1,
+ UINT_MAX};
+
+static unsigned char test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
+
+static int signed_test_values[] = {0, 1, -1, 1024, -1024, 12345, -12345,
+ 32000, -32000, INT_MAX, INT_MIN, INT_MAX-1,
+ INT_MIN+1};
+
+
+int main(int argc, char *argv[])
+ {
+ unsigned int a, b, i, j;
+ int c, d;
+ unsigned char e, f;
+ int num_failed = 0, num_all = 0;
+ fprintf(stdout, "Testing constant time operations...\n");
+
+ for (i = 0; i < sizeof(test_values)/sizeof(int); ++i)
+ {
+ a = test_values[i];
+ num_failed += test_is_zero(a);
+ num_failed += test_is_zero_8(a);
+ num_all += 2;
+ for (j = 0; j < sizeof(test_values)/sizeof(int); ++j)
+ {
+ b = test_values[j];
+ num_failed += test_binary_op(&constant_time_lt,
+ "constant_time_lt", a, b, a < b);
+ num_failed += test_binary_op_8(&constant_time_lt_8,
+ "constant_time_lt_8", a, b, a < b);
+ num_failed += test_binary_op(&constant_time_lt,
+ "constant_time_lt_8", b, a, b < a);
+ num_failed += test_binary_op_8(&constant_time_lt_8,
+ "constant_time_lt_8", b, a, b < a);
+ num_failed += test_binary_op(&constant_time_ge,
+ "constant_time_ge", a, b, a >= b);
+ num_failed += test_binary_op_8(&constant_time_ge_8,
+ "constant_time_ge_8", a, b, a >= b);
+ num_failed += test_binary_op(&constant_time_ge,
+ "constant_time_ge", b, a, b >= a);
+ num_failed += test_binary_op_8(&constant_time_ge_8,
+ "constant_time_ge_8", b, a, b >= a);
+ num_failed += test_binary_op(&constant_time_eq,
+ "constant_time_eq", a, b, a == b);
+ num_failed += test_binary_op_8(&constant_time_eq_8,
+ "constant_time_eq_8", a, b, a == b);
+ num_failed += test_binary_op(&constant_time_eq,
+ "constant_time_eq", b, a, b == a);
+ num_failed += test_binary_op_8(&constant_time_eq_8,
+ "constant_time_eq_8", b, a, b == a);
+ num_failed += test_select(a, b);
+ num_all += 13;
+ }
+ }
+
+ for (i = 0; i < sizeof(signed_test_values)/sizeof(int); ++i)
+ {
+ c = signed_test_values[i];
+ for (j = 0; j < sizeof(signed_test_values)/sizeof(int); ++j)
+ {
+ d = signed_test_values[j];
+ num_failed += test_select_int(c, d);
+ num_failed += test_eq_int(c, d);
+ num_failed += test_eq_int_8(c, d);
+ num_all += 3;
+ }
+ }
+
+ for (i = 0; i < sizeof(test_values_8); ++i)
+ {
+ e = test_values_8[i];
+ for (j = 0; j < sizeof(test_values_8); ++j)
+ {
+ f = test_values_8[j];
+ num_failed += test_select_8(e, f);
+ num_all += 1;
+ }
+ }
+
+ if (!num_failed)
+ {
+ fprintf(stdout, "ok (ran %d tests)\n", num_all);
+ return EXIT_SUCCESS;
+ }
+ else
+ {
+ fprintf(stdout, "%d of %d tests failed!\n", num_failed, num_all);
+ return EXIT_FAILURE;
+ }
+ }
Index: src/crypto/dist/openssl/doc/crypto/CMS_add1_signer.pod
diff -u /dev/null src/crypto/dist/openssl/doc/crypto/CMS_add1_signer.pod:1.1.6.2
--- /dev/null Sun Oct 19 20:11:09 2014
+++ src/crypto/dist/openssl/doc/crypto/CMS_add1_signer.pod Sun Oct 19 20:11:08 2014
@@ -0,0 +1,101 @@
+=pod
+
+=head1 NAME
+
+ CMS_add1_signer, CMS_SignerInfo_sign - add a signer to a CMS_ContentInfo signed data structure.
+
+=head1 SYNOPSIS
+
+ #include <openssl/cms.h>
+
+ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, unsigned int flags);
+
+ int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+
+
+=head1 DESCRIPTION
+
+CMS_add1_signer() adds a signer with certificate B<signcert> and private
+key B<pkey> using message digest B<md> to CMS_ContentInfo SignedData
+structure B<cms>.
+
+The CMS_ContentInfo structure should be obtained from an initial call to
+CMS_sign() with the flag B<CMS_PARTIAL> set or in the case or re-signing a
+valid CMS_ContentInfo SignedData structure.
+
+If the B<md> parameter is B<NULL> then the default digest for the public
+key algorithm will be used.
+
+Unless the B<CMS_REUSE_DIGEST> flag is set the returned CMS_ContentInfo
+structure is not complete and must be finalized either by streaming (if
+applicable) or a call to CMS_final().
+
+The CMS_SignerInfo_sign() function will explicitly sign a CMS_SignerInfo
+structure, its main use is when B<CMS_REUSE_DIGEST> and B<CMS_PARTIAL> flags
+are both set.
+
+=head1 NOTES
+
+The main purpose of CMS_add1_signer() is to provide finer control
+over a CMS signed data structure where the simpler CMS_sign() function defaults
+are not appropriate. For example if multiple signers or non default digest
+algorithms are needed. New attributes can also be added using the returned
+CMS_SignerInfo structure and the CMS attribute utility functions or the
+CMS signed receipt request functions.
+
+Any of the following flags (ored together) can be passed in the B<flags>
+parameter.
+
+If B<CMS_REUSE_DIGEST> is set then an attempt is made to copy the content
+digest value from the CMS_ContentInfo structure: to add a signer to an existing
+structure. An error occurs if a matching digest value cannot be found to copy.
+The returned CMS_ContentInfo structure will be valid and finalized when this
+flag is set.
+
+If B<CMS_PARTIAL> is set in addition to B<CMS_REUSE_DIGEST> then the
+CMS_SignerInfo structure will not be finalized so additional attributes
+can be added. In this case an explicit call to CMS_SignerInfo_sign() is
+needed to finalize it.
+
+If B<CMS_NOCERTS> is set the signer's certificate will not be included in the
+CMS_ContentInfo structure, the signer's certificate must still be supplied in
+the B<signcert> parameter though. This can reduce the size of the signature if
+the signers certificate can be obtained by other means: for example a
+previously signed message.
+
+The SignedData structure includes several CMS signedAttributes including the
+signing time, the CMS content type and the supported list of ciphers in an
+SMIMECapabilities attribute. If B<CMS_NOATTR> is set then no signedAttributes
+will be used. If B<CMS_NOSMIMECAP> is set then just the SMIMECapabilities are
+omitted.
+
+OpenSSL will by default identify signing certificates using issuer name
+and serial number. If B<CMS_USE_KEYID> is set it will use the subject key
+identifier value instead. An error occurs if the signing certificate does not
+have a subject key identifier extension.
+
+If present the SMIMECapabilities attribute indicates support for the following
+algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192
+bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2.
+If any of these algorithms is not available then it will not be included: for example the GOST algorithms will not be included if the GOST ENGINE is
+not loaded.
+
+CMS_add1_signer() returns an internal pointer to the CMS_SignerInfo
+structure just added, this can be used to set additional attributes
+before it is finalized.
+
+=head1 RETURN VALUES
+
+CMS_add1_signer() returns an internal pointer to the CMS_SignerInfo
+structure just added or NULL if an error occurs.
+
+=head1 SEE ALSO
+
+L<ERR_get_error(3)|ERR_get_error(3)>, L<CMS_sign(3)|CMS_sign(3)>,
+L<CMS_final(3)|CMS_final(3)>,
+
+=head1 HISTORY
+
+CMS_add1_signer() was added to OpenSSL 0.9.8
+
+=cut
Index: src/crypto/dist/openssl/test/constant_time_test.c
diff -u /dev/null src/crypto/dist/openssl/test/constant_time_test.c:1.1.6.2
--- /dev/null Sun Oct 19 20:11:09 2014
+++ src/crypto/dist/openssl/test/constant_time_test.c Sun Oct 19 20:11:09 2014
@@ -0,0 +1,330 @@
+/* crypto/constant_time_test.c */
+/*
+ * Utilities for constant-time cryptography.
+ *
+ * Author: Emilia Kasper ([email protected])
+ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
+ * (Google).
+ * ====================================================================
+ * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young ([email protected])"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson ([email protected])"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "../crypto/constant_time_locl.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const unsigned int CONSTTIME_TRUE = (unsigned)(~0);
+static const unsigned int CONSTTIME_FALSE = 0;
+static const unsigned char CONSTTIME_TRUE_8 = 0xff;
+static const unsigned char CONSTTIME_FALSE_8 = 0;
+
+static int test_binary_op(unsigned int (*op)(unsigned int a, unsigned int b),
+ const char* op_name, unsigned int a, unsigned int b, int is_true)
+ {
+ unsigned c = op(a, b);
+ if (is_true && c != CONSTTIME_TRUE)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %du "
+ "(TRUE), got %du\n", op_name, a, b, CONSTTIME_TRUE, c);
+ return 1;
+ }
+ else if (!is_true && c != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %du "
+ "(FALSE), got %du\n", op_name, a, b, CONSTTIME_FALSE,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_binary_op_8(unsigned char (*op)(unsigned int a, unsigned int b),
+ const char* op_name, unsigned int a, unsigned int b, int is_true)
+ {
+ unsigned char c = op(a, b);
+ if (is_true && c != CONSTTIME_TRUE_8)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %u "
+ "(TRUE), got %u\n", op_name, a, b, CONSTTIME_TRUE_8, c);
+ return 1;
+ }
+ else if (!is_true && c != CONSTTIME_FALSE_8)
+ {
+ fprintf(stderr, "Test failed for %s(%du, %du): expected %u "
+ "(FALSE), got %u\n", op_name, a, b, CONSTTIME_FALSE_8,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_is_zero(unsigned int a)
+ {
+ unsigned int c = constant_time_is_zero(a);
+ if (a == 0 && c != CONSTTIME_TRUE)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %du (TRUE), got %du\n", a, CONSTTIME_TRUE, c);
+ return 1;
+ }
+ else if (a != 0 && c != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %du (FALSE), got %du\n", a, CONSTTIME_FALSE,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_is_zero_8(unsigned int a)
+ {
+ unsigned char c = constant_time_is_zero_8(a);
+ if (a == 0 && c != CONSTTIME_TRUE_8)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %u (TRUE), got %u\n", a, CONSTTIME_TRUE_8, c);
+ return 1;
+ }
+ else if (a != 0 && c != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+ "expected %u (FALSE), got %u\n", a, CONSTTIME_FALSE_8,
+ c);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_select(unsigned int a, unsigned int b)
+ {
+ unsigned int selected = constant_time_select(CONSTTIME_TRUE, a, b);
+ if (selected != a)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
+ "%du): expected %du(first value), got %du\n",
+ CONSTTIME_TRUE, a, b, a, selected);
+ return 1;
+ }
+ selected = constant_time_select(CONSTTIME_FALSE, a, b);
+ if (selected != b)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
+ "%du): expected %du(second value), got %du\n",
+ CONSTTIME_FALSE, a, b, b, selected);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_select_8(unsigned char a, unsigned char b)
+ {
+ unsigned char selected = constant_time_select_8(CONSTTIME_TRUE_8, a, b);
+ if (selected != a)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
+ "%u): expected %u(first value), got %u\n",
+ CONSTTIME_TRUE, a, b, a, selected);
+ return 1;
+ }
+ selected = constant_time_select_8(CONSTTIME_FALSE_8, a, b);
+ if (selected != b)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
+ "%u): expected %u(second value), got %u\n",
+ CONSTTIME_FALSE, a, b, b, selected);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_select_int(int a, int b)
+ {
+ int selected = constant_time_select_int(CONSTTIME_TRUE, a, b);
+ if (selected != a)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
+ "%d): expected %d(first value), got %d\n",
+ CONSTTIME_TRUE, a, b, a, selected);
+ return 1;
+ }
+ selected = constant_time_select_int(CONSTTIME_FALSE, a, b);
+ if (selected != b)
+ {
+ fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
+ "%d): expected %d(second value), got %d\n",
+ CONSTTIME_FALSE, a, b, b, selected);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_eq_int(int a, int b)
+ {
+ unsigned int equal = constant_time_eq_int(a, b);
+ if (a == b && equal != CONSTTIME_TRUE)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
+ "expected %du(TRUE), got %du\n",
+ a, b, CONSTTIME_TRUE, equal);
+ return 1;
+ }
+ else if (a != b && equal != CONSTTIME_FALSE)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
+ "expected %du(FALSE), got %du\n",
+ a, b, CONSTTIME_FALSE, equal);
+ return 1;
+ }
+ return 0;
+ }
+
+static int test_eq_int_8(int a, int b)
+ {
+ unsigned char equal = constant_time_eq_int_8(a, b);
+ if (a == b && equal != CONSTTIME_TRUE_8)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
+ "expected %u(TRUE), got %u\n",
+ a, b, CONSTTIME_TRUE_8, equal);
+ return 1;
+ }
+ else if (a != b && equal != CONSTTIME_FALSE_8)
+ {
+ fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
+ "expected %u(FALSE), got %u\n",
+ a, b, CONSTTIME_FALSE_8, equal);
+ return 1;
+ }
+ return 0;
+ }
+
+static unsigned int test_values[] = {0, 1, 1024, 12345, 32000, UINT_MAX/2-1,
+ UINT_MAX/2, UINT_MAX/2+1, UINT_MAX-1,
+ UINT_MAX};
+
+static unsigned char test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
+
+static int signed_test_values[] = {0, 1, -1, 1024, -1024, 12345, -12345,
+ 32000, -32000, INT_MAX, INT_MIN, INT_MAX-1,
+ INT_MIN+1};
+
+
+int main(int argc, char *argv[])
+ {
+ unsigned int a, b, i, j;
+ int c, d;
+ unsigned char e, f;
+ int num_failed = 0, num_all = 0;
+ fprintf(stdout, "Testing constant time operations...\n");
+
+ for (i = 0; i < sizeof(test_values)/sizeof(int); ++i)
+ {
+ a = test_values[i];
+ num_failed += test_is_zero(a);
+ num_failed += test_is_zero_8(a);
+ num_all += 2;
+ for (j = 0; j < sizeof(test_values)/sizeof(int); ++j)
+ {
+ b = test_values[j];
+ num_failed += test_binary_op(&constant_time_lt,
+ "constant_time_lt", a, b, a < b);
+ num_failed += test_binary_op_8(&constant_time_lt_8,
+ "constant_time_lt_8", a, b, a < b);
+ num_failed += test_binary_op(&constant_time_lt,
+ "constant_time_lt_8", b, a, b < a);
+ num_failed += test_binary_op_8(&constant_time_lt_8,
+ "constant_time_lt_8", b, a, b < a);
+ num_failed += test_binary_op(&constant_time_ge,
+ "constant_time_ge", a, b, a >= b);
+ num_failed += test_binary_op_8(&constant_time_ge_8,
+ "constant_time_ge_8", a, b, a >= b);
+ num_failed += test_binary_op(&constant_time_ge,
+ "constant_time_ge", b, a, b >= a);
+ num_failed += test_binary_op_8(&constant_time_ge_8,
+ "constant_time_ge_8", b, a, b >= a);
+ num_failed += test_binary_op(&constant_time_eq,
+ "constant_time_eq", a, b, a == b);
+ num_failed += test_binary_op_8(&constant_time_eq_8,
+ "constant_time_eq_8", a, b, a == b);
+ num_failed += test_binary_op(&constant_time_eq,
+ "constant_time_eq", b, a, b == a);
+ num_failed += test_binary_op_8(&constant_time_eq_8,
+ "constant_time_eq_8", b, a, b == a);
+ num_failed += test_select(a, b);
+ num_all += 13;
+ }
+ }
+
+ for (i = 0; i < sizeof(signed_test_values)/sizeof(int); ++i)
+ {
+ c = signed_test_values[i];
+ for (j = 0; j < sizeof(signed_test_values)/sizeof(int); ++j)
+ {
+ d = signed_test_values[j];
+ num_failed += test_select_int(c, d);
+ num_failed += test_eq_int(c, d);
+ num_failed += test_eq_int_8(c, d);
+ num_all += 3;
+ }
+ }
+
+ for (i = 0; i < sizeof(test_values_8); ++i)
+ {
+ e = test_values_8[i];
+ for (j = 0; j < sizeof(test_values_8); ++j)
+ {
+ f = test_values_8[j];
+ num_failed += test_select_8(e, f);
+ num_all += 1;
+ }
+ }
+
+ if (!num_failed)
+ {
+ fprintf(stdout, "ok (ran %d tests)\n", num_all);
+ return EXIT_SUCCESS;
+ }
+ else
+ {
+ fprintf(stdout, "%d of %d tests failed!\n", num_failed, num_all);
+ return EXIT_FAILURE;
+ }
+ }