Compare commits

...

29 Commits

Author SHA1 Message Date
Matt Caswell
36216218ca Prepare for 0.9.8zc release
Reviewed-by: Stephen Henson <steve@openssl.org>
2014-10-15 13:48:52 +01:00
Matt Caswell
115eaf4886 make update
Reviewed-by: Stephen Henson <steve@openssl.org>
2014-10-15 13:48:52 +01:00
Matt Caswell
53ce5647d4 Updates to NEWS
Reviewed-by: Dr Stephen Henson <steve@openssl.org>
2014-10-15 08:46:57 -04:00
Matt Caswell
4d2efa29f6 Updates to CHANGES file
Reviewed-by: Bodo Möller <bodo@openssl.org>
2014-10-15 08:46:57 -04:00
Geoff Thorpe
cd332a0750 Fix no-ssl3 configuration option
CVE-2014-3568

Reviewed-by: Emilia Kasper <emilia@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
2014-10-15 08:46:57 -04:00
Dr. Stephen Henson
2ed80d14d7 Fix for session tickets memory leak.
CVE-2014-3567

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(cherry picked from commit 90e53055939db40cf0fac1ad0c59630280aeee86)
2014-10-15 08:46:57 -04:00
Bodo Moeller
d286606301 Fix SSL_R naming inconsistency.
Reviewed-by: Tim Hudson <tjh@openssl.org>
2014-10-15 14:39:17 +02:00
Bodo Moeller
3f4d81e88b Add TLS_FALLBACK_SCSV documentation, and move s_client -fallback_scsv
handling out of #ifndef OPENSSL_NO_DTLS1 section.

Reviewed-by: Rich Salz <rsalz@openssl.org>
2014-10-15 11:15:58 +02:00
Bodo Moeller
dc5dfe431c Oops -- fix typo in coment added with TLS_FALLBACK_SCSV support.
Reviewed-by: Steve Henson <steve@openss.org>
2014-10-15 04:26:29 +02:00
Bodo Moeller
c6a876473c Support TLS_FALLBACK_SCSV.
Reviewed-by: Stephen Henson <steve@openssl.org>
2014-10-15 04:18:29 +02:00
Dr. Stephen Henson
5a7fc89394 Add additional DigestInfo checks.
Reencode DigestInto in DER and check against the original: this
will reject any improperly encoded DigestInfo structures.

Note: this is a precautionary measure, there is no known attack
which can exploit this.

Thanks to Brian Smith for reporting this issue.
Reviewed-by: Tim Hudson <tjh@openssl.org>
2014-09-29 12:31:29 +01:00
Emilia Kasper
116fd3732a Add missing tests
Accidentally omitted from commit 455b65dfab

Reviewed-by: Kurt Roeckx <kurt@openssl.org>
(cherry picked from commit fdc35a9d3e)
2014-09-25 13:48:08 +02:00
Emilia Kasper
1bb01b1b5f RT3425: constant-time evp_enc
Do the final padding check in EVP_DecryptFinal_ex in constant time to
avoid a timing leak from padding failure.

Reviewed-by: Rich Salz <rsalz@openssl.org>
(cherry picked from commit b55ff319f8)

Conflicts:
	crypto/evp/Makefile
	crypto/evp/evp_enc.c
2014-09-24 16:41:55 +02:00
Emilia Kasper
699d78ce98 RT3067: simplify patch
(Original commit adb46dbc6d)

Use the new constant-time methods consistently in s3_srvr.c

Reviewed-by: Kurt Roeckx <kurt@openssl.org>
(cherry picked from commit 455b65dfab)

Conflicts:
	ssl/Makefile
2014-09-24 16:01:46 +02:00
Adam Langley
43d613ec18 This change alters the processing of invalid, RSA pre-master secrets so
that bad encryptions are treated like random session keys in constant
time.

(cherry picked from commit adb46dbc6d)

Reviewed-by: Rich Salz <rsalz@openssl.org>
2014-09-24 16:00:16 +02:00
Emilia Kasper
96e1015eec RT3066: rewrite RSA padding checks to be slightly more constant time.
Also tweak s3_cbc.c to use new constant-time methods.
Also fix memory leaks from internal errors in RSA_padding_check_PKCS1_OAEP_mgf1

This patch is based on the original RT submission by Adam Langley <agl@chromium.org>,
as well as code from BoringSSL and OpenSSL.

Reviewed-by: Kurt Roeckx <kurt@openssl.org>

Conflicts:
	crypto/rsa/rsa_oaep.c
2014-09-24 14:39:44 +02:00
Tim Hudson
cf4b01a766 Fixed error introduced in commit f2be92b94d
that fixed PR#3450 where an existing cast masked an issue when i was changed
from int to long in that commit

Picked up on z/linux (s390) where sizeof(int)!=sizeof(long)

Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(cherry picked from commit b5ff559ff9)
2014-09-22 06:31:05 +10:00
Adam Langley
45d129511f Ensure that x**0 mod 1 = 0.
(cherry picked from commit 2b0180c37f)

Reviewed-by: Ben Laurie <ben@openssl.org>
2014-09-04 16:07:39 +02:00
Richard Levitte
0976adac8f Followup on RT3334 fix: make sure that a directory that's the empty
string returns 0 with errno = ENOENT.

