Everything is an AEAD now. Change-Id: Ib47638e128843fc8299c3dbf9bd60c01eb5afa16 Reviewed-on: https://boringssl-review.googlesource.com/2700 Reviewed-by: Adam Langley <agl@google.com>kris/onging/CECPQ3_patch15
@@ -1259,19 +1259,8 @@ struct ssl_st | |||||
struct ssl_cipher_preference_list_st *cipher_list; | struct ssl_cipher_preference_list_st *cipher_list; | ||||
STACK_OF(SSL_CIPHER) *cipher_list_by_id; | STACK_OF(SSL_CIPHER) *cipher_list_by_id; | ||||
/* These are the ones being used, the ones in SSL_SESSION are | |||||
* the ones to be 'copied' into these ones */ | |||||
SSL_AEAD_CTX *aead_read_ctx; /* AEAD context. If non-NULL, then | |||||
|enc_read_ctx| and |read_hash| are | |||||
ignored. */ | |||||
EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ | |||||
EVP_MD_CTX *read_hash; /* used for mac generation */ | |||||
SSL_AEAD_CTX *aead_write_ctx; /* AEAD context. If non-NULL, then | |||||
|enc_write_ctx| and |write_hash| are | |||||
ignored. */ | |||||
EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ | |||||
EVP_MD_CTX *write_hash; /* used for mac generation */ | |||||
SSL_AEAD_CTX *aead_read_ctx; | |||||
SSL_AEAD_CTX *aead_write_ctx; | |||||
/* session info */ | /* session info */ | ||||
@@ -464,10 +464,7 @@ typedef struct ssl3_state_st | |||||
int key_block_length; | int key_block_length; | ||||
unsigned char *key_block; | unsigned char *key_block; | ||||
const EVP_CIPHER *new_sym_enc; | |||||
const EVP_AEAD *new_aead; | const EVP_AEAD *new_aead; | ||||
const EVP_MD *new_hash; | |||||
int new_mac_pkey_type; | |||||
uint8_t new_mac_secret_len; | uint8_t new_mac_secret_len; | ||||
uint8_t new_fixed_iv_len; | uint8_t new_fixed_iv_len; | ||||
uint8_t new_variable_iv_len; | uint8_t new_variable_iv_len; | ||||
@@ -14,7 +14,6 @@ add_library( | |||||
d1_srtp.c | d1_srtp.c | ||||
d1_srvr.c | d1_srvr.c | ||||
s3_both.c | s3_both.c | ||||
s3_cbc.c | |||||
s3_clnt.c | s3_clnt.c | ||||
s3_enc.c | s3_enc.c | ||||
s3_lib.c | s3_lib.c | ||||
@@ -78,7 +78,6 @@ static int dtls1_handshake_write(SSL *s); | |||||
const SSL3_ENC_METHOD DTLSv1_enc_data = { | const SSL3_ENC_METHOD DTLSv1_enc_data = { | ||||
tls1_enc, | tls1_enc, | ||||
tls1_mac, | |||||
tls1_prf, | tls1_prf, | ||||
tls1_setup_key_block, | tls1_setup_key_block, | ||||
tls1_generate_master_secret, | tls1_generate_master_secret, | ||||
@@ -98,7 +97,6 @@ const SSL3_ENC_METHOD DTLSv1_enc_data = { | |||||
const SSL3_ENC_METHOD DTLSv1_2_enc_data = { | const SSL3_ENC_METHOD DTLSv1_2_enc_data = { | ||||
tls1_enc, | tls1_enc, | ||||
tls1_mac, | |||||
tls1_prf, | tls1_prf, | ||||
tls1_setup_key_block, | tls1_setup_key_block, | ||||
tls1_generate_master_secret, | tls1_generate_master_secret, | ||||
@@ -328,15 +328,11 @@ static int dtls1_process_buffered_records(SSL *s) { | |||||
} | } | ||||
static int dtls1_process_record(SSL *s) { | static int dtls1_process_record(SSL *s) { | ||||
int i, al; | |||||
int al; | |||||
int enc_err; | int enc_err; | ||||
SSL_SESSION *sess; | |||||
SSL3_RECORD *rr; | SSL3_RECORD *rr; | ||||
unsigned int mac_size, orig_len; | |||||
unsigned char md[EVP_MAX_MD_SIZE]; | |||||
rr = &(s->s3->rrec); | rr = &(s->s3->rrec); | ||||
sess = s->session; | |||||
/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, and | /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, and | ||||
* we have that many bytes in s->packet. */ | * we have that many bytes in s->packet. */ | ||||
@@ -372,55 +368,6 @@ static int dtls1_process_record(SSL *s) { | |||||
s->packet_length = 0; | s->packet_length = 0; | ||||
goto err; | goto err; | ||||
} | } | ||||
/* 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)) { | |||||
/* s->read_hash != NULL => mac_size != -1 */ | |||||
uint8_t *mac = NULL; | |||||
uint8_t mac_tmp[EVP_MAX_MD_SIZE]; | |||||
mac_size = EVP_MD_CTX_size(s->read_hash); | |||||
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)) { | |||||
al = SSL_AD_DECODE_ERROR; | |||||
OPENSSL_PUT_ERROR(SSL, dtls1_process_record, SSL_R_LENGTH_TOO_SHORT); | |||||
goto f_err; | |||||
} | |||||
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; | |||||
} else { | |||||
/* 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->enc_method->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 (enc_err < 0) { | if (enc_err < 0) { | ||||
/* decryption failed, silently discard message */ | /* decryption failed, silently discard message */ | ||||
rr->length = 0; | rr->length = 0; | ||||
@@ -761,7 +708,9 @@ start: | |||||
/* make sure that we are not getting application data when we | /* make sure that we are not getting application data when we | ||||
* are doing a handshake for the first time */ | * are doing a handshake for the first time */ | ||||
if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && | if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && | ||||
(s->enc_read_ctx == NULL)) { | |||||
(s->aead_read_ctx == NULL)) { | |||||
/* TODO(davidben): Is this check redundant with the handshake_func | |||||
* check? */ | |||||
al = SSL_AD_UNEXPECTED_MESSAGE; | al = SSL_AD_UNEXPECTED_MESSAGE; | ||||
OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE); | OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE); | ||||
goto f_err; | goto f_err; | ||||
@@ -1151,12 +1100,11 @@ int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) { | |||||
static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, | static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, | ||||
unsigned int len) { | unsigned int len) { | ||||
uint8_t *p, *pseq; | uint8_t *p, *pseq; | ||||
int i, mac_size = 0; | |||||
int i; | |||||
int prefix_len = 0; | int prefix_len = 0; | ||||
int eivlen = 0; | int eivlen = 0; | ||||
SSL3_RECORD *wr; | SSL3_RECORD *wr; | ||||
SSL3_BUFFER *wb; | SSL3_BUFFER *wb; | ||||
SSL_SESSION *sess; | |||||
/* first check if there is a SSL3_BUFFER still being written | /* first check if there is a SSL3_BUFFER still being written | ||||
* out. This will happen with non blocking IO */ | * out. This will happen with non blocking IO */ | ||||
@@ -1180,15 +1128,6 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, | |||||
wr = &(s->s3->wrec); | wr = &(s->s3->wrec); | ||||
wb = &(s->s3->wbuf); | wb = &(s->s3->wbuf); | ||||
sess = s->session; | |||||
if (sess != NULL && s->enc_write_ctx != NULL && | |||||
EVP_MD_CTX_md(s->write_hash) != NULL) { | |||||
mac_size = EVP_MD_CTX_size(s->write_hash); | |||||
if (mac_size < 0) { | |||||
goto err; | |||||
} | |||||
} | |||||
p = wb->buf + prefix_len; | p = wb->buf + prefix_len; | ||||
@@ -1212,15 +1151,9 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, | |||||
pseq = p; | pseq = p; | ||||
p += 10; | p += 10; | ||||
/* Explicit IV length, block ciphers appropriate version flag */ | |||||
if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && | |||||
EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE) { | |||||
eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); | |||||
if (eivlen <= 1) { | |||||
eivlen = 0; | |||||
} | |||||
} else if (s->aead_write_ctx != NULL && | |||||
s->aead_write_ctx->variable_nonce_included_in_record) { | |||||
/* Leave room for the variable nonce for AEADs which specify it explicitly. */ | |||||
if (s->aead_write_ctx != NULL && | |||||
s->aead_write_ctx->variable_nonce_included_in_record) { | |||||
eivlen = s->aead_write_ctx->variable_nonce_len; | eivlen = s->aead_write_ctx->variable_nonce_len; | ||||
} | } | ||||
@@ -1233,15 +1166,6 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf, | |||||
memcpy(wr->data, wr->input, wr->length); | memcpy(wr->data, wr->input, wr->length); | ||||
wr->input = wr->data; | wr->input = wr->data; | ||||
/* we should still have the output to wr->data and the input from wr->input. | |||||
* Length should be wr->length. wr->data still points in the wb->buf */ | |||||
if (mac_size != 0) { | |||||
if (s->enc_method->mac(s, &(p[wr->length + eivlen]), 1) < 0) { | |||||
goto err; | |||||
} | |||||
wr->length += mac_size; | |||||
} | |||||
/* this is true regardless of mac size */ | /* this is true regardless of mac size */ | ||||
wr->input = p; | wr->input = p; | ||||
wr->data = p; | wr->data = p; | ||||
@@ -1,601 +0,0 @@ | |||||
/* ==================================================================== | |||||
* 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 <assert.h> | |||||
#include <openssl/obj.h> | |||||
#include <openssl/sha.h> | |||||
#include "../crypto/internal.h" | |||||
#include "ssl_locl.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 | |||||
/* 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 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 | |||||
* -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 (SSL_USE_EXPLICIT_IV(s)) { | |||||
/* 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]; | |||||
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 = 256; /* maximum amount of padding, inc length byte. */ | |||||
if (to_check > rec->length) { | |||||
to_check = rec->length; | |||||
} | |||||
for (i = 0; i < to_check; 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. */ | |||||
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. */ | |||||
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 constant_time_select_int(good, 1, -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; | |||||
assert(orig_len >= md_size); | |||||
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_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); | |||||
} | |||||
/* 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_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 | |||||
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 | |||||
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 | |||||
/* 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) { | |||||
switch (EVP_MD_CTX_type(ctx)) { | |||||
case NID_sha1: | |||||
case NID_sha256: | |||||
case NID_sha384: | |||||
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: 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. ) */ | |||||
int 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; | |||||
/* This is a, hopefully redundant, check that allows us to forget about | |||||
* many possible overflows later in this function. */ | |||||
assert(data_plus_mac_plus_padding_size < 1024 * 1024); | |||||
switch (EVP_MD_CTX_type(ctx)) { | |||||
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; | |||||
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; | |||||
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; | |||||
default: | |||||
/* ssl3_cbc_record_digest_supported should have been | |||||
* called first to check that the hash function is | |||||
* supported. */ | |||||
assert(0); | |||||
*md_out_size = 0; | |||||
return 0; | |||||
} | |||||
assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); | |||||
assert(md_block_size <= MAX_HASH_BLOCK_SIZE); | |||||
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); | |||||
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); | |||||
} | |||||
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; | |||||
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: 7 bytes (SHA1). */ | |||||
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_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 = 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. */ | |||||
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 = constant_time_select_8( | |||||
is_block_b, length_bytes[j - (md_block_size - md_length_size)], b); | |||||
} | |||||
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); | |||||
if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */)) { | |||||
EVP_MD_CTX_cleanup(&md_ctx); | |||||
return 0; | |||||
} | |||||
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); | |||||
*md_out_size = md_out_size_u; | |||||
EVP_MD_CTX_cleanup(&md_ctx); | |||||
return 1; | |||||
} |
@@ -558,7 +558,6 @@ const SSL_CIPHER ssl3_ciphers[] = { | |||||
const SSL3_ENC_METHOD SSLv3_enc_data = { | const SSL3_ENC_METHOD SSLv3_enc_data = { | ||||
tls1_enc, | tls1_enc, | ||||
tls1_mac, | |||||
ssl3_prf, | ssl3_prf, | ||||
tls1_setup_key_block, | tls1_setup_key_block, | ||||
tls1_generate_master_secret, | tls1_generate_master_secret, | ||||
@@ -270,16 +270,12 @@ static int ssl3_get_record(SSL *s) { | |||||
int ssl_major, ssl_minor, al; | int ssl_major, ssl_minor, al; | ||||
int enc_err, n, i, ret = -1; | int enc_err, n, i, ret = -1; | ||||
SSL3_RECORD *rr; | SSL3_RECORD *rr; | ||||
SSL_SESSION *sess; | |||||
uint8_t *p; | uint8_t *p; | ||||
uint8_t md[EVP_MAX_MD_SIZE]; | |||||
short version; | short version; | ||||
unsigned mac_size, orig_len; | |||||
size_t extra; | size_t extra; | ||||
unsigned empty_record_count = 0; | unsigned empty_record_count = 0; | ||||
rr = &s->s3->rrec; | rr = &s->s3->rrec; | ||||
sess = s->session; | |||||
if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { | if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { | ||||
extra = SSL3_RT_MAX_EXTRA; | extra = SSL3_RT_MAX_EXTRA; | ||||
@@ -387,55 +383,6 @@ again: | |||||
OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); | OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); | ||||
goto f_err; | goto f_err; | ||||
} | } | ||||
/* |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) { | |||||
/* s->read_hash != NULL => mac_size != -1 */ | |||||
uint8_t *mac = NULL; | |||||
uint8_t mac_tmp[EVP_MAX_MD_SIZE]; | |||||
mac_size = EVP_MD_CTX_size(s->read_hash); | |||||
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)) { | |||||
al = SSL_AD_DECODE_ERROR; | |||||
OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_LENGTH_TOO_SHORT); | |||||
goto f_err; | |||||
} | |||||
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; | |||||
} else { | |||||
/* 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->enc_method->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 (enc_err < 0) { | if (enc_err < 0) { | ||||
/* A separate 'decryption_failed' alert was introduced with TLS 1.0, SSL | /* A separate 'decryption_failed' alert was introduced with TLS 1.0, SSL | ||||
* 3.0 only has 'bad_record_mac'. But unless a decryption failure is | * 3.0 only has 'bad_record_mac'. But unless a decryption failure is | ||||
@@ -570,13 +517,12 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) { | |||||
static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len, | static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len, | ||||
char fragment, char is_fragment) { | char fragment, char is_fragment) { | ||||
uint8_t *p, *plen; | uint8_t *p, *plen; | ||||
int i, mac_size; | |||||
int i; | |||||
int prefix_len = 0; | int prefix_len = 0; | ||||
int eivlen = 0; | int eivlen = 0; | ||||
long align = 0; | long align = 0; | ||||
SSL3_RECORD *wr; | SSL3_RECORD *wr; | ||||
SSL3_BUFFER *wb = &(s->s3->wbuf); | SSL3_BUFFER *wb = &(s->s3->wbuf); | ||||
SSL_SESSION *sess; | |||||
/* first check if there is a SSL3_BUFFER still being written out. This will | /* first check if there is a SSL3_BUFFER still being written out. This will | ||||
* happen with non blocking IO */ | * happen with non blocking IO */ | ||||
@@ -602,17 +548,6 @@ static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len, | |||||
} | } | ||||
wr = &s->s3->wrec; | wr = &s->s3->wrec; | ||||
sess = s->session; | |||||
if (sess == NULL || s->enc_write_ctx == NULL || | |||||
EVP_MD_CTX_md(s->write_hash) == NULL) { | |||||
mac_size = 0; | |||||
} else { | |||||
mac_size = EVP_MD_CTX_size(s->write_hash); | |||||
if (mac_size < 0) { | |||||
goto err; | |||||
} | |||||
} | |||||
if (fragment) { | if (fragment) { | ||||
/* countermeasure against known-IV weakness in CBC ciphersuites (see | /* countermeasure against known-IV weakness in CBC ciphersuites (see | ||||
@@ -667,15 +602,9 @@ static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len, | |||||
plen = p; | plen = p; | ||||
p += 2; | p += 2; | ||||
/* Explicit IV length, block ciphers appropriate version flag */ | |||||
if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) && | |||||
EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE) { | |||||
eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); | |||||
if (eivlen <= 1) { | |||||
eivlen = 0; | |||||
} | |||||
} else if (s->aead_write_ctx != NULL && | |||||
s->aead_write_ctx->variable_nonce_included_in_record) { | |||||
/* Leave room for the variable nonce for AEADs which specify it explicitly. */ | |||||
if (s->aead_write_ctx != NULL && | |||||
s->aead_write_ctx->variable_nonce_included_in_record) { | |||||
eivlen = s->aead_write_ctx->variable_nonce_len; | eivlen = s->aead_write_ctx->variable_nonce_len; | ||||
} | } | ||||
@@ -692,13 +621,6 @@ static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len, | |||||
/* we should still have the output to wr->data and the input from wr->input. | /* we should still have the output to wr->data and the input from wr->input. | ||||
* Length should be wr->length. wr->data still points in the wb->buf */ | * Length should be wr->length. wr->data still points in the wb->buf */ | ||||
if (mac_size != 0) { | |||||
if (s->enc_method->mac(s, &(p[wr->length + eivlen]), 1) < 0) { | |||||
goto err; | |||||
} | |||||
wr->length += mac_size; | |||||
} | |||||
wr->input = p; | wr->input = p; | ||||
wr->data = p; | wr->data = p; | ||||
wr->length += eivlen; | wr->length += eivlen; | ||||
@@ -930,7 +852,9 @@ start: | |||||
/* make sure that we are not getting application data when we are doing a | /* make sure that we are not getting application data when we are doing a | ||||
* handshake for the first time */ | * handshake for the first time */ | ||||
if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && | if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA && | ||||
s->enc_read_ctx == NULL) { | |||||
s->aead_read_ctx == NULL) { | |||||
/* TODO(davidben): Is this check redundant with the handshake_func | |||||
* check? */ | |||||
al = SSL_AD_UNEXPECTED_MESSAGE; | al = SSL_AD_UNEXPECTED_MESSAGE; | ||||
OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE); | OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE); | ||||
goto f_err; | goto f_err; | ||||
@@ -360,111 +360,6 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, | |||||
} | } | ||||
} | } | ||||
int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, | |||||
const EVP_MD **md, int *mac_pkey_type, | |||||
size_t *mac_secret_size) { | |||||
const SSL_CIPHER *c; | |||||
c = s->cipher; | |||||
if (c == NULL || | |||||
/* This function doesn't deal with EVP_AEAD. See | |||||
* |ssl_cipher_get_aead_evp|. */ | |||||
(c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) || | |||||
enc == NULL || | |||||
md == NULL) { | |||||
return 0; | |||||
} | |||||
switch (c->algorithm_enc) { | |||||
case SSL_3DES: | |||||
*enc = EVP_des_ede3_cbc(); | |||||
break; | |||||
case SSL_RC4: | |||||
*enc = EVP_rc4(); | |||||
break; | |||||
case SSL_AES128: | |||||
*enc = EVP_aes_128_cbc(); | |||||
break; | |||||
case SSL_AES256: | |||||
*enc = EVP_aes_256_cbc(); | |||||
break; | |||||
default: | |||||
return 0; | |||||
} | |||||
if (!ssl_cipher_get_mac(s, md, mac_pkey_type, mac_secret_size)) { | |||||
return 0; | |||||
} | |||||
assert(*enc != NULL && *md != NULL); | |||||
/* TODO(fork): enable the stitched cipher modes. */ | |||||
#if 0 | |||||
if (s->ssl_version>>8 != TLS1_VERSION_MAJOR || | |||||
s->ssl_version < TLS1_VERSION) | |||||
return 1; | |||||
if (c->algorithm_enc == SSL_RC4 && | |||||
c->algorithm_mac == SSL_MD5 && | |||||
(evp=EVP_get_cipherbyname("RC4-HMAC-MD5"))) | |||||
*enc = evp, *md = NULL; | |||||
else if (c->algorithm_enc == SSL_AES128 && | |||||
c->algorithm_mac == SSL_SHA1 && | |||||
(evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) | |||||
*enc = evp, *md = NULL; | |||||
else if (c->algorithm_enc == SSL_AES256 && | |||||
c->algorithm_mac == SSL_SHA1 && | |||||
(evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) | |||||
*enc = evp, *md = NULL; | |||||
#endif | |||||
return 1; | |||||
} | |||||
int ssl_cipher_get_mac(const SSL_SESSION *s, const EVP_MD **md, | |||||
int *mac_pkey_type, size_t *mac_secret_size) { | |||||
const SSL_CIPHER *c; | |||||
c = s->cipher; | |||||
if (c == NULL) { | |||||
return 0; | |||||
} | |||||
switch (c->algorithm_mac) { | |||||
case SSL_MD5: | |||||
*md = EVP_md5(); | |||||
break; | |||||
case SSL_SHA1: | |||||
*md = EVP_sha1(); | |||||
break; | |||||
case SSL_SHA256: | |||||
*md = EVP_sha256(); | |||||
break; | |||||
case SSL_SHA384: | |||||
*md = EVP_sha384(); | |||||
break; | |||||
default: | |||||
return 0; | |||||
} | |||||
if (mac_pkey_type != NULL) { | |||||
*mac_pkey_type = EVP_PKEY_HMAC; | |||||
} | |||||
if (mac_secret_size != NULL) { | |||||
*mac_secret_size = EVP_MD_size(*md); | |||||
} | |||||
return 1; | |||||
} | |||||
int ssl_get_handshake_digest(size_t idx, long *mask, const EVP_MD **md) { | int ssl_get_handshake_digest(size_t idx, long *mask, const EVP_MD **md) { | ||||
if (idx >= SSL_MAX_DIGEST) { | if (idx >= SSL_MAX_DIGEST) { | ||||
return 0; | return 0; | ||||
@@ -208,8 +208,6 @@ int SSL_clear(SSL *s) { | |||||
s->packet_length = 0; | s->packet_length = 0; | ||||
ssl_clear_cipher_ctx(s); | ssl_clear_cipher_ctx(s); | ||||
ssl_clear_hash_ctx(&s->read_hash); | |||||
ssl_clear_hash_ctx(&s->write_hash); | |||||
if (s->next_proto_negotiated) { | if (s->next_proto_negotiated) { | ||||
OPENSSL_free(s->next_proto_negotiated); | OPENSSL_free(s->next_proto_negotiated); | ||||
@@ -607,8 +605,6 @@ void SSL_free(SSL *s) { | |||||
} | } | ||||
ssl_clear_cipher_ctx(s); | ssl_clear_cipher_ctx(s); | ||||
ssl_clear_hash_ctx(&s->read_hash); | |||||
ssl_clear_hash_ctx(&s->write_hash); | |||||
if (s->cert != NULL) { | if (s->cert != NULL) { | ||||
ssl_cert_free(s->cert); | ssl_cert_free(s->cert); | ||||
@@ -2365,8 +2361,6 @@ void SSL_set_accept_state(SSL *s) { | |||||
s->handshake_func = s->method->ssl_accept; | s->handshake_func = s->method->ssl_accept; | ||||
/* clear the current cipher */ | /* clear the current cipher */ | ||||
ssl_clear_cipher_ctx(s); | ssl_clear_cipher_ctx(s); | ||||
ssl_clear_hash_ctx(&s->read_hash); | |||||
ssl_clear_hash_ctx(&s->write_hash); | |||||
} | } | ||||
void SSL_set_connect_state(SSL *s) { | void SSL_set_connect_state(SSL *s) { | ||||
@@ -2376,8 +2370,6 @@ void SSL_set_connect_state(SSL *s) { | |||||
s->handshake_func = s->method->ssl_connect; | s->handshake_func = s->method->ssl_connect; | ||||
/* clear the current cipher */ | /* clear the current cipher */ | ||||
ssl_clear_cipher_ctx(s); | ssl_clear_cipher_ctx(s); | ||||
ssl_clear_hash_ctx(&s->read_hash); | |||||
ssl_clear_hash_ctx(&s->write_hash); | |||||
} | } | ||||
int ssl_undefined_function(SSL *s) { | int ssl_undefined_function(SSL *s) { | ||||
@@ -2426,18 +2418,6 @@ const char *SSL_SESSION_get_version(const SSL_SESSION *sess) { | |||||
} | } | ||||
void ssl_clear_cipher_ctx(SSL *s) { | void ssl_clear_cipher_ctx(SSL *s) { | ||||
if (s->enc_read_ctx != NULL) { | |||||
EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); | |||||
OPENSSL_free(s->enc_read_ctx); | |||||
s->enc_read_ctx = NULL; | |||||
} | |||||
if (s->enc_write_ctx != NULL) { | |||||
EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); | |||||
OPENSSL_free(s->enc_write_ctx); | |||||
s->enc_write_ctx = NULL; | |||||
} | |||||
if (s->aead_read_ctx != NULL) { | if (s->aead_read_ctx != NULL) { | ||||
EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx); | EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx); | ||||
OPENSSL_free(s->aead_read_ctx); | OPENSSL_free(s->aead_read_ctx); | ||||
@@ -3186,27 +3166,6 @@ uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) { | |||||
return version; | return version; | ||||
} | } | ||||
/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer vairable, | |||||
* freeing EVP_MD_CTX previously stored in that variable, if any. If EVP_MD | |||||
* pointer is passed, initializes ctx with this md Returns newly allocated | |||||
* ctx. */ | |||||
EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) { | |||||
ssl_clear_hash_ctx(hash); | |||||
*hash = EVP_MD_CTX_create(); | |||||
if (md != NULL && *hash != NULL && !EVP_DigestInit_ex(*hash, md, NULL)) { | |||||
EVP_MD_CTX_destroy(*hash); | |||||
*hash = NULL; | |||||
} | |||||
return *hash; | |||||
} | |||||
void ssl_clear_hash_ctx(EVP_MD_CTX **hash) { | |||||
if (*hash) { | |||||
EVP_MD_CTX_destroy(*hash); | |||||
} | |||||
*hash = NULL; | |||||
} | |||||
int SSL_cache_hit(SSL *s) { return s->hit; } | int SSL_cache_hit(SSL *s) { return s->hit; } | ||||
int SSL_is_server(SSL *s) { return s->server; } | int SSL_is_server(SSL *s) { return s->server; } | ||||
@@ -577,7 +577,6 @@ struct ssl_protocol_method_st { | |||||
* of a mess of functions, but hell, think of it as an opaque structure. */ | * of a mess of functions, but hell, think of it as an opaque structure. */ | ||||
struct ssl3_enc_method { | struct ssl3_enc_method { | ||||
int (*enc)(SSL *, int); | int (*enc)(SSL *, int); | ||||
int (*mac)(SSL *, uint8_t *, int); | |||||
int (*prf)(SSL *, uint8_t *, size_t, const uint8_t *, size_t, const char *, | int (*prf)(SSL *, uint8_t *, size_t, const uint8_t *, size_t, const char *, | ||||
size_t, const uint8_t *, size_t, const uint8_t *, size_t); | size_t, const uint8_t *, size_t, const uint8_t *, size_t); | ||||
int (*setup_key_block)(SSL *); | int (*setup_key_block)(SSL *); | ||||
@@ -694,11 +693,6 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, | |||||
size_t *out_fixed_iv_len, | size_t *out_fixed_iv_len, | ||||
const SSL_CIPHER *cipher, uint16_t version); | const SSL_CIPHER *cipher, uint16_t version); | ||||
int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, | |||||
const EVP_MD **md, int *mac_pkey_type, | |||||
size_t *mac_secret_size); | |||||
int ssl_cipher_get_mac(const SSL_SESSION *s, const EVP_MD **md, | |||||
int *mac_pkey_type, size_t *mac_secret_size); | |||||
int ssl_get_handshake_digest(size_t i, long *mask, const EVP_MD **md); | int ssl_get_handshake_digest(size_t i, long *mask, const EVP_MD **md); | ||||
int ssl_cipher_get_cert_index(const SSL_CIPHER *c); | int ssl_cipher_get_cert_index(const SSL_CIPHER *c); | ||||
int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher); | int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher); | ||||
@@ -913,7 +907,6 @@ int tls1_enc(SSL *s, int snd); | |||||
int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len); | int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len); | ||||
int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *p); | int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *p); | ||||
int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *p); | int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *p); | ||||
int tls1_mac(SSL *ssl, uint8_t *md, int snd); | |||||
int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, | int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, | ||||
size_t premaster_len); | size_t premaster_len); | ||||
int tls1_export_keying_material(SSL *s, uint8_t *out, size_t olen, | int tls1_export_keying_material(SSL *s, uint8_t *out, size_t olen, | ||||
@@ -1030,8 +1023,6 @@ int ssl3_is_version_enabled(SSL *s, uint16_t version); | |||||
* the wire version except at API boundaries. */ | * the wire version except at API boundaries. */ | ||||
uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version); | uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version); | ||||
EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md); | |||||
void ssl_clear_hash_ctx(EVP_MD_CTX **hash); | |||||
int ssl_add_serverhello_renegotiate_ext(SSL *s, uint8_t *p, int *len, | int ssl_add_serverhello_renegotiate_ext(SSL *s, uint8_t *p, int *len, | ||||
int maxlen); | int maxlen); | ||||
int ssl_parse_serverhello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert); | int ssl_parse_serverhello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert); | ||||
@@ -1055,19 +1046,4 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert); | |||||
int ssl_add_serverhello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen); | int ssl_add_serverhello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen); | ||||
int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert); | int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert); | ||||
/* s3_cbc.c */ | |||||
void ssl3_cbc_copy_mac(uint8_t *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); | |||||
int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, uint8_t *md_out, | |||||
size_t *md_out_size, const uint8_t header[13], | |||||
const uint8_t *data, size_t data_plus_mac_size, | |||||
size_t data_plus_mac_plus_padding_size, | |||||
const uint8_t *mac_secret, | |||||
unsigned mac_secret_length, char is_sslv3); | |||||
#endif | #endif |
@@ -307,20 +307,6 @@ static int tls1_aead_ctx_init(SSL_AEAD_CTX **aead_ctx) { | |||||
return 1; | return 1; | ||||
} | } | ||||
static void tls1_cleanup_enc_ctx(EVP_CIPHER_CTX **ctx) { | |||||
if (*ctx != NULL) { | |||||
EVP_CIPHER_CTX_free(*ctx); | |||||
} | |||||
*ctx = NULL; | |||||
} | |||||
static void tls1_cleanup_hash_ctx(EVP_MD_CTX **ctx) { | |||||
if (*ctx != NULL) { | |||||
EVP_MD_CTX_destroy(*ctx); | |||||
} | |||||
*ctx = NULL; | |||||
} | |||||
static int tls1_change_cipher_state_aead(SSL *s, char is_read, | static int tls1_change_cipher_state_aead(SSL *s, char is_read, | ||||
const uint8_t *key, unsigned key_len, | const uint8_t *key, unsigned key_len, | ||||
const uint8_t *iv, unsigned iv_len, | const uint8_t *iv, unsigned iv_len, | ||||
@@ -332,14 +318,6 @@ static int tls1_change_cipher_state_aead(SSL *s, char is_read, | |||||
* simulates pre-AEAD cipher suites. */ | * simulates pre-AEAD cipher suites. */ | ||||
uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH]; | uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH]; | ||||
if (is_read) { | |||||
tls1_cleanup_enc_ctx(&s->enc_read_ctx); | |||||
tls1_cleanup_hash_ctx(&s->read_hash); | |||||
} else { | |||||
tls1_cleanup_enc_ctx(&s->enc_write_ctx); | |||||
tls1_cleanup_hash_ctx(&s->write_hash); | |||||
} | |||||
if (mac_secret_len > 0) { | if (mac_secret_len > 0) { | ||||
/* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher | /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher | ||||
* suites). */ | * suites). */ | ||||
@@ -422,120 +400,6 @@ static int tls1_change_cipher_state_aead(SSL *s, char is_read, | |||||
return 1; | return 1; | ||||
} | } | ||||
static void tls1_cleanup_aead_ctx(SSL_AEAD_CTX **ctx) { | |||||
if (*ctx != NULL) { | |||||
EVP_AEAD_CTX_cleanup(&(*ctx)->ctx); | |||||
OPENSSL_free(*ctx); | |||||
} | |||||
*ctx = NULL; | |||||
} | |||||
/* tls1_change_cipher_state_cipher performs the work needed to switch cipher | |||||
* states when using EVP_CIPHER. The argument |is_read| is true iff this | |||||
* function is being called due to reading, as opposed to writing, a | |||||
* ChangeCipherSpec message. In order to support export ciphersuites, | |||||
* use_client_keys indicates whether the key material provided is in the | |||||
* "client write" direction. */ | |||||
static int tls1_change_cipher_state_cipher(SSL *s, char is_read, | |||||
char use_client_keys, | |||||
const uint8_t *mac_secret, | |||||
unsigned mac_secret_len, | |||||
const uint8_t *key, unsigned key_len, | |||||
const uint8_t *iv, unsigned iv_len) { | |||||
const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc; | |||||
EVP_CIPHER_CTX *cipher_ctx; | |||||
EVP_MD_CTX *mac_ctx; | |||||
if (is_read) { | |||||
tls1_cleanup_aead_ctx(&s->aead_read_ctx); | |||||
} else { | |||||
/* When updating the cipher state for DTLS, we do not wish to free the old | |||||
* ones because DTLS stores pointers to them in order to implement | |||||
* retransmission. See dtls1_hm_fragment_free. | |||||
* | |||||
* TODO(davidben): Simplify aead_write_ctx ownership, probably by just | |||||
* forbidding DTLS renego. */ | |||||
if (!SSL_IS_DTLS(s)) { | |||||
tls1_cleanup_aead_ctx(&s->aead_write_ctx); | |||||
} else { | |||||
s->aead_write_ctx = NULL; | |||||
} | |||||
} | |||||
if (is_read) { | |||||
if (s->enc_read_ctx != NULL && !SSL_IS_DTLS(s)) { | |||||
EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); | |||||
} else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { | |||||
goto err; | |||||
} | |||||
cipher_ctx = s->enc_read_ctx; | |||||
mac_ctx = ssl_replace_hash(&s->read_hash, NULL); | |||||
if (mac_ctx == NULL) { | |||||
goto err; | |||||
} | |||||
memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len); | |||||
s->s3->read_mac_secret_size = mac_secret_len; | |||||
} else { | |||||
/* When updating the write contexts for DTLS, we do not wish to free the | |||||
* old ones because DTLS stores pointers to them in order to implement | |||||
* retransmission. */ | |||||
if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) { | |||||
EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); | |||||
} else { | |||||
s->enc_write_ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); | |||||
if (s->enc_write_ctx == NULL) { | |||||
goto err; | |||||
} | |||||
} | |||||
EVP_CIPHER_CTX_init(s->enc_write_ctx); | |||||
cipher_ctx = s->enc_write_ctx; | |||||
if (SSL_IS_DTLS(s)) { | |||||
/* This is the same as ssl_replace_hash, but doesn't | |||||
* free the old |s->write_hash|. */ | |||||
mac_ctx = EVP_MD_CTX_create(); | |||||
if (!mac_ctx) { | |||||
goto err; | |||||
} | |||||
s->write_hash = mac_ctx; | |||||
} else { | |||||
mac_ctx = ssl_replace_hash(&s->write_hash, NULL); | |||||
if (mac_ctx == NULL) { | |||||
goto err; | |||||
} | |||||
} | |||||
memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len); | |||||
s->s3->write_mac_secret_size = mac_secret_len; | |||||
} | |||||
EVP_PKEY *mac_key = EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, NULL, | |||||
mac_secret, mac_secret_len); | |||||
if (!mac_key) { | |||||
return 0; | |||||
} | |||||
if (!EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key)) { | |||||
EVP_PKEY_free(mac_key); | |||||
goto err; | |||||
} | |||||
EVP_PKEY_free(mac_key); | |||||
if (!EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv, | |||||
!is_read)) { | |||||
goto err; | |||||
} | |||||
return 1; | |||||
err: | |||||
OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_cipher, ERR_R_MALLOC_FAILURE); | |||||
return 0; | |||||
} | |||||
int tls1_change_cipher_state(SSL *s, int which) { | int tls1_change_cipher_state(SSL *s, int which) { | ||||
/* is_read is true if we have just read a ChangeCipherSpec message - i.e. we | /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we | ||||
* need to update the read cipherspec. Otherwise we have just written one. */ | * need to update the read cipherspec. Otherwise we have just written one. */ | ||||
@@ -548,7 +412,6 @@ int tls1_change_cipher_state(SSL *s, int which) { | |||||
const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret; | const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret; | ||||
const uint8_t *client_write_key, *server_write_key, *key; | const uint8_t *client_write_key, *server_write_key, *key; | ||||
const uint8_t *client_write_iv, *server_write_iv, *iv; | const uint8_t *client_write_iv, *server_write_iv, *iv; | ||||
const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc; | |||||
const EVP_AEAD *aead = s->s3->tmp.new_aead; | const EVP_AEAD *aead = s->s3->tmp.new_aead; | ||||
size_t key_len, iv_len, mac_secret_len; | size_t key_len, iv_len, mac_secret_len; | ||||
const uint8_t *key_data; | const uint8_t *key_data; | ||||
@@ -561,20 +424,21 @@ int tls1_change_cipher_state(SSL *s, int which) { | |||||
mac_secret_len = s->s3->tmp.new_mac_secret_len; | mac_secret_len = s->s3->tmp.new_mac_secret_len; | ||||
iv_len = s->s3->tmp.new_fixed_iv_len; | iv_len = s->s3->tmp.new_fixed_iv_len; | ||||
if (aead != NULL) { | |||||
key_len = EVP_AEAD_key_length(aead); | |||||
if (mac_secret_len > 0) { | |||||
/* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) | |||||
* the key length reported by |EVP_AEAD_key_length| will include the MAC | |||||
* and IV key bytes. */ | |||||
if (key_len < mac_secret_len + iv_len) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR); | |||||
return 0; | |||||
} | |||||
key_len -= mac_secret_len + iv_len; | |||||
if (aead == NULL) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR); | |||||
return 0; | |||||
} | |||||
key_len = EVP_AEAD_key_length(aead); | |||||
if (mac_secret_len > 0) { | |||||
/* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher | |||||
* suites) the key length reported by |EVP_AEAD_key_length| will | |||||
* include the MAC and IV key bytes. */ | |||||
if (key_len < mac_secret_len + iv_len) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR); | |||||
return 0; | |||||
} | } | ||||
} else { | |||||
key_len = EVP_CIPHER_key_length(cipher); | |||||
key_len -= mac_secret_len + iv_len; | |||||
} | } | ||||
key_data = s->s3->tmp.key_block; | key_data = s->s3->tmp.key_block; | ||||
@@ -606,33 +470,17 @@ int tls1_change_cipher_state(SSL *s, int which) { | |||||
return 0; | return 0; | ||||
} | } | ||||
if (aead != NULL) { | |||||
if (!tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len, | |||||
mac_secret, mac_secret_len)) { | |||||
return 0; | |||||
} | |||||
} else { | |||||
if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys, | |||||
mac_secret, mac_secret_len, key, | |||||
key_len, iv, iv_len)) { | |||||
return 0; | |||||
} | |||||
} | |||||
return 1; | |||||
return tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len, | |||||
mac_secret, mac_secret_len); | |||||
} | } | ||||
int tls1_setup_key_block(SSL *s) { | int tls1_setup_key_block(SSL *s) { | ||||
uint8_t *p; | uint8_t *p; | ||||
const EVP_CIPHER *c = NULL; | |||||
const EVP_MD *hash = NULL; | |||||
const EVP_AEAD *aead = NULL; | const EVP_AEAD *aead = NULL; | ||||
int mac_type = NID_undef; | |||||
int ret = 0; | int ret = 0; | ||||
size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len; | size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len; | ||||
size_t key_block_len; | size_t key_block_len; | ||||
if (s->s3->tmp.key_block_length != 0) { | if (s->s3->tmp.key_block_length != 0) { | ||||
return 1; | return 1; | ||||
} | } | ||||
@@ -641,40 +489,29 @@ int tls1_setup_key_block(SSL *s) { | |||||
goto cipher_unavailable_err; | goto cipher_unavailable_err; | ||||
} | } | ||||
/* TODO(davidben): Prune away dead code. To be done in follow-up commit. */ | |||||
if (1) { | |||||
if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len, | |||||
s->session->cipher, | |||||
ssl3_version_from_wire(s, s->version))) { | |||||
goto cipher_unavailable_err; | |||||
} | |||||
key_len = EVP_AEAD_key_length(aead); | |||||
variable_iv_len = EVP_AEAD_nonce_length(aead); | |||||
if (mac_secret_len > 0) { | |||||
/* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) | |||||
* the key length reported by |EVP_AEAD_key_length| will include the MAC | |||||
* key bytes and initial implicit IV. */ | |||||
if (key_len < mac_secret_len + fixed_iv_len) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR); | |||||
return 0; | |||||
} | |||||
key_len -= mac_secret_len + fixed_iv_len; | |||||
} else { | |||||
/* The nonce is split into a fixed portion and a variable portion. */ | |||||
if (variable_iv_len < fixed_iv_len) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR); | |||||
return 0; | |||||
} | |||||
variable_iv_len -= fixed_iv_len; | |||||
if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len, | |||||
s->session->cipher, | |||||
ssl3_version_from_wire(s, s->version))) { | |||||
goto cipher_unavailable_err; | |||||
} | |||||
key_len = EVP_AEAD_key_length(aead); | |||||
variable_iv_len = EVP_AEAD_nonce_length(aead); | |||||
if (mac_secret_len > 0) { | |||||
/* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the | |||||
* key length reported by |EVP_AEAD_key_length| will include the MAC key | |||||
* bytes and initial implicit IV. */ | |||||
if (key_len < mac_secret_len + fixed_iv_len) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR); | |||||
return 0; | |||||
} | } | ||||
key_len -= mac_secret_len + fixed_iv_len; | |||||
} else { | } else { | ||||
if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type, | |||||
&mac_secret_len)) { | |||||
goto cipher_unavailable_err; | |||||
/* The nonce is split into a fixed portion and a variable portion. */ | |||||
if (variable_iv_len < fixed_iv_len) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR); | |||||
return 0; | |||||
} | } | ||||
key_len = EVP_CIPHER_key_length(c); | |||||
fixed_iv_len = EVP_CIPHER_iv_length(c); | |||||
variable_iv_len = 0; | |||||
variable_iv_len -= fixed_iv_len; | |||||
} | } | ||||
assert(mac_secret_len < 256); | assert(mac_secret_len < 256); | ||||
@@ -682,9 +519,6 @@ int tls1_setup_key_block(SSL *s) { | |||||
assert(variable_iv_len < 256); | assert(variable_iv_len < 256); | ||||
s->s3->tmp.new_aead = aead; | s->s3->tmp.new_aead = aead; | ||||
s->s3->tmp.new_sym_enc = c; | |||||
s->s3->tmp.new_hash = hash; | |||||
s->s3->tmp.new_mac_pkey_type = mac_type; | |||||
s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; | s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len; | ||||
s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; | s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len; | ||||
s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len; | s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len; | ||||
@@ -741,10 +575,6 @@ cipher_unavailable_err: | |||||
* an internal error occured. */ | * an internal error occured. */ | ||||
int tls1_enc(SSL *s, int send) { | int tls1_enc(SSL *s, int send) { | ||||
SSL3_RECORD *rec; | SSL3_RECORD *rec; | ||||
EVP_CIPHER_CTX *ds; | |||||
unsigned long l; | |||||
int bs, i, j, k, pad = 0, ret, mac_size = 0; | |||||
const EVP_CIPHER *enc; | |||||
const SSL_AEAD_CTX *aead; | const SSL_AEAD_CTX *aead; | ||||
if (send) { | if (send) { | ||||
@@ -755,215 +585,140 @@ int tls1_enc(SSL *s, int send) { | |||||
aead = s->aead_read_ctx; | aead = s->aead_read_ctx; | ||||
} | } | ||||
if (aead) { | |||||
uint8_t ad[13], *seq, *in, *out, nonce[EVP_AEAD_MAX_NONCE_LENGTH]; | |||||
unsigned nonce_used; | |||||
size_t n, ad_len; | |||||
if (s->session == NULL || aead == NULL) { | |||||
memmove(rec->data, rec->input, rec->length); | |||||
rec->input = rec->data; | |||||
return 1; | |||||
} | |||||
seq = send ? s->s3->write_sequence : s->s3->read_sequence; | |||||
uint8_t ad[13], *seq, *in, *out, nonce[EVP_AEAD_MAX_NONCE_LENGTH]; | |||||
unsigned nonce_used; | |||||
size_t n, ad_len; | |||||
if (SSL_IS_DTLS(s)) { | |||||
uint8_t dtlsseq[9], *p = dtlsseq; | |||||
seq = send ? s->s3->write_sequence : s->s3->read_sequence; | |||||
s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p); | |||||
memcpy(p, &seq[2], 6); | |||||
memcpy(ad, dtlsseq, 8); | |||||
} else { | |||||
memcpy(ad, seq, 8); | |||||
for (i = 7; i >= 0; i--) { | |||||
++seq[i]; | |||||
if (seq[i] != 0) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
if (SSL_IS_DTLS(s)) { | |||||
uint8_t dtlsseq[9], *p = dtlsseq; | |||||
ad[8] = rec->type; | |||||
ad_len = 9; | |||||
if (!aead->omit_version_in_ad) { | |||||
ad[ad_len++] = (uint8_t)(s->version >> 8); | |||||
ad[ad_len++] = (uint8_t)(s->version); | |||||
s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p); | |||||
memcpy(p, &seq[2], 6); | |||||
memcpy(ad, dtlsseq, 8); | |||||
} else { | |||||
int i; | |||||
memcpy(ad, seq, 8); | |||||
for (i = 7; i >= 0; i--) { | |||||
++seq[i]; | |||||
if (seq[i] != 0) { | |||||
break; | |||||
} | |||||
} | } | ||||
} | |||||
if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce)) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR); | |||||
return -1; /* internal error - should never happen. */ | |||||
} | |||||
ad[8] = rec->type; | |||||
ad_len = 9; | |||||
if (!aead->omit_version_in_ad) { | |||||
ad[ad_len++] = (uint8_t)(s->version >> 8); | |||||
ad[ad_len++] = (uint8_t)(s->version); | |||||
} | |||||
memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len); | |||||
nonce_used = aead->fixed_nonce_len; | |||||
if (send) { | |||||
size_t len = rec->length; | |||||
size_t eivlen = 0; | |||||
in = rec->input; | |||||
out = rec->data; | |||||
uint8_t *variable_nonce = nonce + nonce_used; | |||||
if (aead->random_variable_nonce) { | |||||
assert(aead->variable_nonce_included_in_record); | |||||
if (!RAND_bytes(nonce + nonce_used, aead->variable_nonce_len)) { | |||||
return -1; | |||||
} | |||||
} else { | |||||
/* When sending we use the sequence number as the variable part of the | |||||
* nonce. */ | |||||
if (aead->variable_nonce_len != 8) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR); | |||||
return -1; | |||||
} | |||||
memcpy(nonce + nonce_used, ad, aead->variable_nonce_len); | |||||
} | |||||
nonce_used += aead->variable_nonce_len; | |||||
/* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in | |||||
* order to leave space for the variable nonce. Thus we can copy the | |||||
* sequence number bytes into place without overwriting any of the | |||||
* plaintext. */ | |||||
if (aead->variable_nonce_included_in_record) { | |||||
memcpy(out, variable_nonce, aead->variable_nonce_len); | |||||
len -= aead->variable_nonce_len; | |||||
eivlen = aead->variable_nonce_len; | |||||
} | |||||
if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce)) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR); | |||||
return -1; /* internal error - should never happen. */ | |||||
} | |||||
if (!aead->omit_length_in_ad) { | |||||
ad[ad_len++] = len >> 8; | |||||
ad[ad_len++] = len & 0xff; | |||||
} | |||||
memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len); | |||||
nonce_used = aead->fixed_nonce_len; | |||||
if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len, | |||||
nonce, nonce_used, in + eivlen, len, ad, ad_len)) { | |||||
if (send) { | |||||
size_t len = rec->length; | |||||
size_t eivlen = 0; | |||||
in = rec->input; | |||||
out = rec->data; | |||||
uint8_t *variable_nonce = nonce + nonce_used; | |||||
if (aead->random_variable_nonce) { | |||||
assert(aead->variable_nonce_included_in_record); | |||||
if (!RAND_bytes(nonce + nonce_used, aead->variable_nonce_len)) { | |||||
return -1; | return -1; | ||||
} | } | ||||
if (aead->variable_nonce_included_in_record) { | |||||
n += aead->variable_nonce_len; | |||||
} | |||||
} else { | } else { | ||||
/* receive */ | |||||
size_t len = rec->length; | |||||
if (rec->data != rec->input) { | |||||
/* When sending we use the sequence number as the variable part of the | |||||
* nonce. */ | |||||
if (aead->variable_nonce_len != 8) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR); | OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR); | ||||
return -1; /* internal error - should never happen. */ | |||||
} | |||||
out = in = rec->input; | |||||
if (len < aead->variable_nonce_len) { | |||||
return 0; | |||||
} | |||||
memcpy(nonce + nonce_used, | |||||
aead->variable_nonce_included_in_record ? in : ad, | |||||
aead->variable_nonce_len); | |||||
nonce_used += aead->variable_nonce_len; | |||||
if (aead->variable_nonce_included_in_record) { | |||||
in += aead->variable_nonce_len; | |||||
len -= aead->variable_nonce_len; | |||||
out += aead->variable_nonce_len; | |||||
} | |||||
if (!aead->omit_length_in_ad) { | |||||
if (len < aead->tag_len) { | |||||
return 0; | |||||
} | |||||
size_t plaintext_len = len - aead->tag_len; | |||||
ad[ad_len++] = plaintext_len >> 8; | |||||
ad[ad_len++] = plaintext_len & 0xff; | |||||
} | |||||
if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, rec->length, nonce, nonce_used, in, | |||||
len, ad, ad_len)) { | |||||
return -1; | return -1; | ||||
} | } | ||||
rec->data = rec->input = out; | |||||
memcpy(nonce + nonce_used, ad, aead->variable_nonce_len); | |||||
} | |||||
nonce_used += aead->variable_nonce_len; | |||||
/* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in | |||||
* order to leave space for the variable nonce. Thus we can copy the | |||||
* sequence number bytes into place without overwriting any of the | |||||
* plaintext. */ | |||||
if (aead->variable_nonce_included_in_record) { | |||||
memcpy(out, variable_nonce, aead->variable_nonce_len); | |||||
len -= aead->variable_nonce_len; | |||||
eivlen = aead->variable_nonce_len; | |||||
} | } | ||||
rec->length = n; | |||||
return 1; | |||||
} | |||||
if (send) { | |||||
ds = s->enc_write_ctx; | |||||
rec = &(s->s3->wrec); | |||||
if (s->enc_write_ctx == NULL) { | |||||
enc = NULL; | |||||
} else { | |||||
int ivlen; | |||||
enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); | |||||
/* For TLSv1.1 and later explicit IV */ | |||||
if (SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) { | |||||
ivlen = EVP_CIPHER_iv_length(enc); | |||||
} else { | |||||
ivlen = 0; | |||||
} | |||||
if (ivlen > 1) { | |||||
if (rec->data != rec->input) { | |||||
/* we can't write into the input stream: | |||||
* Can this ever happen?? (steve) | |||||
*/ | |||||
fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__, | |||||
__LINE__); | |||||
} else if (!RAND_bytes(rec->input, ivlen)) { | |||||
return -1; | |||||
} | |||||
} | |||||
if (!aead->omit_length_in_ad) { | |||||
ad[ad_len++] = len >> 8; | |||||
ad[ad_len++] = len & 0xff; | |||||
} | } | ||||
} else { | |||||
ds = s->enc_read_ctx; | |||||
rec = &(s->s3->rrec); | |||||
if (s->enc_read_ctx == NULL) { | |||||
enc = NULL; | |||||
} else { | |||||
enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); | |||||
if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len, | |||||
nonce, nonce_used, in + eivlen, len, ad, ad_len)) { | |||||
return -1; | |||||
} | } | ||||
} | |||||
if (s->session == NULL || ds == NULL || enc == NULL) { | |||||
memmove(rec->data, rec->input, rec->length); | |||||
rec->input = rec->data; | |||||
ret = 1; | |||||
if (aead->variable_nonce_included_in_record) { | |||||
n += aead->variable_nonce_len; | |||||
} | |||||
} else { | } else { | ||||
l = rec->length; | |||||
bs = EVP_CIPHER_block_size(ds->cipher); | |||||
if (bs != 1 && send) { | |||||
i = bs - ((int)l % bs); | |||||
/* receive */ | |||||
size_t len = rec->length; | |||||
/* Add weird padding of upto 256 bytes */ | |||||
/* we need to add 'i' padding bytes of value j */ | |||||
j = i - 1; | |||||
for (k = (int)l; k < (int)(l + i); k++) { | |||||
rec->input[k] = j; | |||||
} | |||||
l += i; | |||||
rec->length += i; | |||||
if (rec->data != rec->input) { | |||||
OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR); | |||||
return -1; /* internal error - should never happen. */ | |||||
} | } | ||||
out = in = rec->input; | |||||
if (!send && (l == 0 || l % bs != 0)) { | |||||
if (len < aead->variable_nonce_len) { | |||||
return 0; | return 0; | ||||
} | } | ||||
if (!EVP_Cipher(ds, rec->data, rec->input, l)) { | |||||
return -1; | |||||
memcpy(nonce + nonce_used, | |||||
aead->variable_nonce_included_in_record ? in : ad, | |||||
aead->variable_nonce_len); | |||||
nonce_used += aead->variable_nonce_len; | |||||
if (aead->variable_nonce_included_in_record) { | |||||
in += aead->variable_nonce_len; | |||||
len -= aead->variable_nonce_len; | |||||
out += aead->variable_nonce_len; | |||||
} | } | ||||
ret = 1; | |||||
if (EVP_MD_CTX_md(s->read_hash) != NULL) { | |||||
mac_size = EVP_MD_CTX_size(s->read_hash); | |||||
} | |||||
if (!aead->omit_length_in_ad) { | |||||
if (len < aead->tag_len) { | |||||
return 0; | |||||
} | |||||
size_t plaintext_len = len - aead->tag_len; | |||||
if (bs != 1 && !send) { | |||||
ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); | |||||
ad[ad_len++] = plaintext_len >> 8; | |||||
ad[ad_len++] = plaintext_len & 0xff; | |||||
} | } | ||||
if (pad && !send) { | |||||
rec->length -= pad; | |||||
if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, rec->length, nonce, nonce_used, in, | |||||
len, ad, ad_len)) { | |||||
return -1; | |||||
} | } | ||||
rec->data = rec->input = out; | |||||
} | } | ||||
return ret; | |||||
rec->length = n; | |||||
return 1; | |||||
} | } | ||||
int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) { | int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) { | ||||
@@ -1072,89 +827,6 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) { | |||||
} | } | ||||
} | } | ||||
int tls1_mac(SSL *ssl, uint8_t *md, int send) { | |||||
SSL3_RECORD *rec; | |||||
uint8_t *seq; | |||||
EVP_MD_CTX *hash; | |||||
size_t md_size, orig_len; | |||||
int i, ok; | |||||
EVP_MD_CTX hmac, *mac_ctx; | |||||
uint8_t header[13]; | |||||
int t; | |||||
if (send) { | |||||
rec = &ssl->s3->wrec; | |||||
seq = &ssl->s3->write_sequence[0]; | |||||
hash = ssl->write_hash; | |||||
} else { | |||||
rec = &ssl->s3->rrec; | |||||
seq = &ssl->s3->read_sequence[0]; | |||||
hash = ssl->read_hash; | |||||
} | |||||
t = EVP_MD_CTX_size(hash); | |||||
assert(t >= 0); | |||||
md_size = t; | |||||
mac_ctx = &hmac; | |||||
if (!EVP_MD_CTX_copy(mac_ctx, hash)) { | |||||
return -1; | |||||
} | |||||
if (SSL_IS_DTLS(ssl)) { | |||||
uint8_t dtlsseq[8], *p = dtlsseq; | |||||
s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p); | |||||
memcpy(p, &seq[2], 6); | |||||
memcpy(header, dtlsseq, 8); | |||||
} else { | |||||
memcpy(header, seq, 8); | |||||
} | |||||
/* 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] = (uint8_t)(ssl->version >> 8); | |||||
header[10] = (uint8_t)(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. */ | |||||
ok = 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); | |||||
ok = EVP_DigestSignFinal(mac_ctx, md, &md_size); | |||||
} | |||||
EVP_MD_CTX_cleanup(mac_ctx); | |||||
if (!ok) { | |||||
return -1; | |||||
} | |||||
if (!SSL_IS_DTLS(ssl)) { | |||||
for (i = 7; i >= 0; i--) { | |||||
++seq[i]; | |||||
if (seq[i] != 0) { | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
return md_size; | |||||
} | |||||
int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, | int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster, | ||||
size_t premaster_len) { | size_t premaster_len) { | ||||
if (s->s3->tmp.extended_master_secret) { | if (s->s3->tmp.extended_master_secret) { | ||||
@@ -128,7 +128,6 @@ static int ssl_check_serverhello_tlsext(SSL *s); | |||||
const SSL3_ENC_METHOD TLSv1_enc_data = { | const SSL3_ENC_METHOD TLSv1_enc_data = { | ||||
tls1_enc, | tls1_enc, | ||||
tls1_mac, | |||||
tls1_prf, | tls1_prf, | ||||
tls1_setup_key_block, | tls1_setup_key_block, | ||||
tls1_generate_master_secret, | tls1_generate_master_secret, | ||||
@@ -148,7 +147,6 @@ const SSL3_ENC_METHOD TLSv1_enc_data = { | |||||
const SSL3_ENC_METHOD TLSv1_1_enc_data = { | const SSL3_ENC_METHOD TLSv1_1_enc_data = { | ||||
tls1_enc, | tls1_enc, | ||||
tls1_mac, | |||||
tls1_prf, | tls1_prf, | ||||
tls1_setup_key_block, | tls1_setup_key_block, | ||||
tls1_generate_master_secret, | tls1_generate_master_secret, | ||||
@@ -168,7 +166,6 @@ const SSL3_ENC_METHOD TLSv1_1_enc_data = { | |||||
const SSL3_ENC_METHOD TLSv1_2_enc_data = { | const SSL3_ENC_METHOD TLSv1_2_enc_data = { | ||||
tls1_enc, | tls1_enc, | ||||
tls1_mac, | |||||
tls1_prf, | tls1_prf, | ||||
tls1_setup_key_block, | tls1_setup_key_block, | ||||
tls1_generate_master_secret, | tls1_generate_master_secret, | ||||