Import OpenSSL 1.0.1j.
This commit is contained in:
parent
cb6864802e
commit
58ab7656b2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor-crypto/openssl/dist/; revision=273138 svn path=/vendor-crypto/openssl/1.0.1j/; revision=273139; tag=vendor/openssl/1.0.1j
51
CHANGES
51
CHANGES
@ -2,6 +2,57 @@
|
||||
OpenSSL CHANGES
|
||||
_______________
|
||||
|
||||
Changes between 1.0.1i and 1.0.1j [15 Oct 2014]
|
||||
|
||||
*) SRTP Memory Leak.
|
||||
|
||||
A flaw in the DTLS SRTP extension parsing code allows an attacker, who
|
||||
sends a carefully crafted handshake message, to cause OpenSSL to fail
|
||||
to free up to 64k of memory causing a memory leak. This could be
|
||||
exploited in a Denial Of Service attack. This issue affects OpenSSL
|
||||
1.0.1 server implementations for both SSL/TLS and DTLS regardless of
|
||||
whether SRTP is used or configured. Implementations of OpenSSL that
|
||||
have been compiled with OPENSSL_NO_SRTP defined are not affected.
|
||||
|
||||
The fix was developed by the OpenSSL team.
|
||||
(CVE-2014-3513)
|
||||
[OpenSSL team]
|
||||
|
||||
*) 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 1.0.1h and 1.0.1i [6 Aug 2014]
|
||||
|
||||
*) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the
|
||||
|
@ -1767,6 +1767,9 @@ open(OUT,'>crypto/opensslconf.h.new') || die "unable to create crypto/opensslcon
|
||||
print OUT "/* opensslconf.h */\n";
|
||||
print OUT "/* WARNING: Generated automatically from opensslconf.h.in by Configure. */\n\n";
|
||||
|
||||
print OUT "#ifdef __cplusplus\n";
|
||||
print OUT "extern \"C\" {\n";
|
||||
print OUT "#endif\n";
|
||||
print OUT "/* OpenSSL was configured with the following options: */\n";
|
||||
my $openssl_algorithm_defines_trans = $openssl_algorithm_defines;
|
||||
$openssl_experimental_defines =~ s/^\s*#\s*define\s+OPENSSL_NO_(.*)/#ifndef OPENSSL_EXPERIMENTAL_$1\n# ifndef OPENSSL_NO_$1\n# define OPENSSL_NO_$1\n# endif\n#endif/mg;
|
||||
@ -1871,6 +1874,9 @@ while (<IN>)
|
||||
{ print OUT $_; }
|
||||
}
|
||||
close(IN);
|
||||
print OUT "#ifdef __cplusplus\n";
|
||||
print OUT "}\n";
|
||||
print OUT "#endif\n";
|
||||
close(OUT);
|
||||
rename("crypto/opensslconf.h","crypto/opensslconf.h.bak") || die "unable to rename crypto/opensslconf.h\n" if -e "crypto/opensslconf.h";
|
||||
rename("crypto/opensslconf.h.new","crypto/opensslconf.h") || die "unable to rename crypto/opensslconf.h.new\n";
|
||||
|
@ -11,8 +11,8 @@ First, read http://wiki.freebsd.org/SubversionPrimer/VendorImports
|
||||
# Xlist
|
||||
setenv XLIST /FreeBSD/work/openssl/svn-FREEBSD-files/FREEBSD-Xlist
|
||||
setenv FSVN "svn+ssh://svn.freebsd.org/base"
|
||||
setenv OSSLVER 1.0.1i
|
||||
# OSSLTAG format: v1_0_1i
|
||||
setenv OSSLVER 1.0.1j
|
||||
# OSSLTAG format: v1_0_1j
|
||||
|
||||
###setenv OSSLTAG v`echo ${OSSLVER} | tr . _`
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -4,7 +4,7 @@
|
||||
## Makefile for OpenSSL
|
||||
##
|
||||
|
||||
VERSION=1.0.1i
|
||||
VERSION=1.0.1j
|
||||
MAJOR=1
|
||||
MINOR=0.1
|
||||
SHLIB_VERSION_NUMBER=1.0.0
|
||||
|
7
NEWS
7
NEWS
@ -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 1.0.1i and OpenSSL 1.0.1j [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 1.0.1h and OpenSSL 1.0.1i [6 Aug 2014]
|
||||
|
||||
o Fix for CVE-2014-3512
|
||||
|
2
README
2
README
@ -1,5 +1,5 @@
|
||||
|
||||
OpenSSL 1.0.1i 6 Aug 2014
|
||||
OpenSSL 1.0.1j 15 Oct 2014
|
||||
|
||||
Copyright (c) 1998-2011 The OpenSSL Project
|
||||
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
|
||||
|
@ -337,6 +337,7 @@ static void sc_usage(void)
|
||||
BIO_printf(bio_err," -tls1_1 - just use TLSv1.1\n");
|
||||
BIO_printf(bio_err," -tls1 - just use TLSv1\n");
|
||||
BIO_printf(bio_err," -dtls1 - just use DTLSv1\n");
|
||||
BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
|
||||
BIO_printf(bio_err," -mtu - set the link layer MTU\n");
|
||||
BIO_printf(bio_err," -no_tls1_2/-no_tls1_1/-no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
|
||||
BIO_printf(bio_err," -bugs - Switch on all SSL implementation bug workarounds\n");
|
||||
@ -617,6 +618,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
|
||||
@ -823,6 +825,10 @@ int MAIN(int argc, char **argv)
|
||||
meth=DTLSv1_client_method();
|
||||
socket_type=SOCK_DGRAM;
|
||||
}
|
||||
else if (strcmp(*argv,"-fallback_scsv") == 0)
|
||||
{
|
||||
fallback_scsv = 1;
|
||||
}
|
||||
else if (strcmp(*argv,"-timeout") == 0)
|
||||
enable_timeouts=1;
|
||||
else if (strcmp(*argv,"-mtu") == 0)
|
||||
@ -1235,6 +1241,10 @@ int MAIN(int argc, char **argv)
|
||||
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)
|
||||
{
|
||||
|
@ -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)
|
||||
@ -43,7 +44,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)
|
||||
|
||||
|
@ -525,6 +525,16 @@ $code.=<<___;
|
||||
.type aesni_ecb_encrypt,\@function,5
|
||||
.align 16
|
||||
aesni_ecb_encrypt:
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0x58(%rsp),%rsp
|
||||
movaps %xmm6,(%rsp)
|
||||
movaps %xmm7,0x10(%rsp)
|
||||
movaps %xmm8,0x20(%rsp)
|
||||
movaps %xmm9,0x30(%rsp)
|
||||
.Lecb_enc_body:
|
||||
___
|
||||
$code.=<<___;
|
||||
and \$-16,$len
|
||||
jz .Lecb_ret
|
||||
|
||||
@ -805,6 +815,16 @@ $code.=<<___;
|
||||
movups $inout5,0x50($out)
|
||||
|
||||
.Lecb_ret:
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps (%rsp),%xmm6
|
||||
movaps 0x10(%rsp),%xmm7
|
||||
movaps 0x20(%rsp),%xmm8
|
||||
movaps 0x30(%rsp),%xmm9
|
||||
lea 0x58(%rsp),%rsp
|
||||
.Lecb_enc_ret:
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
|
||||
___
|
||||
@ -2730,28 +2750,9 @@ $code.=<<___;
|
||||
.extern __imp_RtlVirtualUnwind
|
||||
___
|
||||
$code.=<<___ if ($PREFIX eq "aesni");
|
||||
.type ecb_se_handler,\@abi-omnipotent
|
||||
.type ecb_ccm64_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
ecb_se_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
push %rbp
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
pushfq
|
||||
sub \$64,%rsp
|
||||
|
||||
mov 152($context),%rax # pull context->Rsp
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size ecb_se_handler,.-ecb_se_handler
|
||||
|
||||
.type ccm64_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
ccm64_se_handler:
|
||||
ecb_ccm64_se_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
@ -2788,7 +2789,7 @@ ccm64_se_handler:
|
||||
lea 0x58(%rax),%rax # adjust stack pointer
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size ccm64_se_handler,.-ccm64_se_handler
|
||||
.size ecb_ccm64_se_handler,.-ecb_ccm64_se_handler
|
||||
|
||||
.type ctr32_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
@ -2993,14 +2994,15 @@ ___
|
||||
$code.=<<___ if ($PREFIX eq "aesni");
|
||||
.LSEH_info_ecb:
|
||||
.byte 9,0,0,0
|
||||
.rva ecb_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lecb_enc_body,.Lecb_enc_ret # HandlerData[]
|
||||
.LSEH_info_ccm64_enc:
|
||||
.byte 9,0,0,0
|
||||
.rva ccm64_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lccm64_enc_body,.Lccm64_enc_ret # HandlerData[]
|
||||
.LSEH_info_ccm64_dec:
|
||||
.byte 9,0,0,0
|
||||
.rva ccm64_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lccm64_dec_body,.Lccm64_dec_ret # HandlerData[]
|
||||
.LSEH_info_ctr32:
|
||||
.byte 9,0,0,0
|
||||
|
@ -568,6 +568,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
|
||||
mbflag |= MBSTRING_FLAG;
|
||||
stmp.data = NULL;
|
||||
stmp.length = 0;
|
||||
stmp.flags = 0;
|
||||
ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
|
||||
if(ret < 0) return ret;
|
||||
*out = stmp.data;
|
||||
|
@ -189,7 +189,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"
|
||||
".p2align 4 \n"
|
||||
"1: movq (%4,%2,8),%0 \n"
|
||||
@ -200,7 +200,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;
|
||||
@ -212,7 +212,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"
|
||||
".p2align 4 \n"
|
||||
"1: movq (%4,%2,8),%0 \n"
|
||||
@ -223,7 +223,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;
|
||||
|
@ -874,6 +874,13 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
|
||||
bits = BN_num_bits(p);
|
||||
if (bits == 0)
|
||||
{
|
||||
/* x**0 mod 1 is still zero. */
|
||||
if (BN_is_one(m))
|
||||
{
|
||||
ret = 1;
|
||||
BN_zero(rr);
|
||||
}
|
||||
else
|
||||
ret = BN_one(rr);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1088,9 +1088,9 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
||||
/* ... and right shift */
|
||||
for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++)
|
||||
{
|
||||
tmp = val>>BN_NIST_521_RSHIFT;
|
||||
val = t_d[i+1];
|
||||
t_d[i] = (tmp | val<<BN_NIST_521_LSHIFT) & BN_MASK2;
|
||||
t_d[i] = ( val>>BN_NIST_521_RSHIFT |
|
||||
(tmp=t_d[i+1])<<BN_NIST_521_LSHIFT ) & BN_MASK2;
|
||||
val=tmp;
|
||||
}
|
||||
t_d[i] = val>>BN_NIST_521_RSHIFT;
|
||||
/* lower 521 bits */
|
||||
|
@ -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_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();
|
||||
|
216
crypto/constant_time_locl.h
Normal file
216
crypto/constant_time_locl.h
Normal 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
330
crypto/constant_time_test.c
Normal 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;
|
||||
}
|
||||
}
|
@ -307,6 +307,12 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
|
||||
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)
|
||||
@ -701,4 +707,3 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
|
||||
old_dsa_priv_encode
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,10 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Avoid name clashes with other applications */
|
||||
#define os_toascii _openssl_os_toascii
|
||||
#define os_toebcdic _openssl_os_toebcdic
|
||||
@ -16,4 +20,7 @@ extern const unsigned char os_toebcdic[256];
|
||||
void *ebcdic2ascii(void *dest, const void *srce, size_t count);
|
||||
void *ascii2ebcdic(void *dest, const void *srce, size_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -629,7 +629,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN
|
||||
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
|
||||
int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *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)
|
||||
|
@ -80,9 +80,6 @@
|
||||
|
||||
const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
return fips_ec_gf2m_simple_method();
|
||||
#else
|
||||
static const EC_METHOD ret = {
|
||||
EC_FLAGS_DEFAULT_OCT,
|
||||
NID_X9_62_characteristic_two_field,
|
||||
@ -125,8 +122,12 @@ const EC_METHOD *EC_GF2m_simple_method(void)
|
||||
0 /* field_decode */,
|
||||
0 /* field_set_to_one */ };
|
||||
|
||||
return &ret;
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return fips_ec_gf2m_simple_method();
|
||||
#endif
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -453,15 +453,17 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
|
||||
if (ktype > 0)
|
||||
{
|
||||
public_key = EC_KEY_get0_public_key(x);
|
||||
if (public_key != NULL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (pub_key)
|
||||
buf_len = (size_t)BN_num_bytes(pub_key);
|
||||
}
|
||||
}
|
||||
|
||||
if (ktype == 2)
|
||||
{
|
||||
|
@ -1183,11 +1183,6 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (priv_key->publicKey)
|
||||
{
|
||||
const unsigned char *pub_oct;
|
||||
size_t pub_oct_len;
|
||||
|
||||
if (ret->pub_key)
|
||||
EC_POINT_clear_free(ret->pub_key);
|
||||
ret->pub_key = EC_POINT_new(ret->group);
|
||||
@ -1196,17 +1191,39 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
|
||||
ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (priv_key->publicKey)
|
||||
{
|
||||
const unsigned char *pub_oct;
|
||||
int pub_oct_len;
|
||||
|
||||
pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
|
||||
pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
|
||||
/* save the point conversion form */
|
||||
/* The first byte - point conversion form - must be present. */
|
||||
if (pub_oct_len <= 0)
|
||||
{
|
||||
ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
/* 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;
|
||||
err:
|
||||
@ -1230,7 +1247,8 @@ int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
|
||||
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);
|
||||
|
@ -72,9 +72,6 @@
|
||||
|
||||
const EC_METHOD *EC_GFp_mont_method(void)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
return fips_ec_gfp_mont_method();
|
||||
#else
|
||||
static const EC_METHOD ret = {
|
||||
EC_FLAGS_DEFAULT_OCT,
|
||||
NID_X9_62_prime_field,
|
||||
@ -114,8 +111,12 @@ const EC_METHOD *EC_GFp_mont_method(void)
|
||||
ec_GFp_mont_field_decode,
|
||||
ec_GFp_mont_field_set_to_one };
|
||||
|
||||
return &ret;
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return fips_ec_gfp_mont_method();
|
||||
#endif
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,9 +73,6 @@
|
||||
|
||||
const EC_METHOD *EC_GFp_nist_method(void)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
return fips_ec_gfp_nist_method();
|
||||
#else
|
||||
static const EC_METHOD ret = {
|
||||
EC_FLAGS_DEFAULT_OCT,
|
||||
NID_X9_62_prime_field,
|
||||
@ -115,8 +112,12 @@ const EC_METHOD *EC_GFp_nist_method(void)
|
||||
0 /* field_decode */,
|
||||
0 /* field_set_to_one */ };
|
||||
|
||||
return &ret;
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return fips_ec_gfp_nist_method();
|
||||
#endif
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
|
@ -73,9 +73,6 @@
|
||||
|
||||
const EC_METHOD *EC_GFp_simple_method(void)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
return fips_ec_gfp_simple_method();
|
||||
#else
|
||||
static const EC_METHOD ret = {
|
||||
EC_FLAGS_DEFAULT_OCT,
|
||||
NID_X9_62_prime_field,
|
||||
@ -115,8 +112,12 @@ const EC_METHOD *EC_GFp_simple_method(void)
|
||||
0 /* field_decode */,
|
||||
0 /* field_set_to_one */ };
|
||||
|
||||
return &ret;
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode())
|
||||
return fips_ec_gfp_simple_method();
|
||||
#endif
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
@ -1317,7 +1318,7 @@ 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)
|
||||
if (prod_Z[i] == NULL) break;
|
||||
BN_clear_free(prod_Z[i]);
|
||||
}
|
||||
OPENSSL_free(prod_Z);
|
||||
|
@ -251,14 +251,15 @@ static void group_order_tests(EC_GROUP *group)
|
||||
if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
|
||||
|
||||
/* Exercise EC_POINTs_mul, including corner cases. */
|
||||
if (EC_POINT_is_at_infinity(group, P)) ABORT;
|
||||
scalars[0] = n1; points[0] = Q; /* => infinity */
|
||||
scalars[1] = n2; points[1] = P; /* => -P */
|
||||
scalars[2] = n1; points[2] = Q; /* => infinity */
|
||||
scalars[3] = n2; points[3] = Q; /* => infinity */
|
||||
scalars[4] = n1; points[4] = P; /* => P */
|
||||
scalars[5] = n2; points[5] = Q; /* => infinity */
|
||||
if (!EC_POINTs_mul(group, Q, NULL, 5, points, scalars, ctx)) ABORT;
|
||||
if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
|
||||
if (!EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx)) ABORT;
|
||||
if (!EC_POINT_is_at_infinity(group, P)) ABORT;
|
||||
}
|
||||
fprintf(stdout, "ok\n");
|
||||
|
||||
|
@ -383,7 +383,7 @@ evp_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
|
||||
evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
|
||||
evp_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
|
||||
evp_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
|
||||
evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
|
||||
evp_enc.o: ../constant_time_locl.h ../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
|
||||
|
@ -166,7 +166,7 @@ extern unsigned int OPENSSL_ia32cap_P[2];
|
||||
#define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
|
||||
#endif
|
||||
#ifdef BSAES_ASM
|
||||
#define BSAES_CAPABLE VPAES_CAPABLE
|
||||
#define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
|
||||
#endif
|
||||
/*
|
||||
* AES-NI section
|
||||
|
@ -67,6 +67,7 @@
|
||||
#ifdef OPENSSL_FIPS
|
||||
#include <openssl/fips.h>
|
||||
#endif
|
||||
#include "constant_time_locl.h"
|
||||
#include "evp_locl.h"
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
@ -500,21 +501,21 @@ 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;
|
||||
|
||||
if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER)
|
||||
{
|
||||
i = M_do_cipher(ctx, out, NULL, 0);
|
||||
if (i < 0)
|
||||
int ret = M_do_cipher(ctx, out, NULL, 0);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
else
|
||||
*outl = i;
|
||||
*outl = ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
b=ctx->cipher->block_size;
|
||||
b=(unsigned int)(ctx->cipher->block_size);
|
||||
if (ctx->flags & EVP_CIPH_NO_PADDING)
|
||||
{
|
||||
if(ctx->buf_len)
|
||||
@ -533,28 +534,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)
|
||||
@ -678,4 +685,3 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
|
||||
return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,7 @@ sub round4_step
|
||||
EOF
|
||||
}
|
||||
|
||||
no warnings qw(uninitialized);
|
||||
my $flavour = shift;
|
||||
my $output = shift;
|
||||
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
|
||||
@ -119,7 +120,6 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
no warnings qw(uninitialized);
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef void (*block128_f)(const unsigned char in[16],
|
||||
unsigned char out[16],
|
||||
const void *key);
|
||||
@ -133,3 +136,6 @@ typedef struct xts128_context XTS128_CONTEXT;
|
||||
|
||||
int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16],
|
||||
const unsigned char *inp, unsigned char *out, size_t len, int enc);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -436,9 +436,12 @@ static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm
|
||||
if(!(flags & OCSP_NOINTERN))
|
||||
{
|
||||
signer = X509_find_by_subject(req->optionalSignature->certs, nm);
|
||||
if (signer)
|
||||
{
|
||||
*psigner = signer;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
signer = X509_find_by_subject(certs, nm);
|
||||
if (signer)
|
||||
|
@ -1,6 +1,9 @@
|
||||
/* opensslconf.h */
|
||||
/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* OpenSSL was configured with the following options: */
|
||||
#ifndef OPENSSL_DOING_MAKEDEPEND
|
||||
|
||||
@ -233,3 +236,6 @@ YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
|
||||
|
||||
#endif /* DES_DEFAULT_OPTIONS */
|
||||
#endif /* HEADER_DES_LOCL_H */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,6 +1,10 @@
|
||||
#ifndef HEADER_OPENSSLV_H
|
||||
#define HEADER_OPENSSLV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Numeric release version identifier:
|
||||
* MNNFFPPS: major minor fix patch status
|
||||
* The status nibble has one of the values 0 for development, 1 to e for betas
|
||||
@ -25,11 +29,11 @@
|
||||
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
|
||||
* major minor fix final patch/beta)
|
||||
*/
|
||||
#define OPENSSL_VERSION_NUMBER 0x1000109fL
|
||||
#define OPENSSL_VERSION_NUMBER 0x100010afL
|
||||
#ifdef OPENSSL_FIPS
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1i-fips 6 Aug 2014"
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j-fips 15 Oct 2014"
|
||||
#else
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1i 6 Aug 2014"
|
||||
#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1j 15 Oct 2014"
|
||||
#endif
|
||||
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
|
||||
|
||||
@ -86,4 +90,7 @@
|
||||
#define SHLIB_VERSION_NUMBER "1.0.0"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HEADER_OPENSSLV_H */
|
||||
|
@ -55,6 +55,10 @@
|
||||
#ifndef HEADER_OPENSSL_TYPES_H
|
||||
#define HEADER_OPENSSL_TYPES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <openssl/e_os2.h>
|
||||
|
||||
#ifdef NO_ASN1_TYPEDEFS
|
||||
@ -199,4 +203,7 @@ typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
|
||||
typedef struct ocsp_response_st OCSP_RESPONSE;
|
||||
typedef struct ocsp_responder_id_st OCSP_RESPID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* def HEADER_OPENSSL_TYPES_H */
|
||||
|
@ -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)
|
||||
|
@ -64,6 +64,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef struct _pqueue *pqueue;
|
||||
|
||||
typedef struct _pitem
|
||||
@ -91,4 +94,7 @@ pitem *pqueue_next(piterator *iter);
|
||||
void pqueue_print(pqueue pq);
|
||||
int pqueue_size(pqueue pq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* ! HEADER_PQUEUE_H */
|
||||
|
@ -212,7 +212,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
|
||||
@ -221,7 +221,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_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
|
||||
|
@ -559,6 +559,7 @@ void ERR_load_RSA_strings(void);
|
||||
#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158
|
||||
#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
|
||||
|
@ -175,6 +175,7 @@ static ERR_STRING_DATA RSA_str_reasons[]=
|
||||
{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
|
||||
{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"},
|
||||
|
@ -18,6 +18,7 @@
|
||||
* an equivalent notion.
|
||||
*/
|
||||
|
||||
#include "constant_time_locl.h"
|
||||
|
||||
#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
|
||||
#include <stdio.h>
|
||||
@ -95,92 +96,117 @@ 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;
|
||||
|
||||
if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen))
|
||||
return -1;
|
||||
goto cleanup;
|
||||
for (i = 0; i < SHA_DIGEST_LENGTH; i++)
|
||||
seed[i] ^= padded_from[i];
|
||||
seed[i] ^= maskedseed[i];
|
||||
|
||||
if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH))
|
||||
return -1;
|
||||
goto cleanup;
|
||||
for (i = 0; i < dblen; i++)
|
||||
db[i] ^= maskeddb[i];
|
||||
|
||||
if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
|
||||
return -1;
|
||||
goto cleanup;
|
||||
|
||||
if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
|
||||
goto decoding_err;
|
||||
else
|
||||
{
|
||||
good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH));
|
||||
|
||||
found_one_byte = 0;
|
||||
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 */
|
||||
/* 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;
|
||||
|
||||
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,
|
||||
|
@ -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)
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
@ -151,6 +151,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 int_rsa_verify(int dtype, const unsigned char *m,
|
||||
unsigned int m_len,
|
||||
unsigned char *rm, size_t *prm_len,
|
||||
@ -228,7 +247,7 @@ int int_rsa_verify(int dtype, const unsigned char *m,
|
||||
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;
|
||||
|
@ -57,6 +57,10 @@
|
||||
|
||||
#include <openssl/stack.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CHECKED_PTR_OF
|
||||
#define CHECKED_PTR_OF(type, p) \
|
||||
((void*) (1 ? p : (type*)0))
|
||||
@ -2660,4 +2664,8 @@ DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
|
||||
#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
|
||||
/* End of util/mkstack.pl block, you may now edit :-) */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !defined HEADER_SAFESTACK_H */
|
||||
|
81
doc/apps/c_rehash.pod
Normal file
81
doc/apps/c_rehash.pod
Normal file
@ -0,0 +1,81 @@
|
||||
=pod
|
||||
|
||||
=for comment
|
||||
Original text by James Westby, contributed under the OpenSSL license.
|
||||
|
||||
=head1 NAME
|
||||
|
||||
c_rehash - Create symbolic links to files named by the hash values
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<c_rehash>
|
||||
[ I<directory>...]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<c_rehash> scans directories and calculates a hash value of each C<.pem>
|
||||
file in the specified directory list and creates symbolic links
|
||||
for each file, where the name of the link is the hash value.
|
||||
This utility is useful as many programs that use OpenSSL require
|
||||
directories to be set up like this in order to find certificates.
|
||||
|
||||
If any directories are named on the command line, then those are
|
||||
processed in turn. If not, then the B<SSL_CERT_DIR> environment variable
|
||||
is consulted; this shold be a colon-separated list of directories,
|
||||
like the Unix B<PATH> variable.
|
||||
If that is not set then the default directory (installation-specific
|
||||
but often B</usr/local/ssl/certs>) is processed.
|
||||
|
||||
In order for a directory to be processed, the user must have write
|
||||
permissions on that directory, otherwise it will be skipped.
|
||||
The links created are of the form C<HHHHHHHH.D>, where each B<H>
|
||||
is a hexadecimal character and B<D> is a single decimal digit.
|
||||
When processing a directory, B<c_rehash> will first remove all links
|
||||
that have a name in that syntax. If you have links in that format
|
||||
used for other purposes, they will be removed.
|
||||
Hashes for CRL's look similar except the letter B<r> appears after
|
||||
the period, like this: C<HHHHHHHH.rD>.
|
||||
|
||||
Multiple objects may have the same hash; they will be indicated by
|
||||
incrementing the B<D> value. Duplicates are found by comparing the
|
||||
full SHA-1 fingerprint. A warning will be displayed if a duplicate
|
||||
is found.
|
||||
|
||||
A warning will also be displayed if there are B<.pem> files that
|
||||
cannot be parsed as either a certificate or a CRL.
|
||||
|
||||
The program uses the B<openssl> program to compute the hashes and
|
||||
fingerprints. If not found in the user's B<PATH>, then set the
|
||||
B<OPENSSL> environment variable to the full pathname.
|
||||
Any program can be used, it will be invoked as follows for either
|
||||
a certificate or CRL:
|
||||
|
||||
$OPENSSL x509 -hash -fingerprint -noout -in FFFFFF
|
||||
$OPENSSL crl -hash -fingerprint -noout -in FFFFFF
|
||||
|
||||
where B<FFFFFF> is the filename. It must output the hash of the
|
||||
file on the first line, and the fingerprint on the second,
|
||||
optionally prefixed with some text and an equals sign.
|
||||
|
||||
=head1 ENVIRONMENT
|
||||
|
||||
=over
|
||||
|
||||
=item B<OPENSSL>
|
||||
|
||||
The path to an executable to use to generate hashes and
|
||||
fingerprints (see above).
|
||||
|
||||
=item B<SSL_CERT_DIR>
|
||||
|
||||
Colon separated list of directories to operate on.
|
||||
Ignored if directories are listed on the command line.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<openssl(1)|openssl(1)>,
|
||||
L<crl(1)|crl(1)>.
|
||||
L<x509(1)|x509(1)>.
|
@ -2,16 +2,17 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
dgst, md5, md4, md2, sha1, sha, mdc2, ripemd160 - message digests
|
||||
dgst, sha, sha1, mdc2, ripemd160, sha224, sha256, sha384, sha512, md2, md4, md5, dss1 - message digests
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<openssl> B<dgst>
|
||||
[B<-md5|-md4|-md2|-sha1|-sha|-mdc2|-ripemd160|-dss1>]
|
||||
[B<-sha|-sha1|-mdc2|-ripemd160|-sha224|-sha256|-sha384|-sha512|-md2|-md4|-md5|-dss1>]
|
||||
[B<-c>]
|
||||
[B<-d>]
|
||||
[B<-hex>]
|
||||
[B<-binary>]
|
||||
[B<-r>]
|
||||
[B<-out filename>]
|
||||
[B<-sign filename>]
|
||||
[B<-keyform arg>]
|
||||
@ -20,17 +21,19 @@ B<openssl> B<dgst>
|
||||
[B<-prverify filename>]
|
||||
[B<-signature filename>]
|
||||
[B<-hmac key>]
|
||||
[B<-non-fips-allow>]
|
||||
[B<-fips-fingerprint>]
|
||||
[B<file...>]
|
||||
|
||||
[B<md5|md4|md2|sha1|sha|mdc2|ripemd160>]
|
||||
[B<-c>]
|
||||
[B<-d>]
|
||||
[B<file...>]
|
||||
B<openssl>
|
||||
[I<digest>]
|
||||
[B<...>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The digest functions output the message digest of a supplied file or files
|
||||
in hexadecimal form. They can also be used for digital signing and verification.
|
||||
in hexadecimal. The digest functions also generate and verify digital
|
||||
signatures using message digests.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
@ -48,12 +51,17 @@ print out BIO debugging information.
|
||||
=item B<-hex>
|
||||
|
||||
digest is to be output as a hex dump. This is the default case for a "normal"
|
||||
digest as opposed to a digital signature.
|
||||
digest as opposed to a digital signature. See NOTES below for digital
|
||||
signatures using B<-hex>.
|
||||
|
||||
=item B<-binary>
|
||||
|
||||
output the digest or signature in binary form.
|
||||
|
||||
=item B<-r>
|
||||
|
||||
output the digest in the "coreutils" format used by programs like B<sha1sum>.
|
||||
|
||||
=item B<-out filename>
|
||||
|
||||
filename to output to, or standard output by default.
|
||||
@ -64,8 +72,8 @@ digitally sign the digest using the private key in "filename".
|
||||
|
||||
=item B<-keyform arg>
|
||||
|
||||
Specifies the key format to sign digest with. Only PEM and ENGINE
|
||||
formats are supported by the B<dgst> command.
|
||||
Specifies the key format to sign digest with. The DER, PEM, P12,
|
||||
and ENGINE formats are supported.
|
||||
|
||||
=item B<-engine id>
|
||||
|
||||
@ -138,6 +146,15 @@ Multiple files can be specified separated by a OS-dependent character.
|
||||
The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
|
||||
all others.
|
||||
|
||||
=item B<-non-fips-allow>
|
||||
|
||||
enable use of non-FIPS algorithms such as MD5 even in FIPS mode.
|
||||
|
||||
=item B<-fips-fingerprint>
|
||||
|
||||
compute HMAC using a specific key
|
||||
for certain OpenSSL-FIPS operations.
|
||||
|
||||
=item B<file...>
|
||||
|
||||
file or files to digest. If no files are specified then standard input is
|
||||
@ -145,18 +162,41 @@ used.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
To create a hex-encoded message digest of a file:
|
||||
openssl dgst -md5 -hex file.txt
|
||||
|
||||
To sign a file using SHA-256 with binary file output:
|
||||
openssl dgst -sha256 -sign privatekey.pem -out signature.sign file.txt
|
||||
|
||||
To verify a signature:
|
||||
openssl dgst -sha256 -verify publickey.pem \
|
||||
-signature signature.sign \
|
||||
file.txt
|
||||
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The digest of choice for all new applications is SHA1. Other digests are
|
||||
however still widely used.
|
||||
|
||||
If you wish to sign or verify data using the DSA algorithm then the dss1
|
||||
digest must be used.
|
||||
When signing a file, B<dgst> will automatically determine the algorithm
|
||||
(RSA, ECC, etc) to use for signing based on the private key's ASN.1 info.
|
||||
When verifying signatures, it only handles the RSA, DSA, or ECDSA signature
|
||||
itself, not the related data to identify the signer and algorithm used in
|
||||
formats such as x.509, CMS, and S/MIME.
|
||||
|
||||
A source of random numbers is required for certain signing algorithms, in
|
||||
particular DSA.
|
||||
particular ECDSA and DSA.
|
||||
|
||||
The signing and verify options should only be used if a single file is
|
||||
being signed or verified.
|
||||
|
||||
Hex signatures cannot be verified using B<openssl>. Instead, use "xxd -r"
|
||||
or similar program to transform the hex signature into a binary signature
|
||||
prior to verification.
|
||||
|
||||
|
||||
=cut
|
||||
|
@ -59,8 +59,8 @@ the accept socket. See L<BIO_s_fd(3)|BIO_s_fd(3)>
|
||||
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.
|
||||
|
@ -2,20 +2,20 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
CMS_sign_add1_signer, CMS_SignerInfo_sign - add a signer to a CMS_ContentInfo signed data structure.
|
||||
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_sign_add1_signer(CMS_ContentInfo *cms, X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, unsigned int flags);
|
||||
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_sign_add1_signer() adds a signer with certificate B<signcert> and private
|
||||
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>.
|
||||
|
||||
@ -36,7 +36,7 @@ are both set.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The main purpose of CMS_sign_add1_signer() is to provide finer control
|
||||
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
|
||||
@ -80,13 +80,13 @@ 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_sign_add1_signer() returns an internal pointer to the CMS_SignerInfo
|
||||
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_sign1_add_signers() returns an internal pointer to the CMS_SignerInfo
|
||||
CMS_add1_signer() returns an internal pointer to the CMS_SignerInfo
|
||||
structure just added or NULL if an error occurs.
|
||||
|
||||
=head1 SEE ALSO
|
||||
@ -96,6 +96,6 @@ L<CMS_final(3)|CMS_final(3)>,
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
CMS_sign_add1_signer() was added to OpenSSL 0.9.8
|
||||
CMS_add1_signer() was added to OpenSSL 0.9.8
|
||||
|
||||
=cut
|
@ -245,15 +245,19 @@ digest name passed on the command line.
|
||||
EVP_MD_CTX_destroy(mdctx);
|
||||
|
||||
printf("Digest is: ");
|
||||
for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);
|
||||
for(i = 0; i < md_len; i++)
|
||||
printf("%02x", md_value[i]);
|
||||
printf("\n");
|
||||
|
||||
/* Call this once before exit. */
|
||||
EVP_cleanup();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>,
|
||||
L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>,
|
||||
L<sha(3)|sha(3)>, L<dgst(1)|dgst(1)>
|
||||
L<dgst(1)|dgst(1)>,
|
||||
L<evp(3)|evp(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
@ -269,7 +273,7 @@ EVP_dss(), EVP_dss1(), EVP_mdc2() and EVP_ripemd160() were
|
||||
changed to return truely const EVP_MD * in OpenSSL 0.9.7.
|
||||
|
||||
The link between digests and signing algorithms was fixed in OpenSSL 1.0 and
|
||||
later, so now EVP_sha1() can be used with RSA and DSA, there is no need to
|
||||
later, so now EVP_sha1() can be used with RSA and DSA; there is no need to
|
||||
use EVP_dss1() any more.
|
||||
|
||||
OpenSSL 1.0 and later does not include the MD2 digest algorithm in the
|
||||
|
@ -38,7 +38,7 @@ or a negative value for failure. In particular a return value of -2 indicates
|
||||
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 random number generator must be seeded
|
||||
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
|
||||
|
@ -387,27 +387,7 @@ for certain common S/MIME ciphers (RC2, DES, triple DES) in CBC mode.
|
||||
|
||||
=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)
|
||||
{
|
||||
@ -421,8 +401,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)))
|
||||
{
|
||||
@ -451,28 +432,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(;;)
|
||||
@ -511,4 +498,7 @@ EVP_DecryptInit_ex(), EVP_DecryptFinal_ex(), EVP_CipherInit_ex(),
|
||||
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
|
||||
|
@ -37,7 +37,7 @@ EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
|
||||
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 convention the key obtained
|
||||
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_DH() and
|
||||
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
|
||||
|
@ -28,9 +28,14 @@ B<sig> and the amount of data written to B<siglen>.
|
||||
|
||||
=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 and SHA256 digest:
|
||||
#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 and SHA256 digest:
|
||||
=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)>,
|
||||
|
@ -48,12 +48,13 @@ even if he gets hold of the normal (certified) key, as this key was
|
||||
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.
|
||||
|
10
e_os.h
10
e_os.h
@ -375,6 +375,15 @@ static unsigned int _strlen31(const char *str)
|
||||
# define check_winnt() (GetVersion() < 0x80000000)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -738,4 +747,3 @@ struct servent *getservbyname(const char *name, const char *proto);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
86
ssl/Makefile
86
ssl/Makefile
@ -547,26 +547,27 @@ 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/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/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/pqueue.h
|
||||
s3_cbc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
|
||||
s3_cbc.o: ../include/openssl/sha.h ../include/openssl/srtp.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/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/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/pqueue.h ../include/openssl/rsa.h
|
||||
s3_cbc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
|
||||
s3_cbc.o: ../include/openssl/srtp.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
|
||||
@ -671,28 +672,29 @@ s3_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
|
||||
s3_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
|
||||
s3_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
|
||||
s3_pkt.o: ../include/openssl/x509_vfy.h s3_pkt.c 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/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/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/srtp.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
|
||||
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/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/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/srtp.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
|
||||
ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
|
||||
ssl_algs.o: ../include/openssl/buffer.h ../include/openssl/comp.h
|
||||
ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
|
||||
|
@ -1492,6 +1492,9 @@ dtls1_process_heartbeat(SSL *s)
|
||||
/* Read type and payload length first */
|
||||
if (1 + 2 + 16 > s->s3->rrec.length)
|
||||
return 0; /* silently discard */
|
||||
if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH)
|
||||
return 0; /* silently discard per RFC 6520 sec. 4 */
|
||||
|
||||
hbtype = *p++;
|
||||
n2s(p, payload);
|
||||
if (1 + 2 + payload + 16 > s->s3->rrec.length)
|
||||
|
10
ssl/d1_lib.c
10
ssl/d1_lib.c
@ -266,6 +266,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);
|
||||
|
@ -168,25 +168,6 @@ static int find_profile_by_name(char *profile_name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int find_profile_by_num(unsigned profile_num,
|
||||
SRTP_PROTECTION_PROFILE **pptr)
|
||||
{
|
||||
SRTP_PROTECTION_PROFILE *p;
|
||||
|
||||
p=srtp_known_profiles;
|
||||
while(p->name)
|
||||
{
|
||||
if(p->id == profile_num)
|
||||
{
|
||||
*pptr=p;
|
||||
return 0;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTECTION_PROFILE) **out)
|
||||
{
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
|
||||
@ -209,11 +190,19 @@ static int ssl_ctx_make_profiles(const char *profiles_string,STACK_OF(SRTP_PROTE
|
||||
if(!find_profile_by_name(ptr,&p,
|
||||
col ? col-ptr : (int)strlen(ptr)))
|
||||
{
|
||||
if (sk_SRTP_PROTECTION_PROFILE_find(profiles,p) >= 0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
|
||||
sk_SRTP_PROTECTION_PROFILE_free(profiles);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sk_SRTP_PROTECTION_PROFILE_push(profiles,p);
|
||||
}
|
||||
else
|
||||
{
|
||||
SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
|
||||
sk_SRTP_PROTECTION_PROFILE_free(profiles);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -305,13 +294,12 @@ int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int max
|
||||
|
||||
int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al)
|
||||
{
|
||||
SRTP_PROTECTION_PROFILE *cprof,*sprof;
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *clnt=0,*srvr;
|
||||
SRTP_PROTECTION_PROFILE *sprof;
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
|
||||
int ct;
|
||||
int mki_len;
|
||||
int i,j;
|
||||
int id;
|
||||
int ret;
|
||||
int i, srtp_pref;
|
||||
unsigned int id;
|
||||
|
||||
/* Length value + the MKI length */
|
||||
if(len < 3)
|
||||
@ -341,8 +329,10 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
clnt=sk_SRTP_PROTECTION_PROFILE_new_null();
|
||||
srvr=SSL_get_srtp_profiles(s);
|
||||
s->srtp_profile = NULL;
|
||||
/* Search all profiles for a match initially */
|
||||
srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
|
||||
|
||||
while(ct)
|
||||
{
|
||||
@ -350,13 +340,21 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
|
||||
ct-=2;
|
||||
len-=2;
|
||||
|
||||
if(!find_profile_by_num(id,&cprof))
|
||||
/*
|
||||
* Only look for match in profiles of higher preference than
|
||||
* current match.
|
||||
* If no profiles have been have been configured then this
|
||||
* does nothing.
|
||||
*/
|
||||
for (i = 0; i < srtp_pref; i++)
|
||||
{
|
||||
sk_SRTP_PROTECTION_PROFILE_push(clnt,cprof);
|
||||
sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
|
||||
if (sprof->id == id)
|
||||
{
|
||||
s->srtp_profile = sprof;
|
||||
srtp_pref = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
; /* Ignore */
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,36 +369,7 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
|
||||
return 1;
|
||||
}
|
||||
|
||||
srvr=SSL_get_srtp_profiles(s);
|
||||
|
||||
/* Pick our most preferred profile. If no profiles have been
|
||||
configured then the outer loop doesn't run
|
||||
(sk_SRTP_PROTECTION_PROFILE_num() = -1)
|
||||
and so we just return without doing anything */
|
||||
for(i=0;i<sk_SRTP_PROTECTION_PROFILE_num(srvr);i++)
|
||||
{
|
||||
sprof=sk_SRTP_PROTECTION_PROFILE_value(srvr,i);
|
||||
|
||||
for(j=0;j<sk_SRTP_PROTECTION_PROFILE_num(clnt);j++)
|
||||
{
|
||||
cprof=sk_SRTP_PROTECTION_PROFILE_value(clnt,j);
|
||||
|
||||
if(cprof->id==sprof->id)
|
||||
{
|
||||
s->srtp_profile=sprof;
|
||||
*al=0;
|
||||
ret=0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret=0;
|
||||
|
||||
done:
|
||||
if(clnt) sk_SRTP_PROTECTION_PROFILE_free(clnt);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen)
|
||||
|
@ -84,6 +84,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define DTLS1_VERSION 0xFEFF
|
||||
#define DTLS_MAX_VERSION DTLS1_VERSION
|
||||
|
||||
#define DTLS1_BAD_VER 0x0100
|
||||
|
||||
#if 0
|
||||
@ -284,4 +286,3 @@ typedef struct dtls1_record_data_st
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -125,9 +125,11 @@ static const 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 if (ver == TLS1_1_VERSION)
|
||||
return(TLSv1_1_client_method());
|
||||
@ -698,6 +700,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))
|
||||
{
|
||||
@ -712,7 +715,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;
|
||||
@ -736,6 +741,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 */
|
||||
|
@ -127,9 +127,11 @@ static const 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 if (ver == TLS1_1_VERSION)
|
||||
return(TLSv1_1_server_method());
|
||||
@ -421,6 +423,9 @@ int ssl23_get_client_hello(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure that TLS_MAX_VERSION is up-to-date */
|
||||
OPENSSL_assert(s->version <= TLS_MAX_VERSION);
|
||||
|
||||
#ifdef OPENSSL_FIPS
|
||||
if (FIPS_mode() && (s->version < TLS1_VERSION))
|
||||
{
|
||||
@ -597,6 +602,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;
|
||||
|
||||
@ -624,14 +635,6 @@ int ssl23_get_client_hello(SSL *s)
|
||||
s->s3->rbuf.left=0;
|
||||
s->s3->rbuf.offset=0;
|
||||
}
|
||||
if (s->version == TLS1_2_VERSION)
|
||||
s->method = TLSv1_2_server_method();
|
||||
else if (s->version == TLS1_1_VERSION)
|
||||
s->method = TLSv1_1_server_method();
|
||||
else 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
|
||||
|
@ -391,6 +391,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;
|
||||
}
|
||||
@ -437,7 +439,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;
|
||||
|
65
ssl/s3_cbc.c
65
ssl/s3_cbc.c
@ -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
|
||||
@ -208,7 +178,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. */
|
||||
@ -216,20 +186,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
|
||||
@ -296,8 +260,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);
|
||||
@ -683,12 +647,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. */
|
||||
@ -704,7 +668,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;
|
||||
}
|
||||
|
254
ssl/s3_clnt.c
254
ssl/s3_clnt.c
@ -326,9 +326,9 @@ int ssl3_connect(SSL *s)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* Check if it is anon DH/ECDH */
|
||||
/* Check if it is anon DH/ECDH, SRP auth */
|
||||
/* or PSK */
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP)) &&
|
||||
!(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
|
||||
{
|
||||
ret=ssl3_get_server_certificate(s);
|
||||
@ -1277,8 +1277,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;
|
||||
const EVP_MD *md = NULL;
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
@ -1354,36 +1354,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
|
||||
@ -1395,6 +1407,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;
|
||||
}
|
||||
@ -1407,14 +1420,22 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
if (alg_k & SSL_kSRP)
|
||||
{
|
||||
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_SRP_N_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@ -1422,14 +1443,24 @@ 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_SRP_G_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@ -1437,15 +1468,25 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
}
|
||||
p+=i;
|
||||
|
||||
|
||||
if (1 > n - param_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += 1;
|
||||
|
||||
i = (unsigned int)(p[0]);
|
||||
p++;
|
||||
param_len+=i+1;
|
||||
if (param_len > n)
|
||||
|
||||
if (i > n - param_len)
|
||||
{
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@ -1453,14 +1494,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_SRP_B_LENGTH);
|
||||
goto f_err;
|
||||
}
|
||||
param_len += i;
|
||||
|
||||
if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
|
||||
@ -1498,14 +1548,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);
|
||||
@ -1513,14 +1572,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);
|
||||
@ -1552,14 +1620,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);
|
||||
@ -1567,14 +1644,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);
|
||||
@ -1582,14 +1668,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);
|
||||
@ -1641,11 +1736,18 @@ 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) ||
|
||||
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;
|
||||
@ -1688,15 +1790,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;
|
||||
@ -1739,7 +1841,15 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
{
|
||||
if (TLS1_get_version(s) >= TLS1_2_VERSION)
|
||||
{
|
||||
int sigalg = tls12_get_sigid(pkey);
|
||||
int sigalg;
|
||||
if (2 > n)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
sigalg = tls12_get_sigid(pkey);
|
||||
/* Should never happen */
|
||||
if (sigalg == -1)
|
||||
{
|
||||
@ -1757,7 +1867,6 @@ int ssl3_get_key_exchange(SSL *s)
|
||||
if (md == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
#ifdef SSL_DEBUG
|
||||
@ -1769,14 +1878,20 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
else
|
||||
md = EVP_sha1();
|
||||
|
||||
if (2 > n)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
|
||||
SSL_R_LENGTH_TOO_SHORT);
|
||||
goto f_err;
|
||||
}
|
||||
n2s(p,i);
|
||||
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;
|
||||
}
|
||||
@ -1785,6 +1900,7 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
if (pkey->type == EVP_PKEY_RSA && TLS1_get_version(s) < TLS1_2_VERSION)
|
||||
{
|
||||
int num;
|
||||
unsigned int size;
|
||||
|
||||
j=0;
|
||||
q=md_buf;
|
||||
@ -1797,9 +1913,9 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
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);
|
||||
@ -1835,8 +1951,8 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(alg_a & SSL_aNULL) && !(alg_k & SSL_kPSK))
|
||||
/* aNULL or kPSK do not need public keys */
|
||||
/* aNULL, aSRP or kPSK do not need public keys */
|
||||
if (!(alg_a & (SSL_aNULL|SSL_aSRP)) && !(alg_k & SSL_kPSK))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
@ -1844,7 +1960,6 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
/* 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;
|
||||
}
|
||||
@ -2846,7 +2961,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;
|
||||
@ -2860,8 +2979,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)
|
||||
{
|
||||
@ -2875,7 +2995,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;
|
||||
@ -2910,13 +3037,12 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
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;
|
||||
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)
|
||||
{
|
||||
|
@ -900,7 +900,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
38
ssl/s3_lib.c
38
ssl/s3_lib.c
@ -3355,6 +3355,33 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
||||
#endif
|
||||
|
||||
#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_2_VERSION
|
||||
# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
|
||||
#endif
|
||||
if (!(s->options & SSL_OP_NO_TLSv1_2))
|
||||
return s->version == TLS1_2_VERSION;
|
||||
if (!(s->options & SSL_OP_NO_TLSv1_1))
|
||||
return s->version == TLS1_1_VERSION;
|
||||
if (!(s->options & SSL_OP_NO_TLSv1))
|
||||
return s->version == TLS1_VERSION;
|
||||
if (!(s->options & SSL_OP_NO_SSLv3))
|
||||
return s->version == SSL3_VERSION;
|
||||
if (!(s->options & SSL_OP_NO_SSLv2))
|
||||
return s->version == SSL2_VERSION;
|
||||
}
|
||||
return 0; /* Unexpected state; fail closed. */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3714,6 +3741,7 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void))
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
@ -3822,8 +3850,13 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
|
||||
emask_k = cert->export_mask_k;
|
||||
emask_a = cert->export_mask_a;
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
mask_k=cert->mask_k | s->srp_ctx.srp_Mask;
|
||||
emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask;
|
||||
if (s->srp_ctx.srp_Mask & SSL_kSRP)
|
||||
{
|
||||
mask_k |= SSL_kSRP;
|
||||
emask_k |= SSL_kSRP;
|
||||
mask_a |= SSL_aSRP;
|
||||
emask_a |= SSL_aSRP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
@ -4291,4 +4324,3 @@ long ssl_get_algorithm2(SSL *s)
|
||||
return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
|
||||
return alg2;
|
||||
}
|
||||
|
||||
|
19
ssl/s3_pkt.c
19
ssl/s3_pkt.c
@ -273,6 +273,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.
|
||||
@ -293,6 +299,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;
|
||||
@ -523,7 +530,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);
|
||||
|
111
ssl/s3_srvr.c
111
ssl/s3_srvr.c
@ -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>
|
||||
@ -410,9 +411,8 @@ int ssl3_accept(SSL *s)
|
||||
case SSL3_ST_SW_CERT_B:
|
||||
/* Check if it is anon DH or anon ECDH, */
|
||||
/* normal PSK or KRB5 or SRP */
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aKRB5|SSL_aSRP))
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
|
||||
{
|
||||
ret=ssl3_send_server_certificate(s);
|
||||
if (ret <= 0) goto end;
|
||||
@ -515,7 +515,9 @@ int ssl3_accept(SSL *s)
|
||||
* (against the specs, but s3_clnt.c accepts this for SSL 3) */
|
||||
!(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
|
||||
/* never request cert in Kerberos ciphersuites */
|
||||
(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
|
||||
(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
|
||||
/* don't request certificate for SRP auth */
|
||||
(s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
|
||||
/* With normal PSK Certificates and
|
||||
* Certificate Requests are omitted */
|
||||
|| (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
|
||||
@ -1846,7 +1848,7 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
n+=2+nr[i];
|
||||
}
|
||||
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
|
||||
if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP))
|
||||
&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
|
||||
{
|
||||
if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
|
||||
@ -2166,6 +2168,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)
|
||||
{
|
||||
@ -2213,52 +2219,59 @@ 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)
|
||||
{
|
||||
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))))
|
||||
{
|
||||
/* 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. */
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
/* 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++)
|
||||
{
|
||||
p[i] = constant_time_select_8(decrypt_good, p[i],
|
||||
rand_premaster_secret[i]);
|
||||
}
|
||||
|
||||
s->session->master_key_length=
|
||||
|
@ -130,6 +130,8 @@ extern "C" {
|
||||
#define SRTP_NULL_SHA1_80 0x0005
|
||||
#define SRTP_NULL_SHA1_32 0x0006
|
||||
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
|
||||
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
|
||||
int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
|
||||
SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
|
||||
@ -137,6 +139,8 @@ SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
|
||||
STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
|
||||
SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -653,6 +653,10 @@ struct ssl_session_st
|
||||
*/
|
||||
#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
|
||||
#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
|
||||
/* Send TLS_FALLBACK_SCSV in the ClientHello.
|
||||
* To be set by applications that reconnect with a downgraded protocol
|
||||
* version; see draft-ietf-tls-downgrade-scsv-00 for details. */
|
||||
#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
|
||||
|
||||
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
|
||||
* they cannot be used to clear bits. */
|
||||
@ -1511,6 +1515,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
|
||||
@ -1621,6 +1626,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82
|
||||
#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83
|
||||
|
||||
#define SSL_CTRL_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) \
|
||||
@ -2379,6 +2386,7 @@ void ERR_load_SSL_strings(void);
|
||||
#define SSL_R_HTTPS_PROXY_REQUEST 155
|
||||
#define SSL_R_HTTP_REQUEST 156
|
||||
#define SSL_R_ILLEGAL_PADDING 283
|
||||
#define SSL_R_INAPPROPRIATE_FALLBACK 373
|
||||
#define SSL_R_INCONSISTENT_COMPRESSION 340
|
||||
#define SSL_R_INVALID_CHALLENGE_LENGTH 158
|
||||
#define SSL_R_INVALID_COMMAND 280
|
||||
@ -2525,6 +2533,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
|
||||
|
@ -128,9 +128,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
|
||||
/* Signalling cipher suite value from RFC 5746
|
||||
* (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */
|
||||
#define SSL3_CK_SCSV 0x030000FF
|
||||
|
||||
/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
|
||||
* (TLS_FALLBACK_SCSV) */
|
||||
#define SSL3_CK_FALLBACK_SCSV 0x03005600
|
||||
|
||||
#define SSL3_CK_RSA_NULL_MD5 0x03000001
|
||||
#define SSL3_CK_RSA_NULL_SHA 0x03000002
|
||||
#define SSL3_CK_RSA_RC4_40_MD5 0x03000003
|
||||
|
@ -383,6 +383,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
|
||||
{ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"},
|
||||
{ERR_REASON(SSL_R_HTTP_REQUEST) ,"http request"},
|
||||
{ERR_REASON(SSL_R_ILLEGAL_PADDING) ,"illegal padding"},
|
||||
{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK),"inappropriate fallback"},
|
||||
{ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION),"inconsistent compression"},
|
||||
{ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
|
||||
{ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
|
||||
@ -529,6 +530,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"},
|
||||
|
@ -1387,6 +1387,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++)
|
||||
{
|
||||
@ -1411,25 +1413,37 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
|
||||
!(s->srp_ctx.srp_Mask & SSL_kSRP))
|
||||
continue;
|
||||
#endif /* OPENSSL_NO_SRP */
|
||||
j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
|
||||
j = put_cb(c,p);
|
||||
p+=j;
|
||||
}
|
||||
/* If p == q, no ciphers and caller indicates an error. Otherwise
|
||||
* add SCSV if not renegotiating.
|
||||
*/
|
||||
if (p != q && !s->renegotiate)
|
||||
/* If p == q, no ciphers; caller indicates an error.
|
||||
* Otherwise, add applicable SCSVs. */
|
||||
if (p != q)
|
||||
{
|
||||
if (!s->renegotiate)
|
||||
{
|
||||
static SSL_CIPHER scsv =
|
||||
{
|
||||
0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
|
||||
j = put_cb(&scsv,p);
|
||||
p+=j;
|
||||
#ifdef OPENSSL_RI_DEBUG
|
||||
fprintf(stderr, "SCSV sent by client\n");
|
||||
fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV)
|
||||
{
|
||||
static SSL_CIPHER scsv =
|
||||
{
|
||||
0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
j = put_cb(&scsv,p);
|
||||
p+=j;
|
||||
}
|
||||
}
|
||||
|
||||
return(p-q);
|
||||
}
|
||||
|
||||
@ -1439,11 +1453,12 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
|
||||
const SSL_CIPHER *c;
|
||||
STACK_OF(SSL_CIPHER) *sk;
|
||||
int i,n;
|
||||
|
||||
if (s->s3)
|
||||
s->s3->send_connection_binding = 0;
|
||||
|
||||
n=ssl_put_cipher_by_char(s,NULL,NULL);
|
||||
if ((num%n) != 0)
|
||||
if (n == 0 || (num%n) != 0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
|
||||
return(NULL);
|
||||
@ -1458,7 +1473,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)))
|
||||
@ -1478,6 +1493,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)
|
||||
@ -2944,15 +2976,26 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
|
||||
|
||||
SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
|
||||
{
|
||||
CERT *ocert = ssl->cert;
|
||||
if (ssl->ctx == ctx)
|
||||
return ssl->ctx;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (ctx == NULL)
|
||||
ctx = ssl->initial_ctx;
|
||||
#endif
|
||||
if (ssl->cert != NULL)
|
||||
ssl_cert_free(ssl->cert);
|
||||
ssl->cert = ssl_cert_dup(ctx->cert);
|
||||
if (ocert != NULL)
|
||||
{
|
||||
int i;
|
||||
/* Copy negotiated digests from original */
|
||||
for (i = 0; i < SSL_PKEY_NUM; i++)
|
||||
{
|
||||
CERT_PKEY *cpk = ocert->pkeys + i;
|
||||
CERT_PKEY *rpk = ssl->cert->pkeys + i;
|
||||
rpk->digest = cpk->digest;
|
||||
}
|
||||
ssl_cert_free(ocert);
|
||||
}
|
||||
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
|
||||
if (ssl->ctx != NULL)
|
||||
SSL_CTX_free(ssl->ctx); /* decrement reference count */
|
||||
|
@ -1241,6 +1241,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);
|
||||
|
12
ssl/t1_lib.c
12
ssl/t1_lib.c
@ -643,7 +643,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
if(SSL_get_srtp_profiles(s))
|
||||
if(SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s))
|
||||
{
|
||||
int el;
|
||||
|
||||
@ -806,7 +806,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned c
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
if(s->srtp_profile)
|
||||
if(SSL_IS_DTLS(s) && s->srtp_profile)
|
||||
{
|
||||
int el;
|
||||
|
||||
@ -1444,7 +1444,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
||||
|
||||
/* session ticket processed earlier */
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
else if (type == TLSEXT_TYPE_use_srtp)
|
||||
else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
|
||||
&& type == TLSEXT_TYPE_use_srtp)
|
||||
{
|
||||
if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
|
||||
al))
|
||||
@ -1698,7 +1699,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
||||
}
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SRTP
|
||||
else if (type == TLSEXT_TYPE_use_srtp)
|
||||
else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp)
|
||||
{
|
||||
if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
|
||||
al))
|
||||
@ -2347,7 +2348,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);
|
||||
return 2;
|
||||
}
|
||||
/* Attempt to decrypt session data */
|
||||
/* Move p after IV to start of encrypted ticket, update length */
|
||||
p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
|
||||
|
17
ssl/tls1.h
17
ssl/tls1.h
@ -159,17 +159,19 @@ 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
|
||||
#define TLS_MAX_VERSION TLS1_2_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)
|
||||
@ -187,6 +189,7 @@ extern "C" {
|
||||
#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */
|
||||
#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */
|
||||
#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */
|
||||
#define TLS1_AD_INAPPROPRIATE_FALLBACK 86 /* fatal */
|
||||
#define TLS1_AD_USER_CANCELLED 90
|
||||
#define TLS1_AD_NO_RENEGOTIATION 100
|
||||
/* codes 110-114 are from RFC3546 */
|
||||
|
@ -1145,6 +1145,7 @@ sub read_options
|
||||
"dll" => \$shlib,
|
||||
"shared" => 0,
|
||||
"no-sctp" => 0,
|
||||
"no-srtp" => 0,
|
||||
"no-gmp" => 0,
|
||||
"no-rfc3779" => 0,
|
||||
"no-montasm" => 0,
|
||||
|
@ -117,6 +117,8 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
|
||||
"SSL_INTERN",
|
||||
# SCTP
|
||||
"SCTP",
|
||||
# SRTP
|
||||
"SRTP",
|
||||
# Unit testing
|
||||
"UNIT_TEST");
|
||||
|
||||
@ -138,7 +140,7 @@ my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
|
||||
my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
|
||||
my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
|
||||
my $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc;
|
||||
my $no_nextprotoneg; my $no_sctp;
|
||||
my $no_nextprotoneg; my $no_sctp; my $no_srtp;
|
||||
my $no_unit_test;
|
||||
|
||||
my $fips;
|
||||
@ -238,6 +240,7 @@ foreach (@ARGV, split(/ /, $options))
|
||||
elsif (/^no-jpake$/) { $no_jpake=1; }
|
||||
elsif (/^no-srp$/) { $no_srp=1; }
|
||||
elsif (/^no-sctp$/) { $no_sctp=1; }
|
||||
elsif (/^no-srtp$/) { $no_srtp=1; }
|
||||
elsif (/^no-unit-test$/){ $no_unit_test=1; }
|
||||
}
|
||||
|
||||
@ -1209,6 +1212,7 @@ sub is_valid
|
||||
if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
|
||||
if ($keyword eq "SRP" && $no_srp) { return 0; }
|
||||
if ($keyword eq "SCTP" && $no_sctp) { return 0; }
|
||||
if ($keyword eq "SRTP" && $no_srtp) { return 0; }
|
||||
if ($keyword eq "UNIT_TEST" && $no_unit_test) { return 0; }
|
||||
if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
|
||||
|
||||
|
@ -310,14 +310,14 @@ TLSv1_2_method 350 EXIST::FUNCTION:
|
||||
SSL_SESSION_get_id_len 351 NOEXIST::FUNCTION:
|
||||
kssl_ctx_get0_client_princ 352 EXIST::FUNCTION:KRB5
|
||||
SSL_export_keying_material 353 EXIST::FUNCTION:TLSEXT
|
||||
SSL_set_tlsext_use_srtp 354 EXIST::FUNCTION:
|
||||
SSL_set_tlsext_use_srtp 354 EXIST::FUNCTION:SRTP
|
||||
SSL_CTX_set_next_protos_advertised_cb 355 EXIST:!VMS:FUNCTION:NEXTPROTONEG
|
||||
SSL_CTX_set_next_protos_adv_cb 355 EXIST:VMS:FUNCTION:NEXTPROTONEG
|
||||
SSL_get0_next_proto_negotiated 356 EXIST::FUNCTION:NEXTPROTONEG
|
||||
SSL_get_selected_srtp_profile 357 EXIST::FUNCTION:
|
||||
SSL_CTX_set_tlsext_use_srtp 358 EXIST::FUNCTION:
|
||||
SSL_get_selected_srtp_profile 357 EXIST::FUNCTION:SRTP
|
||||
SSL_CTX_set_tlsext_use_srtp 358 EXIST::FUNCTION:SRTP
|
||||
SSL_select_next_proto 359 EXIST::FUNCTION:NEXTPROTONEG
|
||||
SSL_get_srtp_profiles 360 EXIST::FUNCTION:
|
||||
SSL_get_srtp_profiles 360 EXIST::FUNCTION:SRTP
|
||||
SSL_CTX_set_next_proto_select_cb 361 EXIST:!VMS:FUNCTION:NEXTPROTONEG
|
||||
SSL_CTX_set_next_proto_sel_cb 361 EXIST:VMS:FUNCTION:NEXTPROTONEG
|
||||
SSL_SESSION_get_compress_id 362 EXIST::FUNCTION:
|
||||
|
Loading…
Reference in New Issue
Block a user