Reviewed-by: Andy Polyakov <appro@openssl.org>
(cherry picked from commit 360928b7d0)
2014-09-03 22:26:24 +02:00
Phil Mesnier
db5b0d9309 RT3334: Fix crypto/LPdir_win.c
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Andy Polyakov <appro@openssl.org>
(cherry picked from commit 6a14fe7576)
2014-09-03 22:26:24 +02:00
Emilia Kasper
aeeedc8acc Make the inline const-time functions static.
"inline" without static is not correct as the compiler may choose to ignore it
and will then either emit an external definition, or expect one.

Reviewed-by: Geoff Thorpe <geoff@openssl.org>
(cherry picked from commit 86f50b36e6)
2014-09-02 15:25:20 +02:00
Matt Caswell
c903866420 Fixed double inclusion of string.h
PR2693

Reviewed-by: Tim Hudson <tjh@openssl.org>
(cherry picked from commit 5d33b70ef5a4768fdfb77a73f9817c4570613039)
2014-08-29 21:40:15 +01:00
Emilia Kasper
9b208659aa Constant-time utilities
Pull constant-time methods out to a separate header, add tests.

Reviewed-by: Bodo Moeller <bodo@openssl.org>
(cherry picked from commit 73729e4cf3)

Conflicts:
	ssl/Makefile
	test/Makefile
2014-08-28 17:28:42 +02:00
Adam Langley
f54fab0fef RT3060: Limit the number of empty records.
Limit the number of empty records that will be processed consecutively
in order to prevent ssl3_get_record from never returning.

Reported by "oftc_must_be_destroyed" and George Kadianakis.

Reviewed-by: Bodo Moeller <bodo@openssl.org>
(cherry picked from commit 3aac17a82f)
2014-08-22 15:53:34 +02:00
Emilia Kasper
b30aaafbe5 define inline for Visual Studio
In Visual Studio, inline is available in C++ only, however __inline is available for C, see
http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Dr Stephen Henson <steve@openssl.org>
(cherry picked from commit f511b25a73)

Conflicts:
	e_os.h
2014-08-21 16:08:55 +02:00
Adam Langley
fee8d86d7a Add volatile qualifications to two blocks of inline asm to stop GCC from
eliminating them as dead code.

Both volatile and "memory" are used because of some concern that the compiler
may still cache values across the asm block without it, and because this was
such a painful debugging session that I wanted to ensure that it's never
repeated.

(cherry picked from commit 7753a3a684)

Conflicts:
	crypto/bn/asm/x86_64-gcc.c

Reviewed-by: Rich Salz <rsalz@openssl.org>
(cherry picked from commit a90b1e32d2)
2014-08-19 17:12:08 +02:00
Matt Caswell
bf3e53a7fa Fixed out-of-bounds read errors in ssl3_get_key_exchange.
PR#3450

Conflicts:
	ssl/s3_clnt.c

Reviewed-by: Emilia Käsper <emilia@openssl.org>
2014-08-15 23:34:45 +01:00
Bodo Moeller
44a8fced97 Further improve/fix ec_GFp_simple_points_make_affine (ecp_smpl.c) and
group_order_tests (ectest.c).  Also fix the EC_POINTs_mul documentation (ec.h).

Reviewed-by: emilia@openssl.org

Conflicts:
	crypto/ec/ectest.c

Conflicts:
	crypto/ec/ec.h
2014-08-13 18:09:00 +02:00
Matt Caswell
4ff07f4c71 Prepare for 0.9.8zc-dev
Reviewed-by: Stephen Henson <steve@openssl.org>
2014-08-06 22:29:40 +01:00
48 changed files with 1329 additions and 351 deletions

37
CHANGES
View File

@@ -2,6 +2,43 @@
OpenSSL CHANGES
_______________
Changes between 0.9.8zb and 0.9.8zc [15 Oct 2014]
*) Session Ticket Memory Leak.
When an OpenSSL SSL/TLS/DTLS server receives a session ticket the
integrity of that ticket is first verified. In the event of a session
ticket integrity check failing, OpenSSL will fail to free memory
causing a memory leak. By sending a large number of invalid session
tickets an attacker could exploit this issue in a Denial Of Service
attack.
(CVE-2014-3567)
[Steve Henson]
*) Build option no-ssl3 is incomplete.
When OpenSSL is configured with "no-ssl3" as a build option, servers
could accept and complete a SSL 3.0 handshake, and clients could be
configured to send them.
(CVE-2014-3568)
[Akamai and the OpenSSL team]
*) Add support for TLS_FALLBACK_SCSV.
Client applications doing fallback retries should call
SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
(CVE-2014-3566)
[Adam Langley, Bodo Moeller]
*) Add additional DigestInfo checks.
Reencode DigestInto in DER and check against the original when
verifying RSA signature: this will reject any improperly encoded
DigestInfo structures.
Note: this is a precautionary measure and no attacks are currently known.
[Steve Henson]
Changes between 0.9.8za and 0.9.8zb [6 Aug 2014]
*) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject

7
NEWS
View File

@@ -5,6 +5,13 @@
This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file.
Major changes between OpenSSL 0.9.8zb and OpenSSL 0.9.8zc [15 Oct 2014]:
o Fix for CVE-2014-3513
o Fix for CVE-2014-3567
o Mitigation for CVE-2014-3566 (SSL protocol vulnerability)
o Fix for CVE-2014-3568
Major changes between OpenSSL 0.9.8za and OpenSSL 0.9.8zb [6 Aug 2014]:
o Fix for CVE-2014-3510

