diff options
Diffstat (limited to 'openssl/ssl')
-rw-r--r-- | openssl/ssl/Makefile | 24 | ||||
-rw-r--r-- | openssl/ssl/d1_enc.c | 59 | ||||
-rw-r--r-- | openssl/ssl/d1_pkt.c | 91 | ||||
-rw-r--r-- | openssl/ssl/d1_srtp.c | 5 | ||||
-rw-r--r-- | openssl/ssl/dtls1.h | 8 | ||||
-rw-r--r-- | openssl/ssl/s2_clnt.c | 14 | ||||
-rw-r--r-- | openssl/ssl/s2_pkt.c | 3 | ||||
-rw-r--r-- | openssl/ssl/s2_srvr.c | 16 | ||||
-rw-r--r-- | openssl/ssl/s3_both.c | 14 | ||||
-rw-r--r-- | openssl/ssl/s3_cbc.c | 790 | ||||
-rw-r--r-- | openssl/ssl/s3_clnt.c | 4 | ||||
-rw-r--r-- | openssl/ssl/s3_enc.c | 123 | ||||
-rw-r--r-- | openssl/ssl/s3_lib.c | 16 | ||||
-rw-r--r-- | openssl/ssl/s3_pkt.c | 101 | ||||
-rw-r--r-- | openssl/ssl/s3_srvr.c | 19 | ||||
-rw-r--r-- | openssl/ssl/ssl.h | 8 | ||||
-rw-r--r-- | openssl/ssl/ssl3.h | 6 | ||||
-rw-r--r-- | openssl/ssl/ssl_algs.c | 1 | ||||
-rw-r--r-- | openssl/ssl/ssl_cert.c | 4 | ||||
-rw-r--r-- | openssl/ssl/ssl_ciph.c | 5 | ||||
-rw-r--r-- | openssl/ssl/ssl_err.c | 1 | ||||
-rw-r--r-- | openssl/ssl/ssl_lib.c | 26 | ||||
-rw-r--r-- | openssl/ssl/ssl_locl.h | 44 | ||||
-rw-r--r-- | openssl/ssl/ssl_rsa.c | 14 | ||||
-rw-r--r-- | openssl/ssl/ssltest.c | 2 | ||||
-rw-r--r-- | openssl/ssl/t1_enc.c | 159 | ||||
-rw-r--r-- | openssl/ssl/t1_lib.c | 133 | ||||
-rw-r--r-- | openssl/ssl/tls_srp.c | 3 |
28 files changed, 1338 insertions, 355 deletions
diff --git a/openssl/ssl/Makefile b/openssl/ssl/Makefile index feaf3e358..debe07405 100644 --- a/openssl/ssl/Makefile +++ b/openssl/ssl/Makefile @@ -22,7 +22,7 @@ LIB=$(TOP)/libssl.a SHARED_LIB= libssl$(SHLIB_EXT) LIBSRC= \ s2_meth.c s2_srvr.c s2_clnt.c s2_lib.c s2_enc.c s2_pkt.c \ - s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c \ + s3_meth.c s3_srvr.c s3_clnt.c s3_lib.c s3_enc.c s3_pkt.c s3_both.c s3_cbc.c \ s23_meth.c s23_srvr.c s23_clnt.c s23_lib.c s23_pkt.c \ t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \ @@ -33,7 +33,7 @@ LIBSRC= \ bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c LIBOBJ= \ s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ - s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ + s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o s3_cbc.o \ s23_meth.o s23_srvr.o s23_clnt.o s23_lib.o s23_pkt.o \ t1_meth.o t1_srvr.o t1_clnt.o t1_lib.o t1_enc.o \ d1_meth.o d1_srvr.o d1_clnt.o d1_lib.o d1_pkt.o \ @@ -547,6 +547,26 @@ 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_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 diff --git a/openssl/ssl/d1_enc.c b/openssl/ssl/d1_enc.c index 07a5e97ce..712c4647f 100644 --- a/openssl/ssl/d1_enc.c +++ b/openssl/ssl/d1_enc.c @@ -126,20 +126,28 @@ #include <openssl/des.h> #endif +/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. */ int dtls1_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; - int bs,i,ii,j,k,n=0; + int bs,i,j,k,mac_size=0; const EVP_CIPHER *enc; if (send) { if (EVP_MD_CTX_md(s->write_hash)) { - n=EVP_MD_CTX_size(s->write_hash); - if (n < 0) + mac_size=EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) return -1; } ds=s->enc_write_ctx; @@ -164,9 +172,8 @@ int dtls1_enc(SSL *s, int send) { if (EVP_MD_CTX_md(s->read_hash)) { - n=EVP_MD_CTX_size(s->read_hash); - if (n < 0) - return -1; + mac_size=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size >= 0); } ds=s->enc_read_ctx; rec= &(s->s3->rrec); @@ -231,7 +238,7 @@ int dtls1_enc(SSL *s, int send) if (!send) { if (l == 0 || l%bs != 0) - return -1; + return 0; } EVP_Cipher(ds,rec->data,rec->input,l); @@ -246,43 +253,7 @@ int dtls1_enc(SSL *s, int send) #endif /* KSSL_DEBUG */ if ((bs != 1) && !send) - { - ii=i=rec->data[l-1]; /* padding_length */ - i++; - if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) - { - /* First packet is even in size, so check */ - if ((memcmp(s->s3->read_sequence, - "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) - s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - i--; - } - /* TLS 1.0 does not bound the number of padding bytes by the block size. - * All of them must have value 'padding_length'. */ - if (i + bs > (int)rec->length) - { - /* Incorrect padding. SSLerr() and ssl3_alert are done - * by caller: we don't want to reveal whether this is - * a decryption error or a MAC verification failure - * (see http://www.openssl.org/~bodo/tls-cbc.txt) - */ - return -1; - } - for (j=(int)(l-i); j<(int)l; j++) - { - if (rec->data[j] != ii) - { - /* Incorrect padding */ - return -1; - } - } - rec->length-=i; - - rec->data += bs; /* skip the implicit IV */ - rec->input += bs; - rec->length -= bs; - } + return tls1_cbc_remove_padding(s, rec, bs, mac_size); } return(1); } diff --git a/openssl/ssl/d1_pkt.c b/openssl/ssl/d1_pkt.c index 987af6083..0bf87be6d 100644 --- a/openssl/ssl/d1_pkt.c +++ b/openssl/ssl/d1_pkt.c @@ -376,15 +376,11 @@ static int dtls1_process_record(SSL *s) { int i,al; - int clear=0; int enc_err; SSL_SESSION *sess; SSL3_RECORD *rr; - unsigned int mac_size; + unsigned int mac_size, orig_len; unsigned char md[EVP_MAX_MD_SIZE]; - int decryption_failed_or_bad_record_mac = 0; - unsigned char *mac = NULL; - rr= &(s->s3->rrec); sess = s->session; @@ -416,12 +412,16 @@ dtls1_process_record(SSL *s) rr->data=rr->input; enc_err = s->method->ssl3_enc->enc(s,0); - if (enc_err <= 0) + /* enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid */ + if (enc_err == 0) { - /* To minimize information leaked via timing, we will always - * perform all computations before discarding the message. - */ - decryption_failed_or_bad_record_mac = 1; + /* For DTLS we simply ignore bad packets. */ + rr->length = 0; + s->packet_length = 0; + goto err; } #ifdef TLS_DEBUG @@ -431,45 +431,62 @@ printf("\n"); #endif /* r->length is now the compressed data plus mac */ - if ( (sess == NULL) || - (s->enc_read_ctx == NULL) || - (s->read_hash == NULL)) - clear=1; - - if (!clear) + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && + (EVP_MD_CTX_md(s->read_hash) != NULL)) { - /* !clear => s->read_hash != NULL => mac_size != -1 */ - int t; - t=EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(t >= 0); - mac_size=t; - - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size=EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + + /* kludge: *_cbc_remove_padding passes padding length in rr->type */ + orig_len = rr->length+((unsigned int)rr->type>>8); + + /* orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different + * amount of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size+1)) { -#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ - al=SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; -#else - decryption_failed_or_bad_record_mac = 1; -#endif } - /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length >= mac_size) + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* We update the length so that the TLS header bytes + * can be constructed correctly but we need to extract + * the MAC in constant time from within the record, + * without leaking the contents of the padding bytes. + * */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); rr->length -= mac_size; - mac = &rr->data[rr->length]; } else - rr->length = 0; - i=s->method->ssl3_enc->mac(s,md,0); - if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0) { - decryption_failed_or_bad_record_mac = 1; + /* In this case there's no padding, so |orig_len| + * equals |rec->length| and we checked that there's + * enough bytes for |mac_size| above. */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; } + + i=s->method->ssl3_enc->mac(s,md,0 /* not send */); + if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) + enc_err = -1; } - if (decryption_failed_or_bad_record_mac) + if (enc_err < 0) { /* decryption failed, silently discard message */ rr->length = 0; diff --git a/openssl/ssl/d1_srtp.c b/openssl/ssl/d1_srtp.c index 928935bd8..ab9c41922 100644 --- a/openssl/ssl/d1_srtp.c +++ b/openssl/ssl/d1_srtp.c @@ -115,11 +115,12 @@ Copyright (C) 2011, RTFM, Inc. */ -#ifndef OPENSSL_NO_SRTP - #include <stdio.h> #include <openssl/objects.h> #include "ssl_locl.h" + +#ifndef OPENSSL_NO_SRTP + #include "srtp.h" diff --git a/openssl/ssl/dtls1.h b/openssl/ssl/dtls1.h index 5008bf608..e65d50119 100644 --- a/openssl/ssl/dtls1.h +++ b/openssl/ssl/dtls1.h @@ -57,8 +57,8 @@ * */ -#ifndef HEADER_DTLS1_H -#define HEADER_DTLS1_H +#ifndef HEADER_DTLS1_H +#define HEADER_DTLS1_H #include <openssl/buffer.h> #include <openssl/pqueue.h> @@ -72,8 +72,12 @@ #elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) #include <sys/timeval.h> #else +#if defined(OPENSSL_SYS_VXWORKS) +#include <sys/times.h> +#else #include <sys/time.h> #endif +#endif #ifdef __cplusplus extern "C" { diff --git a/openssl/ssl/s2_clnt.c b/openssl/ssl/s2_clnt.c index 00ac158f9..03b6cf967 100644 --- a/openssl/ssl/s2_clnt.c +++ b/openssl/ssl/s2_clnt.c @@ -359,12 +359,14 @@ static int get_server_hello(SSL *s) SSL_R_PEER_ERROR); return(-1); } -#ifdef __APPLE_CC__ - /* The Rhapsody 5.5 (a.k.a. MacOS X) compiler bug - * workaround. <appro@fy.chalmers.se> */ - s->hit=(i=*(p++))?1:0; -#else +#if 0 s->hit=(*(p++))?1:0; + /* Some [PPC?] compilers fail to increment p in above + statement, e.g. one provided with Rhapsody 5.5, but + most recent example XL C 11.1 for AIX, even without + optimization flag... */ +#else + s->hit=(*p)?1:0; p++; #endif s->s2->tmp.cert_type= *(p++); n2s(p,i); @@ -937,7 +939,7 @@ static int get_server_verify(SSL *s) s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */ p += 1; - if (memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) + if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT); diff --git a/openssl/ssl/s2_pkt.c b/openssl/ssl/s2_pkt.c index ac963b2d4..8bb6ab8ba 100644 --- a/openssl/ssl/s2_pkt.c +++ b/openssl/ssl/s2_pkt.c @@ -269,8 +269,7 @@ static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) s->s2->ract_data_length-=mac_size; ssl2_mac(s,mac,0); s->s2->ract_data_length-=s->s2->padding; - if ( (memcmp(mac,s->s2->mac_data, - (unsigned int)mac_size) != 0) || + if ( (CRYPTO_memcmp(mac,s->s2->mac_data,mac_size) != 0) || (s->s2->rlength%EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { SSLerr(SSL_F_SSL2_READ_INTERNAL,SSL_R_BAD_MAC_DECODE); diff --git a/openssl/ssl/s2_srvr.c b/openssl/ssl/s2_srvr.c index bc885e8e7..2cba426bb 100644 --- a/openssl/ssl/s2_srvr.c +++ b/openssl/ssl/s2_srvr.c @@ -1059,10 +1059,12 @@ static int request_certificate(SSL *s) EVP_PKEY *pkey=NULL; EVP_MD_CTX_init(&ctx); - EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL); - EVP_VerifyUpdate(&ctx,s->s2->key_material, - s->s2->key_material_length); - EVP_VerifyUpdate(&ctx,ccd,SSL2_MIN_CERT_CHALLENGE_LENGTH); + if (!EVP_VerifyInit_ex(&ctx,s->ctx->rsa_md5, NULL) + || !EVP_VerifyUpdate(&ctx,s->s2->key_material, + s->s2->key_material_length) + || !EVP_VerifyUpdate(&ctx,ccd, + SSL2_MIN_CERT_CHALLENGE_LENGTH)) + goto msg_end; i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,NULL); buf2=OPENSSL_malloc((unsigned int)i); @@ -1073,7 +1075,11 @@ static int request_certificate(SSL *s) } p2=buf2; i=i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509,&p2); - EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i); + if (!EVP_VerifyUpdate(&ctx,buf2,(unsigned int)i)) + { + OPENSSL_free(buf2); + goto msg_end; + } OPENSSL_free(buf2); pkey=X509_get_pubkey(x509); diff --git a/openssl/ssl/s3_both.c b/openssl/ssl/s3_both.c index b63460a56..ead01c82a 100644 --- a/openssl/ssl/s3_both.c +++ b/openssl/ssl/s3_both.c @@ -204,7 +204,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) #ifndef OPENSSL_NO_NEXTPROTONEG /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */ -static void ssl3_take_mac(SSL *s) { +static void ssl3_take_mac(SSL *s) + { const char *sender; int slen; @@ -221,7 +222,7 @@ static void ssl3_take_mac(SSL *s) { s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, sender,slen,s->s3->tmp.peer_finish_md); -} + } #endif int ssl3_get_finished(SSL *s, int a, int b) @@ -231,8 +232,9 @@ int ssl3_get_finished(SSL *s, int a, int b) unsigned char *p; #ifdef OPENSSL_NO_NEXTPROTONEG - /* the mac has already been generated when we received the change - * cipher spec message and is in s->s3->tmp.peer_finish_md. */ + /* the mac has already been generated when we received the + * change cipher spec message and is in s->s3->tmp.peer_finish_md. + */ #endif n=s->method->ssl_get_message(s, @@ -263,7 +265,7 @@ int ssl3_get_finished(SSL *s, int a, int b) goto f_err; } - if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) + if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED); @@ -537,12 +539,14 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) s->init_num += i; n -= i; } + #ifndef OPENSSL_NO_NEXTPROTONEG /* If receiving Finished, record MAC of prior handshake messages for * Finished verification. */ if (*s->init_buf->data == SSL3_MT_FINISHED) ssl3_take_mac(s); #endif + /* Feed this message into MAC computation. */ ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); if (s->msg_callback) diff --git a/openssl/ssl/s3_cbc.c b/openssl/ssl/s3_cbc.c new file mode 100644 index 000000000..02edf3f91 --- /dev/null +++ b/openssl/ssl/s3_cbc.c @@ -0,0 +1,790 @@ +/* ssl/s3_cbc.c */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" + +#include <openssl/md5.h> +#include <openssl/sha.h> + +/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length + * field. (SHA-384/512 have 128-bit length.) */ +#define MAX_HASH_BIT_COUNT_BYTES 16 + +/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. + * Currently SHA-384/512 has a 128-byte block size and that's the largest + * 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. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. */ +int ssl3_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size) + { + unsigned padding_length, good; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + + /* These lengths are all public so we can test them in non-constant + * time. */ + if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length-1]; + good = constant_time_ge(rec->length, padding_length+overhead); + /* SSLv3 requires that the padding is minimal. */ + good &= constant_time_ge(block_size, padding_length+1); + 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)); +} + +/* 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 + * -1 otherwise. It also removes any explicit IV from the start of the record + * without leaking any timing about whether there was enough space after the + * padding was removed. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. */ +int tls1_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size) + { + unsigned padding_length, good, to_check, i; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + /* Check if version requires explicit IV */ + if (s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION) + { + /* These lengths are all public so we can test them in + * non-constant time. + */ + if (overhead + block_size > rec->length) + return 0; + /* We can now safely skip explicit IV */ + rec->data += block_size; + rec->input += block_size; + rec->length -= block_size; + } + else if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length-1]; + + /* NB: if compression is in operation the first packet may not be of + * even length so the padding bug check cannot be performed. This bug + * workaround has been around since SSLeay so hopefully it is either + * fixed now or no buggy implementation supports compression [steve] + */ + if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) + { + /* First packet is even in size, so check */ + if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0",8) == 0) && + !(padding_length & 1)) + { + s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; + } + if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && + padding_length > 0) + { + padding_length--; + } + } + + if (EVP_CIPHER_flags(s->enc_read_ctx->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER) + { + /* padding is already verified */ + rec->length -= padding_length + 1; + return 1; + } + + good = constant_time_ge(rec->length, overhead+padding_length); + /* The padding consists of a length byte at the end of the record and + * then that many bytes of padding, all with the same value as the + * length byte. Thus, with the length byte included, there are i+1 + * bytes of padding. + * + * We can't check just |padding_length+1| bytes because that leaks + * decrypted information. Therefore we always have to check the maximum + * amount of padding possible. (Again, the length of the record is + * public information so we can use it.) */ + to_check = 255; /* maximum amount of padding. */ + if (to_check > rec->length-1) + to_check = rec->length-1; + + for (i = 0; i < to_check; i++) + { + unsigned char mask = constant_time_ge(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. */ + good &= ~(mask&(padding_length ^ b)); + } + + /* 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); + + 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)); + } + +/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in + * constant time (independent of the concrete value of rec->length, which may + * vary within a 256-byte window). + * + * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to + * this function. + * + * On entry: + * rec->orig_len >= md_size + * md_size <= EVP_MAX_MD_SIZE + * + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into + * a single or pair of cache-lines, then the variable memory accesses don't + * actually affect the timing. CPUs with smaller cache-lines [if any] are + * not multi-core and are not considered vulnerable to cache-timing attacks. + */ +#define CBC_MAC_ROTATE_IN_PLACE + +void ssl3_cbc_copy_mac(unsigned char* out, + const SSL3_RECORD *rec, + unsigned md_size,unsigned orig_len) + { +#if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE]; + unsigned char *rotated_mac; +#else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; +#endif + + /* mac_end is the index of |rec->data| just after the end of the MAC. */ + unsigned mac_end = rec->length; + unsigned mac_start = mac_end - md_size; + /* scan_start contains the number of bytes that we can ignore because + * the MAC's position can only vary by 255 bytes. */ + unsigned scan_start = 0; + unsigned i, j; + unsigned div_spoiler; + unsigned rotate_offset; + + OPENSSL_assert(orig_len >= md_size); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + +#if defined(CBC_MAC_ROTATE_IN_PLACE) + rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63); +#endif + + /* This information is public so it's safe to branch based on it. */ + if (orig_len > md_size + 255 + 1) + scan_start = orig_len - (md_size + 255 + 1); + /* div_spoiler contains a multiple of md_size that is used to cause the + * modulo operation to be constant time. Without this, the time varies + * based on the amount of padding when running on Intel chips at least. + * + * The aim of right-shifting md_size is so that the compiler doesn't + * figure out that it can remove div_spoiler as that would require it + * to prove that md_size is always even, which I hope is beyond it. */ + div_spoiler = md_size >> 1; + div_spoiler <<= (sizeof(div_spoiler)-1)*8; + rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; + + 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 b = rec->data[i]; + rotated_mac[j++] |= b & mac_started & ~mac_ended; + j &= constant_time_lt(j,md_size); + } + + /* Now rotate the MAC */ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < md_size; i++) + { + /* in case cache-line is 32 bytes, touch second line */ + ((volatile unsigned char *)rotated_mac)[rotate_offset^32]; + out[j++] = rotated_mac[rotate_offset++]; + rotate_offset &= constant_time_lt(rotate_offset,md_size); + } +#else + memset(out, 0, md_size); + rotate_offset = md_size - rotate_offset; + rotate_offset &= constant_time_lt(rotate_offset,md_size); + for (i = 0; i < md_size; i++) + { + for (j = 0; j < md_size; j++) + out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); + rotate_offset++; + rotate_offset &= constant_time_lt(rotate_offset,md_size); + } +#endif + } + +/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in + * little-endian order. The value of p is advanced by four. */ +#define u32toLE(n, p) \ + (*((p)++)=(unsigned char)(n), \ + *((p)++)=(unsigned char)(n>>8), \ + *((p)++)=(unsigned char)(n>>16), \ + *((p)++)=(unsigned char)(n>>24)) + +/* These functions serialize the state of a hash and thus perform the standard + * "final" operation without adding the padding and length that such a function + * typically does. */ +static void tls1_md5_final_raw(void* ctx, unsigned char *md_out) + { + MD5_CTX *md5 = ctx; + u32toLE(md5->A, md_out); + u32toLE(md5->B, md_out); + u32toLE(md5->C, md_out); + u32toLE(md5->D, md_out); + } + +static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out) + { + SHA_CTX *sha1 = ctx; + l2n(sha1->h0, md_out); + l2n(sha1->h1, md_out); + l2n(sha1->h2, md_out); + l2n(sha1->h3, md_out); + l2n(sha1->h4, md_out); + } +#define LARGEST_DIGEST_CTX SHA_CTX + +#ifndef OPENSSL_NO_SHA256 +static void tls1_sha256_final_raw(void* ctx, unsigned char *md_out) + { + SHA256_CTX *sha256 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) + { + l2n(sha256->h[i], md_out); + } + } +#undef LARGEST_DIGEST_CTX +#define LARGEST_DIGEST_CTX SHA256_CTX +#endif + +#ifndef OPENSSL_NO_SHA512 +static void tls1_sha512_final_raw(void* ctx, unsigned char *md_out) + { + SHA512_CTX *sha512 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) + { + l2n8(sha512->h[i], md_out); + } + } +#undef LARGEST_DIGEST_CTX +#define LARGEST_DIGEST_CTX SHA512_CTX +#endif + +/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. */ +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) + { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return 0; +#endif + switch (EVP_MD_CTX_type(ctx)) + { + case NID_md5: + case NID_sha1: +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + case NID_sha256: +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + case NID_sha512: +#endif + return 1; + default: + return 0; + } + } + +/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS + * record. + * + * ctx: the EVP_MD_CTX from which we take the hash function. + * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. + * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. + * md_out_size: if non-NULL, the number of output bytes is written here. + * header: the 13-byte, TLS record header. + * data: the record data itself, less any preceeding explicit IV. + * data_plus_mac_size: the secret, reported length of the data and MAC + * once the padding has been removed. + * data_plus_mac_plus_padding_size: the public length of the whole + * record, including padding. + * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. + * + * On entry: by virtue of having been through one of the remove_padding + * functions, above, we know that data_plus_mac_size is large enough to contain + * a padding byte and MAC. (If the padding was invalid, it might contain the + * padding too. ) */ +void ssl3_cbc_digest_record( + const EVP_MD_CTX *ctx, + unsigned char* md_out, + size_t* md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, + char is_sslv3) + { + union { double align; + unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; } md_state; + void (*md_final_raw)(void *ctx, unsigned char *md_out); + void (*md_transform)(void *ctx, const unsigned char *block); + unsigned md_size, md_block_size = 64; + unsigned sslv3_pad_length = 40, header_length, variance_blocks, + len, max_mac_bytes, num_blocks, + num_starting_blocks, k, mac_end_offset, c, index_a, index_b; + unsigned int bits; /* at most 18 bits */ + unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + /* hmac_pad is the masked HMAC key. */ + unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; + unsigned char first_block[MAX_HASH_BLOCK_SIZE]; + unsigned char mac_out[EVP_MAX_MD_SIZE]; + unsigned i, j, md_out_size_u; + EVP_MD_CTX md_ctx; + /* mdLengthSize is the number of bytes in the length field that terminates + * the hash. */ + unsigned md_length_size = 8; + char length_is_big_endian = 1; + + /* This is a, hopefully redundant, check that allows us to forget about + * many possible overflows later in this function. */ + OPENSSL_assert(data_plus_mac_plus_padding_size < 1024*1024); + + switch (EVP_MD_CTX_type(ctx)) + { + case NID_md5: + MD5_Init((MD5_CTX*)md_state.c); + md_final_raw = tls1_md5_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform; + md_size = 16; + sslv3_pad_length = 48; + length_is_big_endian = 0; + break; + case NID_sha1: + SHA1_Init((SHA_CTX*)md_state.c); + md_final_raw = tls1_sha1_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA1_Transform; + md_size = 20; + break; +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + SHA224_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 224/8; + break; + case NID_sha256: + SHA256_Init((SHA256_CTX*)md_state.c); + md_final_raw = tls1_sha256_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA256_Transform; + md_size = 32; + break; +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + SHA384_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 384/8; + md_block_size = 128; + md_length_size = 16; + break; + case NID_sha512: + SHA512_Init((SHA512_CTX*)md_state.c); + md_final_raw = tls1_sha512_final_raw; + md_transform = (void(*)(void *ctx, const unsigned char *block)) SHA512_Transform; + md_size = 64; + md_block_size = 128; + md_length_size = 16; + break; +#endif + default: + /* ssl3_cbc_record_digest_supported should have been + * called first to check that the hash function is + * supported. */ + OPENSSL_assert(0); + if (md_out_size) + *md_out_size = -1; + return; + } + + OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + + header_length = 13; + if (is_sslv3) + { + header_length = + mac_secret_length + + sslv3_pad_length + + 8 /* sequence number */ + + 1 /* record type */ + + 2 /* record length */; + } + + /* variance_blocks is the number of blocks of the hash that we have to + * calculate in constant time because they could be altered by the + * padding value. + * + * In SSLv3, the padding must be minimal so the end of the plaintext + * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that + * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash + * termination (0x80 + 64-bit length) don't fit in the final block, we + * say that the final two blocks can vary based on the padding. + * + * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not + * required to be minimal. Therefore we say that the final six blocks + * can vary based on the padding. + * + * Later in the function, if the message is short and there obviously + * cannot be this many blocks then variance_blocks can be reduced. */ + variance_blocks = is_sslv3 ? 2 : 6; + /* From now on we're dealing with the MAC, which conceptually has 13 + * bytes of `header' before the start of the data (TLS) or 71/75 bytes + * (SSLv3) */ + len = data_plus_mac_plus_padding_size + header_length; + /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including + * |header|, assuming that there's no padding. */ + max_mac_bytes = len - md_size - 1; + /* num_blocks is the maximum number of hash blocks. */ + num_blocks = (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; + /* In order to calculate the MAC in constant time we have to handle + * the final blocks specially because the padding value could cause the + * end to appear somewhere in the final |variance_blocks| blocks and we + * can't leak where. However, |num_starting_blocks| worth of data can + * be hashed right away because no padding value can affect whether + * they are plaintext. */ + num_starting_blocks = 0; + /* k is the starting byte offset into the conceptual header||data where + * we start processing. */ + k = 0; + /* mac_end_offset is the index just past the end of the data to be + * MACed. */ + mac_end_offset = data_plus_mac_size + header_length - md_size; + /* c is the index of the 0x80 byte in the final hash block that + * contains application data. */ + c = mac_end_offset % md_block_size; + /* index_a is the hash block number that contains the 0x80 terminating + * value. */ + index_a = mac_end_offset / md_block_size; + /* index_b is the hash block number that contains the 64-bit hash + * length, in bits. */ + index_b = (mac_end_offset + md_length_size) / md_block_size; + /* bits is the hash-length in bits. It includes the additional hash + * block for the masked HMAC key, or whole of |header| in the case of + * SSLv3. */ + + /* For SSLv3, if we're going to have any starting blocks then we need + * at least two because the header is larger than a single block. */ + if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) + { + num_starting_blocks = num_blocks - variance_blocks; + k = md_block_size*num_starting_blocks; + } + + bits = 8*mac_end_offset; + if (!is_sslv3) + { + /* Compute the initial HMAC block. For SSLv3, the padding and + * secret bytes are included in |header| because they take more + * than a single block. */ + bits += 8*md_block_size; + memset(hmac_pad, 0, md_block_size); + OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); + memcpy(hmac_pad, mac_secret, mac_secret_length); + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x36; + + md_transform(md_state.c, hmac_pad); + } + + if (length_is_big_endian) + { + memset(length_bytes,0,md_length_size-4); + length_bytes[md_length_size-4] = (unsigned char)(bits>>24); + length_bytes[md_length_size-3] = (unsigned char)(bits>>16); + length_bytes[md_length_size-2] = (unsigned char)(bits>>8); + length_bytes[md_length_size-1] = (unsigned char)bits; + } + else + { + memset(length_bytes,0,md_length_size); + length_bytes[md_length_size-5] = (unsigned char)(bits>>24); + length_bytes[md_length_size-6] = (unsigned char)(bits>>16); + length_bytes[md_length_size-7] = (unsigned char)(bits>>8); + length_bytes[md_length_size-8] = (unsigned char)bits; + } + + if (k > 0) + { + if (is_sslv3) + { + /* The SSLv3 header is larger than a single block. + * overhang is the number of bytes beyond a single + * block that the header consumes: either 7 bytes + * (SHA1) or 11 bytes (MD5). */ + unsigned overhang = header_length-md_block_size; + md_transform(md_state.c, header); + memcpy(first_block, header + md_block_size, overhang); + memcpy(first_block + overhang, data, md_block_size-overhang); + md_transform(md_state.c, first_block); + for (i = 1; i < k/md_block_size - 1; i++) + md_transform(md_state.c, data + md_block_size*i - overhang); + } + else + { + /* k is a multiple of md_block_size. */ + memcpy(first_block, header, 13); + memcpy(first_block+13, data, md_block_size-13); + md_transform(md_state.c, first_block); + for (i = 1; i < k/md_block_size; i++) + md_transform(md_state.c, data + md_block_size*i - 13); + } + } + + memset(mac_out, 0, sizeof(mac_out)); + + /* We now process the final hash blocks. For each block, we construct + * it in constant time. If the |i==index_a| then we'll include the 0x80 + * bytes and zero pad etc. For each block we selectively copy it, in + * constant time, to |mac_out|. */ + for (i = num_starting_blocks; i <= num_starting_blocks+variance_blocks; i++) + { + unsigned char block[MAX_HASH_BLOCK_SIZE]; + unsigned char is_block_a = constant_time_eq_8(i, index_a); + unsigned char is_block_b = constant_time_eq_8(i, index_b); + for (j = 0; j < md_block_size; j++) + { + unsigned char b = 0, is_past_c, is_past_cp1; + if (k < header_length) + b = header[k]; + else if (k < data_plus_mac_plus_padding_size + header_length) + 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); + /* 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); + /* If this the the block containing the end of the + * application data and we're past the 0x80 value then + * just write zero. */ + b = b&~is_past_cp1; + /* If this is index_b (the final block), but not + * index_a (the end of the data), then the 64-bit + * length didn't fit into index_a and we're having to + * add an extra block of zeros. */ + b &= ~is_block_b | is_block_a; + + /* The final bytes of one of the blocks contains the + * length. */ + 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)]); + } + block[j] = b; + } + + md_transform(md_state.c, block); + md_final_raw(md_state.c, block); + /* If this is index_b, copy the hash value to |mac_out|. */ + for (j = 0; j < md_size; j++) + mac_out[j] |= block[j]&is_block_b; + } + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */); + if (is_sslv3) + { + /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ + memset(hmac_pad, 0x5c, sslv3_pad_length); + + EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length); + EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + } + else + { + /* Complete the HMAC in the standard manner. */ + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x6a; + + EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + } + EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); + if (md_out_size) + *md_out_size = md_out_size_u; + EVP_MD_CTX_cleanup(&md_ctx); + } + +#ifdef OPENSSL_FIPS + +/* Due to the need to use EVP in FIPS mode we can't reimplement digests but + * we can ensure the number of blocks processed is equal for all cases + * by digesting additional data. + */ + +void tls_fips_digest_extra( + const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx, + const unsigned char *data, size_t data_len, size_t orig_len) + { + size_t block_size, digest_pad, blocks_data, blocks_orig; + if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) + return; + block_size = EVP_MD_CTX_block_size(mac_ctx); + /* We are in FIPS mode if we get this far so we know we have only SHA* + * digests and TLS to deal with. + * Minimum digest padding length is 17 for SHA384/SHA512 and 9 + * otherwise. + * Additional header is 13 bytes. To get the number of digest blocks + * processed round up the amount of data plus padding to the nearest + * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. + * So we have: + * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size + * equivalently: + * blocks = (payload_len + digest_pad + 12)/block_size + 1 + * HMAC adds a constant overhead. + * We're ultimately only interested in differences so this becomes + * blocks = (payload_len + 29)/128 + * for SHA384/SHA512 and + * blocks = (payload_len + 21)/64 + * otherwise. + */ + digest_pad = block_size == 64 ? 21 : 29; + blocks_orig = (orig_len + digest_pad)/block_size; + blocks_data = (data_len + digest_pad)/block_size; + /* MAC enough blocks to make up the difference between the original + * and actual lengths plus one extra block to ensure this is never a + * no op. The "data" pointer should always have enough space to + * perform this operation as it is large enough for a maximum + * length TLS buffer. + */ + EVP_DigestSignUpdate(mac_ctx, data, + (blocks_orig - blocks_data + 1) * block_size); + } +#endif diff --git a/openssl/ssl/s3_clnt.c b/openssl/ssl/s3_clnt.c index b80d052e1..344e2eb1a 100644 --- a/openssl/ssl/s3_clnt.c +++ b/openssl/ssl/s3_clnt.c @@ -459,7 +459,6 @@ int ssl3_connect(SSL *s) SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); if (ret <= 0) goto end; - #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) s->state=SSL3_ST_CW_FINISHED_A; #else @@ -987,7 +986,10 @@ int ssl3_get_server_hello(SSL *s) * client authentication. */ if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s)) + { + al = SSL_AD_INTERNAL_ERROR; goto f_err; + } /* lets get the compression algorithm */ /* COMPRESSION */ #ifdef OPENSSL_NO_COMP diff --git a/openssl/ssl/s3_enc.c b/openssl/ssl/s3_enc.c index c5df2cb90..e3cd4f062 100644 --- a/openssl/ssl/s3_enc.c +++ b/openssl/ssl/s3_enc.c @@ -466,12 +466,21 @@ void ssl3_cleanup_key_block(SSL *s) s->s3->tmp.key_block_length=0; } +/* ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding is invalid or, if sending, an internal error + * occured. + */ int ssl3_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; - int bs,i; + int bs,i,mac_size=0; const EVP_CIPHER *enc; if (send) @@ -522,32 +531,16 @@ int ssl3_enc(SSL *s, int send) if (!send) { if (l == 0 || l%bs != 0) - { - SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); return 0; - } /* otherwise, rec->length >= bs */ } EVP_Cipher(ds,rec->data,rec->input,l); + if (EVP_MD_CTX_md(s->read_hash) != NULL) + mac_size = EVP_MD_CTX_size(s->read_hash); if ((bs != 1) && !send) - { - i=rec->data[l-1]+1; - /* SSL 3.0 bounds the number of padding bytes by the block size; - * padding bytes (except the last one) are arbitrary */ - if (i > bs) - { - /* Incorrect padding. SSLerr() and ssl3_alert are done - * by caller: we don't want to reveal whether this is - * a decryption error or a MAC verification failure - * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ - return -1; - } - /* now i <= bs <= rec->length */ - rec->length-=i; - } + return ssl3_cbc_remove_padding(s, rec, bs, mac_size); } return(1); } @@ -716,7 +709,7 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) EVP_MD_CTX md_ctx; const EVP_MD_CTX *hash; unsigned char *p,rec_char; - unsigned int md_size; + size_t md_size, orig_len; int npad; int t; @@ -741,28 +734,72 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) md_size=t; npad=(48/md_size)*md_size; - /* Chop the digest off the end :-) */ - EVP_MD_CTX_init(&md_ctx); - - EVP_MD_CTX_copy_ex( &md_ctx,hash); - EVP_DigestUpdate(&md_ctx,mac_sec,md_size); - EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); - EVP_DigestUpdate(&md_ctx,seq,8); - rec_char=rec->type; - EVP_DigestUpdate(&md_ctx,&rec_char,1); - p=md; - s2n(rec->length,p); - EVP_DigestUpdate(&md_ctx,md,2); - EVP_DigestUpdate(&md_ctx,rec->input,rec->length); - EVP_DigestFinal_ex( &md_ctx,md,NULL); - - EVP_MD_CTX_copy_ex( &md_ctx,hash); - EVP_DigestUpdate(&md_ctx,mac_sec,md_size); - EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); - EVP_DigestUpdate(&md_ctx,md,md_size); - EVP_DigestFinal_ex( &md_ctx,md,&md_size); - - EVP_MD_CTX_cleanup(&md_ctx); + /* kludge: ssl3_cbc_remove_padding passes padding length in rec->type */ + orig_len = rec->length+md_size+((unsigned int)rec->type>>8); + rec->type &= 0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(hash)) + { + /* This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of + * data we are hashing because that gives an attacker a + * timing-oracle. */ + + /* npad is, at most, 48 bytes and that's with MD5: + * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. + * + * With SHA-1 (the largest hash speced for SSLv3) the hash size + * goes up 4, but npad goes down by 8, resulting in a smaller + * total size. */ + unsigned char header[75]; + unsigned j = 0; + memcpy(header+j, mac_sec, md_size); + j += md_size; + memcpy(header+j, ssl3_pad_1, npad); + j += npad; + memcpy(header+j, seq, 8); + j += 8; + header[j++] = rec->type; + header[j++] = rec->length >> 8; + header[j++] = rec->length & 0xff; + + ssl3_cbc_digest_record( + hash, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + mac_sec, md_size, + 1 /* is SSLv3 */); + } + else + { + unsigned int md_size_u; + /* Chop the digest off the end :-) */ + EVP_MD_CTX_init(&md_ctx); + + EVP_MD_CTX_copy_ex( &md_ctx,hash); + EVP_DigestUpdate(&md_ctx,mac_sec,md_size); + EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); + EVP_DigestUpdate(&md_ctx,seq,8); + rec_char=rec->type; + EVP_DigestUpdate(&md_ctx,&rec_char,1); + p=md; + s2n(rec->length,p); + EVP_DigestUpdate(&md_ctx,md,2); + EVP_DigestUpdate(&md_ctx,rec->input,rec->length); + EVP_DigestFinal_ex( &md_ctx,md,NULL); + + EVP_MD_CTX_copy_ex( &md_ctx,hash); + EVP_DigestUpdate(&md_ctx,mac_sec,md_size); + EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); + EVP_DigestUpdate(&md_ctx,md,md_size); + EVP_DigestFinal_ex( &md_ctx,md,&md_size_u); + md_size = md_size_u; + + EVP_MD_CTX_cleanup(&md_ctx); + } ssl3_record_sequence_update(seq); return(md_size); diff --git a/openssl/ssl/s3_lib.c b/openssl/ssl/s3_lib.c index fb60cde8e..e7c5dcb80 100644 --- a/openssl/ssl/s3_lib.c +++ b/openssl/ssl/s3_lib.c @@ -1125,7 +1125,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_DSS_WITH_AES_128_SHA256, TLS1_CK_DH_DSS_WITH_AES_128_SHA256, - SSL_kDHr, + SSL_kDHd, SSL_aDH, SSL_AES128, SSL_SHA256, @@ -1407,7 +1407,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 0, /* not implemented (non-ephemeral DH) */ TLS1_TXT_DH_DSS_WITH_AES_256_SHA256, TLS1_CK_DH_DSS_WITH_AES_256_SHA256, - SSL_kDHr, + SSL_kDHd, SSL_aDH, SSL_AES256, SSL_SHA256, @@ -1958,7 +1958,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 0, TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256, TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256, - SSL_kDHr, + SSL_kDHd, SSL_aDH, SSL_AES128GCM, SSL_AEAD, @@ -1974,7 +1974,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 0, TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384, TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384, - SSL_kDHr, + SSL_kDHd, SSL_aDH, SSL_AES256GCM, SSL_AEAD, @@ -2669,7 +2669,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256, TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256, - SSL_kECDHe, + SSL_kECDHr, SSL_aECDH, SSL_AES128, SSL_SHA256, @@ -2685,7 +2685,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384, TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384, - SSL_kECDHe, + SSL_kECDHr, SSL_aECDH, SSL_AES256, SSL_SHA384, @@ -2799,7 +2799,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, - SSL_kECDHe, + SSL_kECDHr, SSL_aECDH, SSL_AES128GCM, SSL_AEAD, @@ -2815,7 +2815,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 1, TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, - SSL_kECDHe, + SSL_kECDHr, SSL_aECDH, SSL_AES256GCM, SSL_AEAD, diff --git a/openssl/ssl/s3_pkt.c b/openssl/ssl/s3_pkt.c index adf8c387c..804291e27 100644 --- a/openssl/ssl/s3_pkt.c +++ b/openssl/ssl/s3_pkt.c @@ -290,11 +290,8 @@ static int ssl3_get_record(SSL *s) unsigned char *p; unsigned char md[EVP_MAX_MD_SIZE]; short version; - int mac_size; - int clear=0; + unsigned mac_size, orig_len; size_t extra; - int decryption_failed_or_bad_record_mac = 0; - unsigned char *mac = NULL; rr= &(s->s3->rrec); sess=s->session; @@ -403,17 +400,15 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); rr->data=rr->input; enc_err = s->method->ssl3_enc->enc(s,0); - if (enc_err <= 0) + /* enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid */ + if (enc_err == 0) { - if (enc_err == 0) - /* SSLerr() and ssl3_send_alert() have been called */ - goto err; - - /* Otherwise enc_err == -1, which indicates bad padding - * (rec->length has not been changed in this case). - * To minimize information leaked via timing, we will perform - * the MAC computation anyway. */ - decryption_failed_or_bad_record_mac = 1; + al=SSL_AD_DECRYPTION_FAILED; + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); + goto f_err; } #ifdef TLS_DEBUG @@ -423,53 +418,62 @@ printf("\n"); #endif /* r->length is now the compressed data plus mac */ - if ( (sess == NULL) || - (s->enc_read_ctx == NULL) || - (EVP_MD_CTX_md(s->read_hash) == NULL)) - clear=1; - - if (!clear) + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && + (EVP_MD_CTX_md(s->read_hash) != NULL)) { - /* !clear => s->read_hash != NULL => mac_size != -1 */ + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; mac_size=EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(mac_size >= 0); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) + /* kludge: *_cbc_remove_padding passes padding length in rr->type */ + orig_len = rr->length+((unsigned int)rr->type>>8); + + /* orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different + * amount of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size+1)) { -#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ - al=SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; -#else - decryption_failed_or_bad_record_mac = 1; -#endif } - /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length >= (unsigned int)mac_size) + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* We update the length so that the TLS header bytes + * can be constructed correctly but we need to extract + * the MAC in constant time from within the record, + * without leaking the contents of the padding bytes. + * */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); rr->length -= mac_size; - mac = &rr->data[rr->length]; } else { - /* record (minus padding) is too short to contain a MAC */ -#if 0 /* OK only for stream ciphers */ - al=SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); - goto f_err; -#else - decryption_failed_or_bad_record_mac = 1; - rr->length = 0; -#endif - } - i=s->method->ssl3_enc->mac(s,md,0); - if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0) - { - decryption_failed_or_bad_record_mac = 1; + /* In this case there's no padding, so |orig_len| + * equals |rec->length| and we checked that there's + * enough bytes for |mac_size| above. */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; } + + i=s->method->ssl3_enc->mac(s,md,0 /* not send */); + if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) + enc_err = -1; } - if (decryption_failed_or_bad_record_mac) + if (enc_err < 0) { /* A separate 'decryption_failed' alert was introduced with TLS 1.0, * SSL 3.0 only has 'bad_record_mac'. But unless a decryption @@ -744,6 +748,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, * bytes and record version number > TLS 1.0 */ if (s->state == SSL3_ST_CW_CLNT_HELLO_B + && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION) *(p++) = 0x1; else @@ -1238,7 +1243,7 @@ start: goto f_err; } #ifdef SSL_AD_MISSING_SRP_USERNAME - if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) + else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) return(0); #endif } diff --git a/openssl/ssl/s3_srvr.c b/openssl/ssl/s3_srvr.c index 118939fab..bfb848054 100644 --- a/openssl/ssl/s3_srvr.c +++ b/openssl/ssl/s3_srvr.c @@ -191,7 +191,8 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) { if(s->srp_ctx.login == NULL) { - /* There isn't any srp login extension !!! */ + /* RFC 5054 says SHOULD reject, + we do so if There is no srp login name */ ret = SSL3_AL_FATAL; *al = SSL_AD_UNKNOWN_PSK_IDENTITY; } @@ -378,6 +379,7 @@ int ssl3_accept(SSL *s) } } #endif + s->renegotiate = 2; s->state=SSL3_ST_SW_SRVR_HELLO_A; s->init_num=0; @@ -1181,7 +1183,7 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } } - if (ssl_check_clienthello_tlsext(s) <= 0) { + if (ssl_check_clienthello_tlsext_early(s) <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT); goto err; } @@ -1389,7 +1391,10 @@ int ssl3_get_client_hello(SSL *s) if (TLS1_get_version(s) < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER)) { if (!ssl3_digest_cached_records(s)) + { + al = SSL_AD_INTERNAL_ERROR; goto f_err; + } } /* we now have the following setup. @@ -1403,6 +1408,16 @@ int ssl3_get_client_hello(SSL *s) * s->tmp.new_cipher - the new cipher to use. */ + /* Handles TLS extensions that we couldn't check earlier */ + if (s->version >= SSL3_VERSION) + { + if (ssl_check_clienthello_tlsext_late(s) <= 0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + } + if (ret < 0) ret=1; if (0) { diff --git a/openssl/ssl/ssl.h b/openssl/ssl/ssl.h index 8b0c2a2da..593579ed3 100644 --- a/openssl/ssl/ssl.h +++ b/openssl/ssl/ssl.h @@ -493,6 +493,9 @@ struct ssl_session_st char *psk_identity_hint; char *psk_identity; #endif + /* Used to indicate that session resumption is not allowed. + * Applications can also set this bit for a new session via + * not_resumable_session_cb to disable session caching and tickets. */ int not_resumable; /* The cert is the certificate used to establish this connection */ @@ -535,7 +538,7 @@ struct ssl_session_st #endif /* OPENSSL_NO_EC */ /* RFC4507 info */ unsigned char *tlsext_tick; /* Session ticket */ - size_t tlsext_ticklen; /* Session ticket length */ + size_t tlsext_ticklen; /* Session ticket length */ long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ #endif #ifndef OPENSSL_NO_SRP @@ -927,6 +930,7 @@ struct ssl_ctx_st /* Callback for status request */ int (*tlsext_status_cb)(SSL *ssl, void *arg); void *tlsext_status_arg; + /* draft-rescorla-tls-opaque-prf-input-00.txt information */ int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg); void *tlsext_opaque_prf_input_callback_arg; @@ -952,6 +956,7 @@ struct ssl_ctx_st #endif #ifndef OPENSSL_NO_TLSEXT + # ifndef OPENSSL_NO_NEXTPROTONEG /* Next protocol negotiation information */ /* (for experimental NPN extension). */ @@ -2206,6 +2211,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_GET_NEW_SESSION 181 #define SSL_F_SSL_GET_PREV_SESSION 217 #define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +#define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 #define SSL_F_SSL_GET_SIGN_PKEY 183 #define SSL_F_SSL_INIT_WBIO_BUFFER 184 #define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 diff --git a/openssl/ssl/ssl3.h b/openssl/ssl/ssl3.h index 112e627de..247e88c2d 100644 --- a/openssl/ssl/ssl3.h +++ b/openssl/ssl/ssl3.h @@ -578,8 +578,10 @@ typedef struct ssl3_state_st #define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) #define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) #define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) +#ifndef OPENSSL_NO_NEXTPROTONEG #define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT) #define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT) +#endif #define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) #define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) /* read from server */ @@ -629,8 +631,10 @@ typedef struct ssl3_state_st #define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) #define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) #define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) +#ifndef OPENSSL_NO_NEXTPROTONEG #define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT) #define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT) +#endif #define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) #define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) /* write to client */ @@ -655,7 +659,9 @@ typedef struct ssl3_state_st #define SSL3_MT_CLIENT_KEY_EXCHANGE 16 #define SSL3_MT_FINISHED 20 #define SSL3_MT_CERTIFICATE_STATUS 22 +#ifndef OPENSSL_NO_NEXTPROTONEG #define SSL3_MT_NEXT_PROTO 67 +#endif #define DTLS1_MT_HELLO_VERIFY_REQUEST 3 diff --git a/openssl/ssl/ssl_algs.c b/openssl/ssl/ssl_algs.c index d443143c5..9c34d1972 100644 --- a/openssl/ssl/ssl_algs.c +++ b/openssl/ssl/ssl_algs.c @@ -94,6 +94,7 @@ int SSL_library_init(void) EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); #endif + #endif #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_cbc()); diff --git a/openssl/ssl/ssl_cert.c b/openssl/ssl/ssl_cert.c index 917be3187..5123a8918 100644 --- a/openssl/ssl/ssl_cert.c +++ b/openssl/ssl/ssl_cert.c @@ -164,14 +164,14 @@ static void ssl_cert_set_default_md(CERT *cert) { /* Set digest values to defaults */ #ifndef OPENSSL_NO_DSA - cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_dss1(); + cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); #endif #ifndef OPENSSL_NO_RSA cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); #endif #ifndef OPENSSL_NO_ECDSA - cert->pkeys[SSL_PKEY_ECC].digest = EVP_ecdsa(); + cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); #endif } diff --git a/openssl/ssl/ssl_ciph.c b/openssl/ssl/ssl_ciph.c index 92d1e94d6..0aba8e048 100644 --- a/openssl/ssl/ssl_ciph.c +++ b/openssl/ssl/ssl_ciph.c @@ -312,6 +312,7 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0}, {0,SSL_TXT_SSLV3,0, 0,0,0,0,SSL_SSLV3, 0,0,0,0}, {0,SSL_TXT_TLSV1,0, 0,0,0,0,SSL_TLSV1, 0,0,0,0}, + {0,SSL_TXT_TLSV1_2,0, 0,0,0,0,SSL_TLSV1_2, 0,0,0,0}, /* export flag */ {0,SSL_TXT_EXP,0, 0,0,0,0,0,SSL_EXPORT,0,0,0}, @@ -1150,9 +1151,9 @@ static int ssl_cipher_process_rulestr(const char *rule_str, while ( ((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || - (ch == '-')) + (ch == '-') || (ch == '.')) #else - while ( isalnum(ch) || (ch == '-')) + while ( isalnum(ch) || (ch == '-') || (ch == '.')) #endif { ch = *(++l); diff --git a/openssl/ssl/ssl_err.c b/openssl/ssl/ssl_err.c index 2577c6895..370fb57e3 100644 --- a/openssl/ssl/ssl_err.c +++ b/openssl/ssl/ssl_err.c @@ -228,6 +228,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "SSL_GET_NEW_SESSION"}, {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"}, {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, +{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"}, {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"}, {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"}, {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, diff --git a/openssl/ssl/ssl_lib.c b/openssl/ssl/ssl_lib.c index f82d071d6..14d143da0 100644 --- a/openssl/ssl/ssl_lib.c +++ b/openssl/ssl/ssl_lib.c @@ -597,8 +597,10 @@ void SSL_free(SSL *s) OPENSSL_free(s->next_proto_negotiated); #endif +#ifndef OPENSSL_NO_SRTP if (s->srtp_profiles) sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); +#endif OPENSSL_free(s); } @@ -1952,8 +1954,10 @@ void SSL_CTX_free(SSL_CTX *a) a->comp_methods = NULL; #endif +#ifndef OPENSSL_NO_SRTP if (a->srtp_profiles) sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); +#endif #ifndef OPENSSL_NO_PSK if (a->psk_identity_hint) @@ -2287,7 +2291,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) #endif /* THIS NEEDS CLEANING UP */ -X509 *ssl_get_server_send_cert(SSL *s) +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) { unsigned long alg_k,alg_a; CERT *c; @@ -2342,12 +2346,20 @@ X509 *ssl_get_server_send_cert(SSL *s) i=SSL_PKEY_GOST01; else /* if (alg_a & SSL_aNULL) */ { - SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR); + SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR); return(NULL); } - if (c->pkeys[i].x509 == NULL) return(NULL); - return(c->pkeys[i].x509); + return c->pkeys + i; + } + +X509 *ssl_get_server_send_cert(const SSL *s) + { + CERT_PKEY *cpk; + cpk = ssl_get_server_send_pkey(s); + if (!cpk) + return NULL; + return cpk->x509; } EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd) @@ -2608,7 +2620,7 @@ const char *SSL_get_version(const SSL *s) return("TLSv1.2"); else if (s->version == TLS1_1_VERSION) return("TLSv1.1"); - if (s->version == TLS1_VERSION) + else if (s->version == TLS1_VERSION) return("TLSv1"); else if (s->version == SSL3_VERSION) return("SSLv3"); @@ -2780,7 +2792,9 @@ void ssl_clear_cipher_ctx(SSL *s) /* Fix this function so that it takes an optional type parameter */ X509 *SSL_get_certificate(const SSL *s) { - if (s->cert != NULL) + if (s->server) + return(ssl_get_server_send_cert(s)); + else if (s->cert != NULL) return(s->cert->key->x509); else return(NULL); diff --git a/openssl/ssl/ssl_locl.h b/openssl/ssl/ssl_locl.h index d87fd51cf..1b98947e6 100644 --- a/openssl/ssl/ssl_locl.h +++ b/openssl/ssl/ssl_locl.h @@ -215,6 +215,15 @@ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ *((c)++)=(unsigned char)(((l) )&0xff)) +#define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + #define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ l|=((BN_ULLONG)(*((c)++)))<<32, \ l|=((BN_ULLONG)(*((c)++)))<<24, \ @@ -830,7 +839,8 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk); int ssl_undefined_function(SSL *s); int ssl_undefined_void_function(void); int ssl_undefined_const_function(const SSL *s); -X509 *ssl_get_server_send_cert(SSL *); +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); +X509 *ssl_get_server_send_cert(const SSL *); EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd); int ssl_cert_type(X509 *x,EVP_PKEY *pkey); void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); @@ -1088,7 +1098,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al); int ssl_prepare_clienthello_tlsext(SSL *s); int ssl_prepare_serverhello_tlsext(SSL *s); -int ssl_check_clienthello_tlsext(SSL *s); +int ssl_check_clienthello_tlsext_early(SSL *s); +int ssl_check_clienthello_tlsext_late(SSL *s); int ssl_check_serverhello_tlsext(SSL *s); #ifndef OPENSSL_NO_HEARTBEATS @@ -1131,4 +1142,33 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen); int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al); +/* s3_cbc.c */ +void ssl3_cbc_copy_mac(unsigned char* out, + const SSL3_RECORD *rec, + unsigned md_size,unsigned orig_len); +int ssl3_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size); +int tls1_cbc_remove_padding(const SSL* s, + SSL3_RECORD *rec, + unsigned block_size, + unsigned mac_size); +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +void ssl3_cbc_digest_record( + const EVP_MD_CTX *ctx, + unsigned char* md_out, + size_t* md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, + char is_sslv3); + +void tls_fips_digest_extra( + const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx, + const unsigned char *data, size_t data_len, size_t orig_len); + #endif diff --git a/openssl/ssl/ssl_rsa.c b/openssl/ssl/ssl_rsa.c index c0960b571..60e7b6685 100644 --- a/openssl/ssl/ssl_rsa.c +++ b/openssl/ssl/ssl_rsa.c @@ -710,7 +710,7 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ - in=BIO_new(BIO_s_file_internal()); + in = BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB); @@ -723,14 +723,16 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) goto end; } - x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); + x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); if (x == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB); goto end; } - ret=SSL_CTX_use_certificate(ctx,x); + ret = SSL_CTX_use_certificate(ctx, x); + if (ERR_peek_error() != 0) ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ if (ret) @@ -742,13 +744,15 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) int r; unsigned long err; - if (ctx->extra_certs != NULL) + if (ctx->extra_certs != NULL) { sk_X509_pop_free(ctx->extra_certs, X509_free); ctx->extra_certs = NULL; } - while ((ca = PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata)) + while ((ca = PEM_read_bio_X509(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata)) != NULL) { r = SSL_CTX_add_extra_chain_cert(ctx, ca); diff --git a/openssl/ssl/ssltest.c b/openssl/ssl/ssltest.c index 0f8fd3902..316bbb0c9 100644 --- a/openssl/ssl/ssltest.c +++ b/openssl/ssl/ssltest.c @@ -543,8 +543,8 @@ int main(int argc, char *argv[]) int comp = 0; #ifndef OPENSSL_NO_COMP COMP_METHOD *cm = NULL; -#endif STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; +#endif int test_cipherlist = 0; #ifdef OPENSSL_FIPS int fips_mode=0; diff --git a/openssl/ssl/t1_enc.c b/openssl/ssl/t1_enc.c index f7bdeb3b9..809ad2ee1 100644 --- a/openssl/ssl/t1_enc.c +++ b/openssl/ssl/t1_enc.c @@ -361,7 +361,7 @@ int tls1_change_cipher_state(SSL *s, int which) { int i; for (i=0; i<s->s3->tmp.key_block_length; i++) - printf("%02x", key_block[i]); printf("\n"); + printf("%02x", s->s3->tmp.key_block[i]); printf("\n"); } #endif /* KSSL_DEBUG */ @@ -667,12 +667,21 @@ err: return(ret); } +/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. + */ int tls1_enc(SSL *s, int send) { SSL3_RECORD *rec; EVP_CIPHER_CTX *ds; unsigned long l; - int bs,i,ii,j,k,pad=0; + int bs,i,j,k,pad=0,ret,mac_size=0; const EVP_CIPHER *enc; if (send) @@ -729,11 +738,11 @@ int tls1_enc(SSL *s, int send) printf("tls1_enc(%d)\n", send); #endif /* KSSL_DEBUG */ - if ((s->session == NULL) || (ds == NULL) || - (enc == NULL)) + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { memmove(rec->data,rec->input,rec->length); rec->input=rec->data; + ret = 1; } else { @@ -797,13 +806,13 @@ int tls1_enc(SSL *s, int send) #ifdef KSSL_DEBUG { - unsigned long ui; + unsigned long ui; printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - ds,rec->data,rec->input,l); + ds,rec->data,rec->input,l); printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", - ds->buf_len, ds->cipher->key_len, - DES_KEY_SZ, DES_SCHEDULE_SZ, - ds->cipher->iv_len); + ds->buf_len, ds->cipher->key_len, + DES_KEY_SZ, DES_SCHEDULE_SZ, + ds->cipher->iv_len); printf("\t\tIV: "); for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); printf("\n"); @@ -816,13 +825,7 @@ int tls1_enc(SSL *s, int send) if (!send) { if (l == 0 || l%bs != 0) - { - if (s->version >= TLS1_1_VERSION) - return -1; - SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); return 0; - } } i = EVP_Cipher(ds,rec->data,rec->input,l); @@ -839,68 +842,24 @@ int tls1_enc(SSL *s, int send) #ifdef KSSL_DEBUG { - unsigned long i; - printf("\trec->data="); + unsigned long i; + printf("\trec->data="); for (i=0; i<l; i++) - printf(" %02x", rec->data[i]); printf("\n"); - } + printf(" %02x", rec->data[i]); printf("\n"); + } #endif /* KSSL_DEBUG */ + ret = 1; + if (EVP_MD_CTX_md(s->read_hash) != NULL) + mac_size = EVP_MD_CTX_size(s->read_hash); if ((bs != 1) && !send) - { - ii=i=rec->data[l-1]; /* padding_length */ - i++; - /* NB: if compression is in operation the first packet - * may not be of even length so the padding bug check - * cannot be performed. This bug workaround has been - * around since SSLeay so hopefully it is either fixed - * now or no buggy implementation supports compression - * [steve] - */ - if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) - && !s->expand) - { - /* First packet is even in size, so check */ - if ((memcmp(s->s3->read_sequence, - "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) - s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - i--; - } - /* TLS 1.0 does not bound the number of padding bytes by the block size. - * All of them must have value 'padding_length'. */ - if (i > (int)rec->length) - { - /* Incorrect padding. SSLerr() and ssl3_alert are done - * by caller: we don't want to reveal whether this is - * a decryption error or a MAC verification failure - * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ - return -1; - } - for (j=(int)(l-i); j<(int)l; j++) - { - if (rec->data[j] != ii) - { - /* Incorrect padding */ - return -1; - } - } - rec->length -=i; - if (s->version >= TLS1_1_VERSION - && EVP_CIPHER_CTX_mode(ds) == EVP_CIPH_CBC_MODE) - { - if (bs > (int)rec->length) - return -1; - rec->data += bs; /* skip the explicit IV */ - rec->input += bs; - rec->length -= bs; - } - } + ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); if (pad && !send) rec->length -= pad; } - return(1); + return ret; } + int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) { unsigned int ret; @@ -990,10 +949,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) SSL3_RECORD *rec; unsigned char *seq; EVP_MD_CTX *hash; - size_t md_size; + size_t md_size, orig_len; int i; EVP_MD_CTX hmac, *mac_ctx; - unsigned char buf[5]; + unsigned char header[13]; int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM)); int t; @@ -1014,12 +973,6 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) OPENSSL_assert(t >= 0); md_size=t; - buf[0]=rec->type; - buf[1]=(unsigned char)(ssl->version>>8); - buf[2]=(unsigned char)(ssl->version); - buf[3]=rec->length>>8; - buf[4]=rec->length&0xff; - /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ if (stream_mac) { @@ -1038,17 +991,55 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); memcpy (p,&seq[2],6); - EVP_DigestSignUpdate(mac_ctx,dtlsseq,8); + memcpy(header, dtlsseq, 8); } else - EVP_DigestSignUpdate(mac_ctx,seq,8); + memcpy(header, seq, 8); - EVP_DigestSignUpdate(mac_ctx,buf,5); - EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); - t=EVP_DigestSignFinal(mac_ctx,md,&md_size); - OPENSSL_assert(t > 0); + /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */ + orig_len = rec->length+md_size+((unsigned int)rec->type>>8); + rec->type &= 0xff; + + header[8]=rec->type; + header[9]=(unsigned char)(ssl->version>>8); + header[10]=(unsigned char)(ssl->version); + header[11]=(rec->length)>>8; + header[12]=(rec->length)&0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(mac_ctx)) + { + /* This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of + * data we are hashing because that gives an attacker a + * timing-oracle. */ + ssl3_cbc_digest_record( + mac_ctx, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + ssl->s3->read_mac_secret, + ssl->s3->read_mac_secret_size, + 0 /* not SSLv3 */); + } + else + { + EVP_DigestSignUpdate(mac_ctx,header,sizeof(header)); + EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); + t=EVP_DigestSignFinal(mac_ctx,md,&md_size); + OPENSSL_assert(t > 0); +#ifdef OPENSSL_FIPS + if (!send && FIPS_mode()) + tls_fips_digest_extra( + ssl->enc_read_ctx, + mac_ctx, rec->input, + rec->length, orig_len); +#endif + } - if (!stream_mac) EVP_MD_CTX_cleanup(&hmac); + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); #ifdef TLS_DEBUG printf("sec="); {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); } diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c index 27c8e3460..e08088c57 100644 --- a/openssl/ssl/t1_lib.c +++ b/openssl/ssl/t1_lib.c @@ -649,6 +649,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha } #endif +#ifndef OPENSSL_NO_SRTP if(SSL_get_srtp_profiles(s)) { int el; @@ -667,6 +668,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha } ret += el; } +#endif if ((extdatalen = ret-p-2)== 0) return p; @@ -781,6 +783,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha } #endif +#ifndef OPENSSL_NO_SRTP if(s->srtp_profile) { int el; @@ -799,6 +802,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha } ret+=el; } +#endif if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) @@ -1077,7 +1081,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in int ellipticcurvelist_length = (*(sdata++) << 8); ellipticcurvelist_length += (*(sdata++)); - if (ellipticcurvelist_length != size - 2) + if (ellipticcurvelist_length != size - 2 || + ellipticcurvelist_length < 1) { *al = TLS1_AD_DECODE_ERROR; return 0; @@ -1328,12 +1333,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in #endif /* session ticket processed earlier */ +#ifndef OPENSSL_NO_SRTP else if (type == TLSEXT_TYPE_use_srtp) - { + { if(ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) return 0; - } + } +#endif data+=size; } @@ -1433,7 +1440,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in unsigned char *sdata = data; int ecpointformatlist_length = *(sdata++); - if (ecpointformatlist_length != size - 1) + if (ecpointformatlist_length != size - 1 || + ecpointformatlist_length < 1) { *al = TLS1_AD_DECODE_ERROR; return 0; @@ -1527,7 +1535,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in unsigned char selected_len; /* We must have requested it. */ - if ((s->ctx->next_proto_select_cb == NULL)) + if (s->ctx->next_proto_select_cb == NULL) { *al = TLS1_AD_UNSUPPORTED_EXTENSION; return 0; @@ -1577,12 +1585,14 @@ 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) - { + { if(ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) return 0; - } + } +#endif data+=size; } @@ -1763,7 +1773,7 @@ int ssl_prepare_serverhello_tlsext(SSL *s) return 1; } -int ssl_check_clienthello_tlsext(SSL *s) +int ssl_check_clienthello_tlsext_early(SSL *s) { int ret=SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; @@ -1782,42 +1792,12 @@ int ssl_check_clienthello_tlsext(SSL *s) else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); - /* If status request then ask callback what to do. - * Note: this must be called after servername callbacks in case - * the certificate has changed. - */ - if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) - { - int r; - r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - switch (r) - { - /* We don't want to send a status request response */ - case SSL_TLSEXT_ERR_NOACK: - s->tlsext_status_expected = 0; - break; - /* status request response should be sent */ - case SSL_TLSEXT_ERR_OK: - if (s->tlsext_ocsp_resp) - s->tlsext_status_expected = 1; - else - s->tlsext_status_expected = 0; - break; - /* something bad happened */ - case SSL_TLSEXT_ERR_ALERT_FATAL: - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - } - else - s->tlsext_status_expected = 0; - #ifdef TLSEXT_TYPE_opaque_prf_input { /* This sort of belongs into ssl_prepare_serverhello_tlsext(), * but we might be sending an alert in response to the client hello, - * so this has to happen here in ssl_check_clienthello_tlsext(). */ + * so this has to happen here in + * ssl_check_clienthello_tlsext_early(). */ int r = 1; @@ -1869,8 +1849,8 @@ int ssl_check_clienthello_tlsext(SSL *s) } } -#endif err: +#endif switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: @@ -1888,6 +1868,71 @@ int ssl_check_clienthello_tlsext(SSL *s) } } +int ssl_check_clienthello_tlsext_late(SSL *s) + { + int ret = SSL_TLSEXT_ERR_OK; + int al; + + /* If status request then ask callback what to do. + * Note: this must be called after servername callbacks in case + * the certificate has changed, and must be called after the cipher + * has been chosen because this may influence which certificate is sent + */ + if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) + { + int r; + CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey == NULL) + { + s->tlsext_status_expected = 0; + return 1; + } + /* Set current certificate to one we will use so + * SSL_get_certificate et al can pick it up. + */ + s->cert->key = certpkey; + r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + switch (r) + { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: + s->tlsext_status_expected = 0; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + else + s->tlsext_status_expected = 0; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + else + s->tlsext_status_expected = 0; + + err: + switch (ret) + { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s,SSL3_AL_FATAL,al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s,SSL3_AL_WARNING,al); + return 1; + + default: + return 1; + } + } + int ssl_check_serverhello_tlsext(SSL *s) { int ret=SSL_TLSEXT_ERR_NOACK; @@ -2189,7 +2234,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, HMAC_Update(&hctx, etick, eticklen); HMAC_Final(&hctx, tick_hmac, NULL); HMAC_CTX_cleanup(&hctx); - if (memcmp(tick_hmac, etick + eticklen, mlen)) + if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) return 2; /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ @@ -2414,7 +2459,7 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) */ #ifndef OPENSSL_NO_DSA if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) - c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_dss1(); + c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); #endif #ifndef OPENSSL_NO_RSA if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) @@ -2425,7 +2470,7 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) #endif #ifndef OPENSSL_NO_ECDSA if (!c->pkeys[SSL_PKEY_ECC].digest) - c->pkeys[SSL_PKEY_ECC].digest = EVP_ecdsa(); + c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); #endif return 1; } diff --git a/openssl/ssl/tls_srp.c b/openssl/ssl/tls_srp.c index 8512c4daf..2315a7c0a 100644 --- a/openssl/ssl/tls_srp.c +++ b/openssl/ssl/tls_srp.c @@ -242,7 +242,8 @@ int SSL_srp_server_param_with_username(SSL *s, int *ad) (s->srp_ctx.v == NULL)) return SSL3_AL_FATAL; - RAND_bytes(b, sizeof(b)); + if (RAND_bytes(b, sizeof(b)) <= 0) + return SSL3_AL_FATAL; s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL); OPENSSL_cleanse(b,sizeof(b)); |