2
README
View File

@@ -1,5 +1,5 @@
OpenSSL 0.9.8zb 6 Aug 2014
OpenSSL 0.9.8zc 15 Oct 2014
Copyright (c) 1998-2011 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson

View File

@@ -226,6 +226,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 link layer 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");
@@ -339,6 +340,7 @@ int MAIN(int argc, char **argv)
char *sess_out = NULL;
struct sockaddr peer;
int peerlen = sizeof(peer);
int fallback_scsv = 0;
int enable_timeouts = 0 ;
long socket_mtu = 0;
#ifndef OPENSSL_NO_JPAKE
@@ -488,6 +490,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)
@@ -778,6 +784,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)
{

View File

@@ -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 <richard@levitte.org>
* All rights reserved.
@@ -82,6 +81,12 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
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] != '>'

View File

@@ -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 <richard@levitte.org>
* All rights reserved.
@@ -65,6 +64,16 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
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)
{
@@ -73,15 +82,35 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
}
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;
@@ -89,17 +118,23 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
}
#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)
{
@@ -116,7 +151,6 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
return 0;
}
}
if (sizeof(TCHAR) != sizeof(char))
{
TCHAR *wdir = (*ctx)->ctx.cFileName;

View File

@@ -30,6 +30,7 @@ AFLAGS=$(ASFLAGS)
LIBS=
GENERAL=Makefile README crypto-lib.com install.com
TEST=constant_time_test.c
LIB= $(TOP)/libcrypto.a
SHARED_LIB= libcrypto$(SHLIB_EXT)

View File

@@ -185,7 +185,7 @@ BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
if (n <= 0) return 0;
asm (
asm volatile (
" subq %2,%2 \n"
".align 16 \n"
"1: movq (%4,%2,8),%0 \n"
@@ -196,7 +196,7 @@ BN_ULONG bn_add_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
" sbbq %0,%0 \n"
: "=&a"(ret),"+c"(n),"=&r"(i)
: "r"(rp),"r"(ap),"r"(bp)
: "cc"
: "cc", "memory"
);
return ret&1;
@@ -208,7 +208,7 @@ BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
if (n <= 0) return 0;
asm (
asm volatile (
" subq %2,%2 \n"
".align 16 \n"
"1: movq (%4,%2,8),%0 \n"
@@ -219,7 +219,7 @@ BN_ULONG bn_sub_words (BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int
" sbbq %0,%0 \n"
: "=&a"(ret),"+c"(n),"=&r"(i)
: "r"(rp),"r"(ap),"r"(bp)
: "cc"
: "cc", "memory"
);
return ret&1;

View File

@@ -767,7 +767,14 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
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)

View File

@@ -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;
@@ -190,7 +227,13 @@ int main(int argc, char *argv[])
ERR_remove_state(0);
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();

216
crypto/constant_time_locl.h Normal file
View File

@@ -0,0 +1,216 @@
/* crypto/constant_time_locl.h */
/*
* Utilities for constant-time cryptography.
*
* Author: Emilia Kasper (emilia@openssl.org)
* Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
* (Google).
* ====================================================================
* Copyright (c) 2014 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_CONSTANT_TIME_LOCL_H
#define HEADER_CONSTANT_TIME_LOCL_H
#include "e_os.h" /* For 'inline' */
#ifdef __cplusplus
extern "C" {
#endif
/*
* The boolean methods return a bitmask of all ones (0xff...f) for true
* and 0 for false. This is useful for choosing a value based on the result
* of a conditional in constant time. For example,
*
* if (a < b) {
* c = a;
* } else {
* c = b;
* }
*
* can be written as
*
* unsigned int lt = constant_time_lt(a, b);
* c = constant_time_select(lt, a, b);
*/
/*
* Returns the given value with the MSB copied to all the other
* bits. Uses the fact that arithmetic shift shifts-in the sign bit.
* However, this is not ensured by the C standard so you may need to
* replace this with something else on odd CPUs.
*/
static inline unsigned int constant_time_msb(unsigned int a);
/*
* Returns 0xff..f if a < b and 0 otherwise.
*/
static inline unsigned int constant_time_lt(unsigned int a, unsigned int b);
/* Convenience method for getting an 8-bit mask. */
static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b);
/*
* Returns 0xff..f if a >= b and 0 otherwise.
*/
static inline unsigned int constant_time_ge(unsigned int a, unsigned int b);
/* Convenience method for getting an 8-bit mask. */
static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b);
/*
* Returns 0xff..f if a == 0 and 0 otherwise.
*/
static inline unsigned int constant_time_is_zero(unsigned int a);
/* Convenience method for getting an 8-bit mask. */
static inline unsigned char constant_time_is_zero_8(unsigned int a);
/*
* Returns 0xff..f if a == b and 0 otherwise.
*/
static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
/* Convenience method for getting an 8-bit mask. */
static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b);
/* Signed integers. */
static inline unsigned int constant_time_eq_int(int a, int b);
/* Convenience method for getting an 8-bit mask. */
static inline unsigned char constant_time_eq_int_8(int a, int b);
/*
* Returns (mask & a) | (~mask & b).
*
* When |mask| is all 1s or all 0s (as returned by the methods above),
* the select methods return either |a| (if |mask| is nonzero) or |b|
* (if |mask| is zero).
*/
static inline unsigned int constant_time_select(unsigned int mask,
unsigned int a, unsigned int b);
/* Convenience method for unsigned chars. */
static inline unsigned char constant_time_select_8(unsigned char mask,
unsigned char a, unsigned char b);
/* Convenience method for signed integers. */
static inline int constant_time_select_int(unsigned int mask, int a, int b);
static inline unsigned int constant_time_msb(unsigned int a)
{
return (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 */

330
crypto/constant_time_test.c Normal file
View File

@@ -0,0 +1,330 @@
/* crypto/constant_time_test.c */
/*
* Utilities for constant-time cryptography.
*
* Author: Emilia Kasper (emilia@openssl.org)
* Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
* (Google).
* ====================================================================
* Copyright (c) 2014 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#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;
}
}

View File

@@ -64,7 +64,6 @@
#include <string.h>
#include "ec_lcl.h"
#include <openssl/err.h>
#include <string.h>
EC_KEY *EC_KEY_new(void)
{

View File

@@ -1676,8 +1676,8 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT
{
for (i = 0; i < num; i++)
{
if (prod_Z[i] != NULL)
BN_clear_free(prod_Z[i]);
if (prod_Z[i] == NULL) break;
BN_clear_free(prod_Z[i]);
}
OPENSSL_free(prod_Z);
}

View File

@@ -69,6 +69,7 @@ R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
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

View File

@@ -385,7 +385,8 @@ evp_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
evp_enc.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
evp_enc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
evp_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
evp_enc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_enc.c evp_locl.h
evp_enc.o: ../../include/openssl/x509_vfy.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

View File

@@ -64,6 +64,7 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "../constant_time_locl.h"
#include "evp_locl.h"
#ifdef OPENSSL_FIPS
@@ -301,11 +302,11 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
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)
@@ -324,28 +325,34 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
return(0);
}
OPENSSL_assert(b <= sizeof ctx->final);
n=ctx->final[b-1];
if (n == 0 || n > (int)b)
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)
{
EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
return(0);
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);
}
for (i=0; i<n; 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;
/*
* 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)

View File

@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
#define OPENSSL_VERSION_NUMBER 0x009081bfL
#define OPENSSL_VERSION_NUMBER 0x009081cfL
#ifdef OPENSSL_FIPS
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zb-fips 6 Aug 2014"
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zc-fips 15 Oct 2014"
#else
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zb 6 Aug 2014"
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8zc 15 Oct 2014"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT

View File

@@ -189,7 +189,7 @@ rsa_oaep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
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
@@ -198,7 +198,8 @@ rsa_pk1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.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_pss.o: ../../e_os.h ../../include/openssl/asn1.h
rsa_pss.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
rsa_pss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h

View File

@@ -479,6 +479,7 @@ void ERR_load_RSA_strings(void);
#define RSA_R_OAEP_DECODING_ERROR 121
#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 142
#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

View File

@@ -151,6 +151,7 @@ static ERR_STRING_DATA RSA_str_reasons[]=
{ERR_REASON(RSA_R_OAEP_DECODING_ERROR) ,"oaep decoding error"},
{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
{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"},

View File

@@ -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,89 +93,114 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
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];
unsigned char *padded_from;
int bad = 0;
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];
if (--num < 2 * SHA_DIGEST_LENGTH + 1)
/* 'num' is the length of the modulus, i.e. does not depend on the
* particular ciphertext. */
if (tlen <= 0 || flen <= 0)
return -1;
/*
* |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;
lzero = num - flen;
if (lzero < 0)
{
/* 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;
flen = num; /* don't overflow the memcpy to padded_from */
}
dblen = num - SHA_DIGEST_LENGTH;
db = OPENSSL_malloc(dblen + num);
if (db == NULL)
dblen = num - SHA_DIGEST_LENGTH - 1;
db = OPENSSL_malloc(dblen);
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;
}
/* Always do this zero-padding copy (even when lzero == 0)
* to avoid leaking timing info about the value of lzero. */
padded_from = db + dblen;
memset(padded_from, 0, lzero);
memcpy(padded_from + lzero, from, flen);
/*
* 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);
maskeddb = padded_from + SHA_DIGEST_LENGTH;
/*
* 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;
MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
for (i = 0; i < SHA_DIGEST_LENGTH; i++)
seed[i] ^= padded_from[i];
seed[i] ^= maskedseed[i];
MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
for (i = 0; i < dblen; i++)
db[i] ^= maskeddb[i];
EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
good &= constant_time_is_zero(CRYPTO_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 (i == dblen || db[i] != 0x01)
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
* which kind of decoding error happened */
/* 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);
cleanup:
if (db != NULL) OPENSSL_free(db);
return -1;
if (em != NULL) OPENSSL_free(em);
return mlen;
}
int PKCS1_MGF1(unsigned char *mask, long len,

View File

@@ -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(unsigned char *to, int tlen,
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;
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;
p=from;
if ((num != (flen+1)) || (*(p++) != 02))
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,RSA_R_BLOCK_TYPE_IS_NOT_02);
return(-1);
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
return -1;
}
#ifdef PKCS1_CHECK
return(num-11);
#endif
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);
/* scan over padding data */
j=flen-1; /* one for type. */
for (i=0; i<j; i++)
if (*(p++) == 0) break;
good = constant_time_is_zero(em[0]);
good &= constant_time_eq(em[1], 2);
if (i == j)
found_zero_byte = 0;
for (i = 2; i < num; i++)
{
RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING);
return(-1);
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;
}
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);
/*
* 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);
return(j);
/* 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;
}

View File

@@ -155,6 +155,25 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
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 RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
{
@@ -215,7 +234,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
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_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
goto err;

View File

@@ -50,6 +50,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>]
@@ -198,10 +199,13 @@ these options disable the use of certain SSL or TLS protocols. By default
the initial handshake uses a method which should be compatible with all
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>

View File

@@ -61,6 +61,12 @@ deal with read/write operations returning without success report. The
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

12
e_os.h
View File

@@ -360,7 +360,16 @@ static unsigned int _strlen31(const char *str)
# define DEFAULT_HOME "C:"
# endif
#else /* The non-microsoft world world */
/*
* Visual Studio: inline is available in C++ only, however
* __inline is available for C, see
* http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
*/
#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline)
# define inline __inline
#endif
#else /* The non-microsoft world */
# ifdef OPENSSL_SYS_VMS
# define VMS 1
@@ -707,4 +716,3 @@ struct servent *getservbyname(const char *name, const char *proto);
#endif
#endif

View File

@@ -6,7 +6,7 @@ Release: 1
Summary: Secure Sockets Layer and cryptography libraries and tools
Name: openssl
Version: 0.9.8zb
Version: 0.9.8zc
Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
License: OpenSSL
Group: System Environment/Libraries

View File

@@ -545,27 +545,28 @@ s3_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.h
s3_cbc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_cbc.o: ../include/openssl/bn.h ../include/openssl/buffer.h
s3_cbc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
s3_cbc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
s3_cbc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
s3_cbc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
s3_cbc.o: ../include/openssl/err.h ../include/openssl/evp.h
s3_cbc.o: ../include/openssl/fips.h ../include/openssl/hmac.h
s3_cbc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
s3_cbc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
s3_cbc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
s3_cbc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
s3_cbc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
s3_cbc.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
s3_cbc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
s3_cbc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
s3_cbc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
s3_cbc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
s3_cbc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
s3_cbc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
s3_cbc.o: ../include/openssl/x509_vfy.h s3_cbc.c ssl_locl.h
s3_cbc.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
s3_cbc.o: ../include/openssl/bio.h ../include/openssl/bn.h
s3_cbc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s3_cbc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
s3_cbc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
s3_cbc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
s3_cbc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
s3_cbc.o: ../include/openssl/evp.h ../include/openssl/fips.h
s3_cbc.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
s3_cbc.o: ../include/openssl/lhash.h ../include/openssl/md5.h
s3_cbc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
s3_cbc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
s3_cbc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_cbc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s3_cbc.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
s3_cbc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
s3_cbc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
s3_cbc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
s3_cbc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
s3_cbc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
s3_cbc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_cbc.c
s3_cbc.o: ssl_locl.h
s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -674,29 +675,29 @@ s3_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
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: ../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
s3_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
s3_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
s3_srvr.o: ../include/openssl/evp.h ../include/openssl/fips.h
s3_srvr.o: ../include/openssl/hmac.h ../include/openssl/krb5_asn.h
s3_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
s3_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
s3_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
s3_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
s3_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
s3_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
s3_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
s3_srvr.o: s3_srvr.c ssl_locl.h
s3_srvr.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
s3_srvr.o: ../include/openssl/bio.h ../include/openssl/bn.h
s3_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
s3_srvr.o: ../include/openssl/crypto.h ../include/openssl/dh.h
s3_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
s3_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
s3_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
s3_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
s3_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.h
s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
s3_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
s3_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
s3_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
ssl_algs.o: ../include/openssl/bn.h ../include/openssl/buffer.h
ssl_algs.o: ../include/openssl/comp.h ../include/openssl/crypto.h

View File

@@ -305,6 +305,16 @@ long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
case DTLS_CTRL_LISTEN:
ret = dtls1_listen(s, parg);
break;
case SSL_CTRL_CHECK_PROTO_VERSION:
/* For library-internal use; checks that the current protocol
* is the highest enabled version (according to s->ctx->method,
* as version negotiation may have changed s->method). */
#if DTLS_MAX_VERSION != DTLS1_VERSION
# error Code needs update for DTLS_method() support beyond DTLS1_VERSION.
#endif
/* Just one protocol version is supported so far;
* fail closed if the version is not as expected. */
return s->version == DTLS_MAX_VERSION;
default:
ret = ssl3_ctrl(s, cmd, larg, parg);

View File

@@ -80,6 +80,8 @@ extern "C" {
#endif
#define DTLS1_VERSION 0xFEFF
#define DTLS_MAX_VERSION DTLS1_VERSION
#define DTLS1_BAD_VER 0x0100
#if 0
@@ -262,4 +264,3 @@ typedef struct dtls1_record_data_st
}
#endif
#endif

View File

@@ -72,9 +72,11 @@ static SSL_METHOD *ssl23_get_client_method(int ver)
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);
@@ -533,6 +535,7 @@ 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))
{
@@ -547,7 +550,9 @@ static int ssl23_get_server_hello(SSL *s)
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;
@@ -559,6 +564,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 */

View File

@@ -124,9 +124,11 @@ static SSL_METHOD *ssl23_get_server_method(int ver)
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);
@@ -398,6 +400,9 @@ int ssl23_get_client_hello(SSL *s)
}
#endif
/* 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
@@ -554,6 +559,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;
@@ -577,11 +588,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

View File

@@ -314,6 +314,8 @@ long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg)
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;
}
@@ -362,7 +364,7 @@ int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
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;

View File

@@ -53,6 +53,7 @@
*
*/
#include "../crypto/constant_time_locl.h"
#include "ssl_locl.h"
#include <openssl/md5.h>
@@ -67,37 +68,6 @@
* supported by TLS.) */
#define MAX_HASH_BLOCK_SIZE 128
/* Some utility functions are needed:
*
* These macros return the given value with the MSB copied to all the other
* bits. They use 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
* them with something else on odd CPUs. */
#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
static unsigned constant_time_lt(unsigned a, unsigned b)
{
a -= b;
return DUPLICATE_MSB_TO_ALL(a);
}
/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
static unsigned constant_time_ge(unsigned a, unsigned b)
{
a -= b;
return DUPLICATE_MSB_TO_ALL(~a);
}
/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
static unsigned char constant_time_eq_8(unsigned a, unsigned b)
{
unsigned c = a ^ b;
c--;
return DUPLICATE_MSB_TO_ALL_8(c);
}
/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
* record in |rec| by updating |rec->length| in constant time.
*
@@ -126,8 +96,8 @@ int ssl3_cbc_remove_padding(const SSL* s,
padding_length = good & (padding_length+1);
rec->length -= padding_length;
rec->type |= padding_length<<8; /* kludge: pass padding length */
return (int)((good & 1) | (~good & -1));
}
return constant_time_select_int(good, 1, -1);
}
/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
* record in |rec| in constant time and returns 1 if the padding is valid and
@@ -201,7 +171,7 @@ int tls1_cbc_remove_padding(const SSL* s,
for (i = 0; i < to_check; i++)
{
unsigned char mask = constant_time_ge(padding_length, i);
unsigned char mask = constant_time_ge_8(padding_length, i);
unsigned char b = rec->data[rec->length-1-i];
/* The final |padding_length+1| bytes should all have the value
* |padding_length|. Therefore the XOR should be zero. */
@@ -209,20 +179,14 @@ int tls1_cbc_remove_padding(const SSL* s,
}
/* If any of the final |padding_length+1| bytes had the wrong value,
* one or more of the lower eight bits of |good| will be cleared. We
* AND the bottom 8 bits together and duplicate the result to all the
* bits. */
good &= good >> 4;
good &= good >> 2;
good &= good >> 1;
good <<= sizeof(good)*8-1;
good = DUPLICATE_MSB_TO_ALL(good);
* one or more of the lower eight bits of |good| will be cleared.
*/
good = constant_time_eq(0xff, good & 0xff);
padding_length = good & (padding_length+1);
rec->length -= padding_length;
rec->type |= padding_length<<8; /* kludge: pass padding length */
return (int)((good & 1) | (~good & -1));
return constant_time_select_int(good, 1, -1);
}
/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
@@ -289,8 +253,8 @@ void ssl3_cbc_copy_mac(unsigned char* out,
memset(rotated_mac, 0, md_size);
for (i = scan_start, j = 0; i < orig_len; i++)
{
unsigned char mac_started = constant_time_ge(i, mac_start);
unsigned char mac_ended = constant_time_ge(i, mac_end);
unsigned char mac_started = constant_time_ge_8(i, mac_start);
unsigned char mac_ended = constant_time_ge_8(i, mac_end);
unsigned char b = rec->data[i];
rotated_mac[j++] |= b & mac_started & ~mac_ended;
j &= constant_time_lt(j,md_size);
@@ -676,12 +640,12 @@ void ssl3_cbc_digest_record(
b = data[k-header_length];
k++;
is_past_c = is_block_a & constant_time_ge(j, c);
is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
is_past_c = is_block_a & constant_time_ge_8(j, c);
is_past_cp1 = is_block_a & constant_time_ge_8(j, c+1);
/* If this is the block containing the end of the
* application data, and we are at the offset for the
* 0x80 value, then overwrite b with 0x80. */
b = (b&~is_past_c) | (0x80&is_past_c);
b = constant_time_select_8(is_past_c, 0x80, b);
/* If this the the block containing the end of the
* application data and we're past the 0x80 value then
* just write zero. */
@@ -697,7 +661,8 @@ void ssl3_cbc_digest_record(
if (j >= md_block_size - md_length_size)
{
/* If this is index_b, write a length byte. */
b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
b = constant_time_select_8(
is_block_b, length_bytes[j-(md_block_size-md_length_size)], b);
}
block[j] = b;
}

View File

@@ -1095,8 +1095,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;
int al,j,ok;
long i,param_len,n,alg;
EVP_PKEY *pkey=NULL;
#ifndef OPENSSL_NO_RSA
RSA *rsa=NULL;
@@ -1160,10 +1160,12 @@ 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=s->s3->tmp.new_cipher->algorithms;
EVP_MD_CTX_init(&md_ctx);
al=SSL_AD_DECODE_ERROR;
#ifndef OPENSSL_NO_RSA
if (alg & SSL_kRSA)
{
@@ -1172,14 +1174,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);
@@ -1187,14 +1198,23 @@ int ssl3_get_key_exchange(SSL *s)
}
p+=i;
n2s(p,i);
param_len+=i+2;
if (param_len > n)
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);
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);
@@ -1226,14 +1246,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);
@@ -1241,14 +1270,23 @@ int ssl3_get_key_exchange(SSL *s)
}
p+=i;
n2s(p,i);
param_len+=i+2;
if (param_len > n)
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);
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);
@@ -1256,14 +1294,23 @@ int ssl3_get_key_exchange(SSL *s)
}
p+=i;
n2s(p,i);
param_len+=i+2;
if (param_len > n)
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);
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);
@@ -1315,12 +1362,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 = 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 = curve_id2nid(*(p + 2))) == 0))
{
al=SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
@@ -1362,15 +1416,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;
@@ -1421,10 +1475,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;
}
@@ -1433,6 +1487,7 @@ int ssl3_get_key_exchange(SSL *s)
if (pkey->type == EVP_PKEY_RSA)
{
int num;
unsigned int size;
j=0;
q=md_buf;
@@ -1445,9 +1500,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);
@@ -1518,7 +1573,6 @@ int ssl3_get_key_exchange(SSL *s)
}
if (n != 0)
{
al=SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);
goto f_err;
}

View File

@@ -764,7 +764,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);
}
}

View File

@@ -1986,6 +1986,29 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
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;
}
@@ -2274,6 +2297,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
break;
#endif
default:
return(0);
}

View File

@@ -229,6 +229,12 @@ int ssl3_read_n(SSL *s, int n, int max, int extend)
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.
@@ -249,6 +255,7 @@ static int ssl3_get_record(SSL *s)
short version;
unsigned mac_size, orig_len;
size_t extra;
unsigned empty_record_count = 0;
rr= &(s->s3->rrec);
sess=s->session;
@@ -476,7 +483,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;
}
return(1);

View File

@@ -128,6 +128,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>
@@ -1828,6 +1829,10 @@ int ssl3_get_client_key_exchange(SSL *s)
#ifndef OPENSSL_NO_RSA
if (l & 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)
{
@@ -1876,54 +1881,61 @@ int ssl3_get_client_key_exchange(SSL *s)
n=i;
}
i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
/* 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 */
al = -1;
if (i != SSL_MAX_MASTER_KEY_LENGTH)
/* 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)
{
al=SSL_AD_DECODE_ERROR;
/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
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;
}
if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (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) &&
(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); */
/* Both decryption and version must be good for decrypt_good
* to remain non-zero (0xff). */
decrypt_good &= version_good;
/* 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. */
}
/* Now copy rand_premaster_secret over p using
* decrypt_good_mask. */
for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
{
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,

View File

@@ -563,6 +563,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,
@@ -1209,6 +1213,7 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
#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
@@ -1298,6 +1303,8 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
#define SSL_CTRL_CLEAR_OPTIONS 77
#define SSL_CTRL_CLEAR_MODE 78
#define SSL_CTRL_CHECK_PROTO_VERSION 119
#define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
#define DTLSv1_handle_timeout(ssl) \
@@ -1945,6 +1952,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
@@ -2072,6 +2080,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

View File

@@ -129,9 +129,14 @@
extern "C" {
#endif
/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
/* Signalling cipher suite value from RFC 5746
* (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */
#define SSL3_CK_SCSV 0x030000FF
/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
* (TLS_FALLBACK_SCSV) */
#define SSL3_CK_FALLBACK_SCSV 0x03005600
#define SSL3_CK_RSA_NULL_MD5 0x03000001
#define SSL3_CK_RSA_NULL_SHA 0x03000002
#define SSL3_CK_RSA_RC4_40_MD5 0x03000003

View File

@@ -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"},

View File

@@ -1296,6 +1296,8 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
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++)
{
@@ -1305,24 +1307,36 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
continue;
#endif /* OPENSSL_NO_KRB5 */
j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
j = put_cb(c,p);
p+=j;
}
/* If p == q, no ciphers and caller indicates an error. Otherwise
* add SCSV if not renegotiating.
*/
if (p != q && !s->new_session)
/* If p == q, no ciphers; caller indicates an error.
* Otherwise, add applicable SCSVs. */
if (p != q)
{
static SSL_CIPHER scsv =
if (!s->new_session)
{
0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
};
j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
p+=j;
static SSL_CIPHER scsv =
{
0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
};
j = put_cb(&scsv,p);
p+=j;
#ifdef OPENSSL_RI_DEBUG
fprintf(stderr, "SCSV sent by client\n");
fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
#endif
}
}
if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV)
{
static SSL_CIPHER scsv =
{
0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0,
};
j = put_cb(&scsv,p);
p+=j;
}
}
return(p-q);
}
@@ -1333,11 +1347,12 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
SSL_CIPHER *c;
STACK_OF(SSL_CIPHER) *sk;
int i,n;
if (s->s3)
s->s3->send_connection_binding = 0;
n=ssl_put_cipher_by_char(s,NULL,NULL);
if ((num%n) != 0)
if (n == 0 || (num%n) != 0)
{
SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
return(NULL);
@@ -1352,7 +1367,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
for (i=0; i<num; i+=n)
{
/* Check for SCSV */
/* 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)))
@@ -1372,6 +1387,23 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
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)

View File

@@ -855,6 +855,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);
#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
(DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
@@ -862,4 +863,3 @@ int tls1_alert_code(int code)
default: return(-1);
}
}

View File

@@ -1101,7 +1101,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
HMAC_Final(&hctx, tick_hmac, NULL);
HMAC_CTX_cleanup(&hctx);
if (CRYPTO_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);

View File

@@ -80,17 +80,24 @@ extern "C" {
#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0
#define TLS1_2_VERSION 0x0303
#define TLS1_2_VERSION_MAJOR 0x03
#define TLS1_2_VERSION_MINOR 0x03
#define TLS1_VERSION 0x0301
#define TLS1_1_VERSION 0x0302
#define TLS1_2_VERSION 0x0303
/* TLS 1.1 and 1.2 are not supported by this version of OpenSSL, so
* TLS_MAX_VERSION indicates TLS 1.0 regardless of the above
* definitions. (s23_clnt.c and s23_srvr.c have an OPENSSL_assert()
* check that would catch the error if TLS_MAX_VERSION was too low.)
*/
#define TLS_MAX_VERSION TLS1_VERSION
#define TLS1_VERSION_MAJOR 0x03
#define TLS1_VERSION_MINOR 0x01
#define TLS1_1_VERSION_MAJOR 0x03
#define TLS1_1_VERSION_MINOR 0x02
#define TLS1_VERSION 0x0301
#define TLS1_VERSION_MAJOR 0x03
#define TLS1_VERSION_MINOR 0x01
#define TLS1_2_VERSION_MAJOR 0x03
#define TLS1_2_VERSION_MINOR 0x03
#define TLS1_get_version(s) \
((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
@@ -108,6 +115,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 */
@@ -419,6 +427,3 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
}
#endif
#endif

View File

@@ -72,6 +72,7 @@ FIPS_DSATEST= fips_dsatest
FIPS_DSSVS= fips_dssvs
FIPS_RNGVS= fips_rngvs
FIPS_TEST_SUITE=fips_test_suite
CONSTTIMETEST= constant_time_test
TESTS= alltests
@@ -88,7 +89,8 @@ EXE= $(BNTEST)$(EXE_EXT) $(ECTEST)$(EXE_EXT) $(ECDSATEST)$(EXE_EXT) $(ECDHTEST)
$(FIPS_HMACTEST)$(EXE_EXT) $(FIPS_RSAVTEST)$(EXE_EXT) \
$(FIPS_RSASTEST)$(EXE_EXT) $(FIPS_RSAGTEST)$(EXE_EXT) \
$(FIPS_DSSVS)$(EXE_EXT) $(FIPS_DSATEST)$(EXE_EXT) \
$(FIPS_RNGVS)$(EXE_EXT) $(FIPS_TEST_SUITE)$(EXE_EXT) jpaketest$(EXE_EXT)
$(FIPS_RNGVS)$(EXE_EXT) $(FIPS_TEST_SUITE)$(EXE_EXT) \
jpaketest$(EXE_EXT) $(CONSTTIMETEST)$(EXE_EXT)
# $(METHTEST)$(EXE_EXT)
@@ -105,7 +107,7 @@ OBJ= $(BNTEST).o $(ECTEST).o $(ECDSATEST).o $(ECDHTEST).o $(IDEATEST).o \
$(FIPS_AESTEST).o $(FIPS_HMACTEST).o $(FIPS_RSAVTEST).o \
$(FIPS_RSASTEST).o $(FIPS_RSAGTEST).o \
$(FIPS_DSSVS).o $(FIPS_DSATEST).o $(FIPS_RNGVS).o $(FIPS_TEST_SUITE).o \
jpaketest.o
jpaketest.o $(CONSTTIMETEST).o
SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
$(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \
@@ -119,7 +121,7 @@ SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
$(FIPS_AESTEST).c $(FIPS_HMACTEST).c $(FIPS_RSAVTEST).c \
$(FIPS_RSASTEST).c $(FIPS_RSAGTEST).c \
$(FIPS_DSSVS).c $(FIPS_DSATEST).c $(FIPS_RNGVS).c $(FIPS_TEST_SUITE).c \
jpaketest.c
jpaketest.c $(CONSTTIMETEST).c
EXHEADER=
HEADER= $(EXHEADER)
@@ -161,7 +163,8 @@ alltests: \
test_rand test_bn test_ec test_ecdsa test_ecdh \
test_enc test_x509 test_rsa test_crl test_sid \
test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
test_ss test_ca test_engine test_evp test_ssl test_ige test_jpake
test_ss test_ca test_engine test_evp test_ssl test_ige test_jpake \
test_constant_time
test_evp:
../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
@@ -333,6 +336,10 @@ test_jpake: jpaketest$(EXE_EXT)
@echo "Test JPAKE"
../util/shlib_wrap.sh ./jpaketest
test_constant_time: $(CONSTTIMETEST)$(EXE_EXT)
@echo "Test constant time utilites"
../util/shlib_wrap.sh ./$(CONSTTIMETEST)
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
@@ -527,6 +534,9 @@ $(IGETEST)$(EXE_EXT): $(IGETEST).o $(DLIBCRYPTO)
jpaketest$(EXE_EXT): jpaketest.o $(DLIBCRYPTO)
@target=jpaketest; $(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
@@ -561,6 +571,9 @@ bntest.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
bntest.o: ../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