* https://www.openssl.org/source/license.html
*/
+#include <assert.h>
#include "../ssl_locl.h"
#include "internal/constant_time_locl.h"
#include <openssl/rand.h>
return 1;
}
+int early_data_count_ok(SSL *s, size_t length, size_t overhead, int *al)
+{
+ uint32_t max_early_data = s->max_early_data;
+
+ /*
+ * If we are a client then we always use the max_early_data from the
+ * session. Otherwise we go with the lowest out of the max early data set in
+ * the session and the configured max_early_data.
+ */
+ if (!s->server || (s->hit
+ && s->session->ext.max_early_data < s->max_early_data))
+ max_early_data = s->session->ext.max_early_data;
+
+ if (max_early_data == 0) {
+ if (al != NULL)
+ *al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA);
+ return 0;
+ }
+
+ /* If we are dealing with ciphertext we need to allow for the overhead */
+ max_early_data += overhead;
+
+ if (s->early_data_count + length > max_early_data) {
+ if (al != NULL)
+ *al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_EARLY_DATA_COUNT_OK, SSL_R_TOO_MUCH_EARLY_DATA);
+ return 0;
+ }
+ s->early_data_count += length;
+
+ return 1;
+}
+
/*
* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that
* will be processed per call to ssl3_get_record. Without this limit an
/* used only by ssl3_read_bytes */
int ssl3_get_record(SSL *s)
{
- int ssl_major, ssl_minor, al;
+ int al;
int enc_err, rret, ret = -1;
int i;
size_t more, n;
- SSL3_RECORD *rr;
+ SSL3_RECORD *rr, *thisrr;
SSL3_BUFFER *rbuf;
SSL_SESSION *sess;
unsigned char *p;
unsigned char md[EVP_MAX_MD_SIZE];
- short version;
+ unsigned int version;
size_t mac_size;
int imac_size;
size_t num_recs = 0, max_recs, j;
+ PACKET pkt, sslv2pkt;
+ size_t first_rec_len;
rr = RECORD_LAYER_get_rrec(&s->rlayer);
rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
sess = s->session;
do {
+ thisrr = &rr[num_recs];
+
/* check if we have the header */
if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
(RECORD_LAYER_get_packet_length(&s->rlayer)
< SSL3_RT_HEADER_LENGTH)) {
+ size_t sslv2len;
+ unsigned int type;
+
rret = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH,
SSL3_BUFFER_get_len(rbuf), 0,
num_recs == 0 ? 1 : 0, &n);
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
p = RECORD_LAYER_get_packet(&s->rlayer);
-
+ if (!PACKET_buf_init(&pkt, RECORD_LAYER_get_packet(&s->rlayer),
+ RECORD_LAYER_get_packet_length(&s->rlayer))) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ sslv2pkt = pkt;
+ if (!PACKET_get_net_2_len(&sslv2pkt, &sslv2len)
+ || !PACKET_get_1(&sslv2pkt, &type)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
/*
* The first record received by the server may be a V2ClientHello.
*/
if (s->server && RECORD_LAYER_is_first_record(&s->rlayer)
- && (p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) {
+ && (sslv2len & 0x8000) != 0
+ && (type == SSL2_MT_CLIENT_HELLO)) {
/*
* SSLv2 style record
*
* because it is an SSLv2ClientHello. We keep it using
* |num_recs| for the sake of consistency
*/
- rr[num_recs].type = SSL3_RT_HANDSHAKE;
- rr[num_recs].rec_version = SSL2_VERSION;
+ thisrr->type = SSL3_RT_HANDSHAKE;
+ thisrr->rec_version = SSL2_VERSION;
- rr[num_recs].length = ((p[0] & 0x7f) << 8) | p[1];
+ thisrr->length = sslv2len & 0x7fff;
- if (rr[num_recs].length > SSL3_BUFFER_get_len(rbuf)
+ if (thisrr->length > SSL3_BUFFER_get_len(rbuf)
- SSL2_RT_HEADER_LENGTH) {
al = SSL_AD_RECORD_OVERFLOW;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
goto f_err;
}
- if (rr[num_recs].length < MIN_SSL2_RECORD_LEN) {
+ if (thisrr->length < MIN_SSL2_RECORD_LEN) {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
s->msg_callback_arg);
/* Pull apart the header into the SSL3_RECORD */
- rr[num_recs].type = *(p++);
- ssl_major = *(p++);
- ssl_minor = *(p++);
- version = (ssl_major << 8) | ssl_minor;
- rr[num_recs].rec_version = version;
- n2s(p, rr[num_recs].length);
-
- /* Lets check version */
- if (!s->first_packet && version != s->version) {
+ if (!PACKET_get_1(&pkt, &type)
+ || !PACKET_get_net_2(&pkt, &version)
+ || !PACKET_get_net_2_len(&pkt, &thisrr->length)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ thisrr->type = type;
+ thisrr->rec_version = version;
+
+ /* Lets check version. In TLSv1.3 we ignore this field */
+ if (!s->first_packet && !SSL_IS_TLS13(s)
+ && version != (unsigned int)s->version) {
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
if ((s->version & 0xFF00) == (version & 0xFF00)
&& !s->enc_write_ctx && !s->write_hash) {
- if (rr->type == SSL3_RT_ALERT) {
+ if (thisrr->type == SSL3_RT_ALERT) {
/*
* The record is using an incorrect version number,
* but what we've got appears to be an alert. We
}
}
- if (rr[num_recs].length >
+ if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL
+ && thisrr->type != SSL3_RT_APPLICATION_DATA) {
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE);
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ goto f_err;
+ }
+
+ if (thisrr->length >
SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
al = SSL_AD_RECORD_OVERFLOW;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
/* now s->rlayer.rstate == SSL_ST_READ_BODY */
}
+ if (SSL_IS_TLS13(s)) {
+ if (thisrr->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ } else {
+ size_t len = SSL3_RT_MAX_ENCRYPTED_LENGTH;
+
+#ifndef OPENSSL_NO_COMP
+ /*
+ * If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH
+ * does not include the compression overhead anyway.
+ */
+ if (s->expand == NULL)
+ len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+
+ if (thisrr->length > len) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ }
+
/*
* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
* Calculate how much more data we need to read for the rest of the
* record
*/
- if (rr[num_recs].rec_version == SSL2_VERSION) {
- more = rr[num_recs].length + SSL2_RT_HEADER_LENGTH
+ if (thisrr->rec_version == SSL2_VERSION) {
+ more = thisrr->length + SSL2_RT_HEADER_LENGTH
- SSL3_RT_HEADER_LENGTH;
} else {
- more = rr[num_recs].length;
+ more = thisrr->length;
}
if (more > 0) {
/* now s->packet_length == SSL3_RT_HEADER_LENGTH */
RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
/*
- * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length,
- * or s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length
- * and we have that many bytes in s->packet
+ * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH
+ * + thisrr->length, or s->packet_length == SSL2_RT_HEADER_LENGTH
+ * + thisrr->length and we have that many bytes in s->packet
*/
- if (rr[num_recs].rec_version == SSL2_VERSION) {
- rr[num_recs].input =
+ if (thisrr->rec_version == SSL2_VERSION) {
+ thisrr->input =
&(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]);
} else {
- rr[num_recs].input =
+ thisrr->input =
&(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]);
}
/*
- * ok, we can now read from 's->packet' data into 'rr' rr->input points
- * at rr->length bytes, which need to be copied into rr->data by either
- * the decryption or by the decompression When the data is 'copied' into
- * the rr->data buffer, rr->input will be pointed at the new buffer
+ * ok, we can now read from 's->packet' data into 'thisrr' thisrr->input
+ * points at thisrr->length bytes, which need to be copied into
+ * thisrr->data by either the decryption or by the decompression When
+ * the data is 'copied' into the thisrr->data buffer, thisrr->input will
+ * be pointed at the new buffer
*/
/*
- * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length
- * bytes of encrypted compressed stuff.
+ * We now have - encrypted [ MAC [ compressed [ plain ] ] ]
+ * thisrr->length bytes of encrypted compressed stuff.
*/
- /* check is not needed I believe */
- if (rr[num_recs].length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* decrypt in place in 'rr->input' */
- rr[num_recs].data = rr[num_recs].input;
- rr[num_recs].orig_len = rr[num_recs].length;
+ /* decrypt in place in 'thisrr->input' */
+ thisrr->data = thisrr->input;
+ thisrr->orig_len = thisrr->length;
/* Mark this record as not read by upper layers yet */
- rr[num_recs].read = 0;
+ thisrr->read = 0;
num_recs++;
RECORD_LAYER_reset_packet_length(&s->rlayer);
RECORD_LAYER_clear_first_record(&s->rlayer);
} while (num_recs < max_recs
- && rr[num_recs - 1].type == SSL3_RT_APPLICATION_DATA
+ && thisrr->type == SSL3_RT_APPLICATION_DATA
&& SSL_USE_EXPLICIT_IV(s)
&& s->enc_read_ctx != NULL
&& (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_read_ctx))
* If in encrypt-then-mac mode calculate mac from encrypted record. All
* the details below are public so no timing details can leak.
*/
- if (SSL_USE_ETM(s) && s->read_hash) {
+ if (SSL_READ_ETM(s) && s->read_hash) {
unsigned char *mac;
/* TODO(size_t): convert this to do size_t properly */
imac_size = EVP_MD_CTX_size(s->read_hash);
- if (imac_size < 0) {
+ assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE);
+ if (imac_size < 0 || imac_size > EVP_MAX_MD_SIZE) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_SSL3_GET_RECORD, ERR_LIB_EVP);
goto f_err;
}
mac_size = (size_t)imac_size;
- OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
for (j = 0; j < num_recs; j++) {
- if (rr[j].length < mac_size) {
+ thisrr = &rr[j];
+
+ if (thisrr->length < mac_size) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
- rr[j].length -= mac_size;
- mac = rr[j].data + rr[j].length;
- i = s->method->ssl3_enc->mac(s, &rr[j], md, 0 /* not send */ );
+ thisrr->length -= mac_size;
+ mac = thisrr->data + thisrr->length;
+ i = s->method->ssl3_enc->mac(s, thisrr, md, 0 /* not send */ );
if (i == 0 || CRYPTO_memcmp(md, mac, mac_size) != 0) {
al = SSL_AD_BAD_RECORD_MAC;
SSLerr(SSL_F_SSL3_GET_RECORD,
}
}
+ first_rec_len = rr[0].length;
+
enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0);
+
/*-
* enc_err is:
- * 0: (in non-constant time) if the record is publically invalid.
+ * 0: (in non-constant time) if the record is publicly invalid.
* 1: if the padding is valid
* -1: if the padding is invalid
*/
if (enc_err == 0) {
+ if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
+ /*
+ * Valid early_data that we cannot decrypt might fail here as
+ * publicly invalid. We treat it like an empty record.
+ */
+
+ thisrr = &rr[0];
+
+ if (!early_data_count_ok(s, thisrr->length,
+ EARLY_DATA_CIPHERTEXT_OVERHEAD, &al))
+ goto f_err;
+
+ thisrr->length = 0;
+ thisrr->read = 1;
+ RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
+ RECORD_LAYER_reset_read_sequence(&s->rlayer);
+ return 1;
+ }
al = SSL_AD_DECRYPTION_FAILED;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
goto f_err;
}
#ifdef SSL_DEBUG
- printf("dec %"OSSLzu"\n", rr->length);
+ printf("dec %"OSSLzu"\n", rr[0].length);
{
size_t z;
- for (z = 0; z < rr->length; z++)
- printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n');
+ for (z = 0; z < rr[0].length; z++)
+ printf("%02X%c", rr[0].data[z], ((z + 1) % 16) ? ' ' : '\n');
}
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) && !SSL_USE_ETM(s)) {
+ (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)) {
/* s->read_hash != NULL => mac_size != -1 */
unsigned char *mac = NULL;
unsigned char mac_tmp[EVP_MAX_MD_SIZE];
OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
for (j = 0; j < num_recs; j++) {
+ thisrr = &rr[j];
/*
* 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 (rr[j].orig_len < mac_size ||
+ if (thisrr->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 &&
- rr[j].orig_len < mac_size + 1)) {
+ thisrr->orig_len < mac_size + 1)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
* contents of the padding bytes.
*/
mac = mac_tmp;
- ssl3_cbc_copy_mac(mac_tmp, &rr[j], mac_size);
- rr[j].length -= mac_size;
+ ssl3_cbc_copy_mac(mac_tmp, thisrr, mac_size);
+ thisrr->length -= mac_size;
} else {
/*
* In this case there's no padding, so |rec->orig_len| equals
* |rec->length| and we checked that there's enough bytes for
* |mac_size| above.
*/
- rr[j].length -= mac_size;
- mac = &rr[j].data[rr[j].length];
+ thisrr->length -= mac_size;
+ mac = &thisrr->data[thisrr->length];
}
- i = s->method->ssl3_enc->mac(s, &rr[j], md, 0 /* not send */ );
+ i = s->method->ssl3_enc->mac(s, thisrr, 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)
+ if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
enc_err = -1;
}
}
if (enc_err < 0) {
+ if (num_recs == 1 && ossl_statem_skip_early_data(s)) {
+ /*
+ * We assume this is unreadable early_data - we treat it like an
+ * empty record
+ */
+
+ /*
+ * The record length may have been modified by the mac check above
+ * so we use the previously saved value
+ */
+ if (!early_data_count_ok(s, first_rec_len,
+ EARLY_DATA_CIPHERTEXT_OVERHEAD, &al))
+ goto f_err;
+
+ thisrr = &rr[0];
+ thisrr->length = 0;
+ thisrr->read = 1;
+ RECORD_LAYER_set_numrpipes(&s->rlayer, 1);
+ RECORD_LAYER_reset_read_sequence(&s->rlayer);
+ return 1;
+ }
/*
* A separate 'decryption_failed' alert was introduced with TLS 1.0,
* SSL 3.0 only has 'bad_record_mac'. But unless a decryption
}
for (j = 0; j < num_recs; j++) {
- /* rr[j].length is now just compressed */
+ thisrr = &rr[j];
+
+ /* thisrr->length is now just compressed */
if (s->expand != NULL) {
- if (rr[j].length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
+ if (thisrr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
al = SSL_AD_RECORD_OVERFLOW;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_COMPRESSED_LENGTH_TOO_LONG);
goto f_err;
}
- if (!ssl3_do_uncompress(s, &rr[j])) {
+ if (!ssl3_do_uncompress(s, thisrr)) {
al = SSL_AD_DECOMPRESSION_FAILURE;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_DECOMPRESSION);
goto f_err;
}
}
- if (rr[j].length > SSL3_RT_MAX_PLAIN_LENGTH) {
+ if (SSL_IS_TLS13(s) && s->enc_read_ctx != NULL) {
+ size_t end;
+
+ if (thisrr->length == 0
+ || thisrr->type != SSL3_RT_APPLICATION_DATA) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE);
+ goto f_err;
+ }
+
+ /* Strip trailing padding */
+ for (end = thisrr->length - 1; end > 0 && thisrr->data[end] == 0;
+ end--)
+ continue;
+
+ thisrr->length = end;
+ thisrr->type = thisrr->data[end];
+ if (thisrr->type != SSL3_RT_APPLICATION_DATA
+ && thisrr->type != SSL3_RT_ALERT
+ && thisrr->type != SSL3_RT_HANDSHAKE) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_RECORD_TYPE);
+ goto f_err;
+ }
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_INNER_CONTENT_TYPE,
+ &thisrr->data[end], 1, s, s->msg_callback_arg);
+ }
+
+ if (thisrr->length > SSL3_RT_MAX_PLAIN_LENGTH) {
al = SSL_AD_RECORD_OVERFLOW;
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG);
goto f_err;
}
- rr[j].off = 0;
+ thisrr->off = 0;
/*-
* So at this point the following is true
- * rr[j].type is the type of record
- * rr[j].length == number of bytes in record
- * rr[j].off == offset to first valid byte
- * rr[j].data == where to take bytes from, increment after use :-).
+ * thisrr->type is the type of record
+ * thisrr->length == number of bytes in record
+ * thisrr->off == offset to first valid byte
+ * thisrr->data == where to take bytes from, increment after use :-).
*/
/* just read a 0 length packet */
- if (rr[j].length == 0) {
+ if (thisrr->length == 0) {
RECORD_LAYER_inc_empty_record_count(&s->rlayer);
if (RECORD_LAYER_get_empty_record_count(&s->rlayer)
> MAX_EMPTY_RECORDS) {
}
}
+ if (s->early_data_state == SSL_EARLY_DATA_READING) {
+ thisrr = &rr[0];
+ if (thisrr->type == SSL3_RT_APPLICATION_DATA
+ && !early_data_count_ok(s, thisrr->length, 0, &al))
+ goto f_err;
+ }
+
RECORD_LAYER_set_numrpipes(&s->rlayer, num_recs);
return 1;
/* TODO(size_t): Convert this call */
i = COMP_compress_block(ssl->compress, wr->data,
- SSL3_RT_MAX_COMPRESSED_LENGTH,
+ (int)(wr->length + SSL3_RT_MAX_COMPRESSED_OVERHEAD),
wr->input, (int)wr->length);
if (i < 0)
return (0);
* -1: if the record's padding is invalid or, if sending, an internal error
* occurred.
*/
-int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int send)
+int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, size_t n_recs, int sending)
{
SSL3_RECORD *rec;
EVP_CIPHER_CTX *ds;
*/
if (n_recs != 1)
return 0;
- if (send) {
+ if (sending) {
ds = s->enc_write_ctx;
if (s->enc_write_ctx == NULL)
enc = NULL;
/* COMPRESS */
- if ((bs != 1) && send) {
+ if ((bs != 1) && sending) {
i = bs - (l % bs);
/* we need to add 'i-1' padding bytes */
rec->input[l - 1] = (unsigned char)(i - 1);
}
- if (!send) {
+ if (!sending) {
if (l == 0 || l % bs != 0)
return 0;
/* otherwise, rec->length >= bs */
return -1;
mac_size = (size_t)imac_size;
}
- if ((bs != 1) && !send)
+ if ((bs != 1) && !sending)
return ssl3_cbc_remove_padding(rec, bs, mac_size);
}
return (1);
* -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
* an internal error occurred.
*/
-int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int send)
+int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending)
{
EVP_CIPHER_CTX *ds;
size_t reclen[SSL_MAX_PIPELINES];
int imac_size;
const EVP_CIPHER *enc;
- if (send) {
+ if (n_recs == 0)
+ return 0;
+
+ if (sending) {
if (EVP_MD_CTX_md(s->write_hash)) {
int n = EVP_MD_CTX_size(s->write_hash);
OPENSSL_assert(n >= 0);
& EVP_CIPH_FLAG_AEAD_CIPHER) {
unsigned char *seq;
- seq = send ? RECORD_LAYER_get_write_sequence(&s->rlayer)
+ seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer)
: RECORD_LAYER_get_read_sequence(&s->rlayer);
if (SSL_IS_DTLS(s)) {
/* DTLS does not support pipelining */
unsigned char dtlsseq[9], *p = dtlsseq;
- s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) :
+ s2n(sending ? DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) :
DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer), p);
memcpy(p, &seq[2], 6);
memcpy(buf[ctr], dtlsseq, 8);
if (pad <= 0)
return -1;
- if (send) {
+ if (sending) {
reclen[ctr] += pad;
recs[ctr].length += pad;
}
- } else if ((bs != 1) && send) {
+ } else if ((bs != 1) && sending) {
padnum = bs - (reclen[ctr] % bs);
/* Add weird padding of upto 256 bytes */
recs[ctr].length += padnum;
}
- if (!send) {
+ if (!sending) {
if (reclen[ctr] == 0 || reclen[ctr] % bs != 0)
return 0;
}
? (tmpr < 0)
: (tmpr == 0))
return -1; /* AEAD can fail to verify MAC */
- if (send == 0) {
+ if (sending == 0) {
if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE) {
for (ctr = 0; ctr < n_recs; ctr++) {
recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
}
ret = 1;
- if (!SSL_USE_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL) {
+ if (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL) {
imac_size = EVP_MD_CTX_size(s->read_hash);
if (imac_size < 0)
return -1;
mac_size = (size_t)imac_size;
}
- if ((bs != 1) && !send) {
+ if ((bs != 1) && !sending) {
int tmpret;
for (ctr = 0; ctr < n_recs; ctr++) {
tmpret = tls1_cbc_remove_padding(s, &recs[ctr], bs, mac_size);
ret, -1);
}
}
- if (pad && !send) {
+ if (pad && !sending) {
for (ctr = 0; ctr < n_recs; ctr++) {
recs[ctr].length -= pad;
}
return ret;
}
-int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send)
+int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
{
unsigned char *mac_sec, *seq;
const EVP_MD_CTX *hash;
size_t npad;
int t;
- if (send) {
+ if (sending) {
mac_sec = &(ssl->s3->write_mac_secret[0]);
seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
hash = ssl->write_hash;
md_size = t;
npad = (48 / md_size) * md_size;
- if (!send &&
+ if (!sending &&
EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
ssl3_cbc_record_digest_supported(hash)) {
/*
return 1;
}
-int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send)
+int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
{
unsigned char *seq;
EVP_MD_CTX *hash;
int i;
EVP_MD_CTX *hmac = NULL, *mac_ctx;
unsigned char header[13];
- int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
+ int stream_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
: (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
int t;
- if (send) {
+ if (sending) {
seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
hash = ssl->write_hash;
} else {
if (SSL_IS_DTLS(ssl)) {
unsigned char dtlsseq[8], *p = dtlsseq;
- s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) :
+ s2n(sending ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) :
DTLS_RECORD_LAYER_get_r_epoch(&ssl->rlayer), p);
memcpy(p, &seq[2], 6);
header[11] = (unsigned char)(rec->length >> 8);
header[12] = (unsigned char)(rec->length & 0xff);
- if (!send && !SSL_USE_ETM(ssl) &&
+ if (!sending && !SSL_READ_ETM(ssl) &&
EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
ssl3_cbc_record_digest_supported(mac_ctx)) {
/*
EVP_MD_CTX_free(hmac);
return 0;
}
- if (!send && !SSL_USE_ETM(ssl) && FIPS_mode())
- if (!tls_fips_digest_extra(ssl->enc_read_ctx,
- mac_ctx, rec->input,
- rec->length, rec->orig_len)) {
- EVP_MD_CTX_free(hmac);
- return 0;
- }
}
EVP_MD_CTX_free(hmac);
*/
size_t mac_end = rec->length;
size_t mac_start = mac_end - md_size;
+ size_t in_mac;
/*
* scan_start contains the number of bytes that we can ignore because the
* MAC's position can only vary by 255 bytes.
*/
size_t scan_start = 0;
size_t i, j;
- size_t div_spoiler;
size_t rotate_offset;
OPENSSL_assert(rec->orig_len >= md_size);
/* This information is public so it's safe to branch based on it. */
if (rec->orig_len > md_size + 255 + 1)
scan_start = rec->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;
+ in_mac = 0;
+ rotate_offset = 0;
memset(rotated_mac, 0, md_size);
for (i = scan_start, j = 0; i < rec->orig_len; i++) {
- unsigned char mac_started = constant_time_ge_8_s(i, mac_start);
- unsigned char mac_ended = constant_time_ge_8_s(i, mac_end);
+ size_t mac_started = constant_time_eq_s(i, mac_start);
+ size_t mac_ended = constant_time_lt_s(i, mac_end);
unsigned char b = rec->data[i];
- rotated_mac[j++] |= b & mac_started & ~mac_ended;
+
+ in_mac |= mac_started;
+ in_mac &= mac_ended;
+ rotate_offset |= j & mac_started;
+ rotated_mac[j++] |= b & in_mac;
j &= constant_time_lt_s(j, md_size);
}
rr->data = rr->input;
rr->orig_len = rr->length;
- if (SSL_USE_ETM(s) && s->read_hash) {
+ if (SSL_READ_ETM(s) && s->read_hash) {
unsigned char *mac;
mac_size = EVP_MD_CTX_size(s->read_hash);
OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
#endif
/* r->length is now the compressed data plus mac */
- if ((sess != NULL) && !SSL_USE_ETM(s) &&
+ if ((sess != NULL) && !SSL_READ_ETM(s) &&
(s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) {
/* s->read_hash != NULL => mac_size != -1 */
unsigned char *mac = NULL;
}
/*
- * retrieve a buffered record that belongs to the current epoch, ie,
- * processed
+ * Retrieve a buffered record that belongs to the current epoch, i.e. processed
*/
#define dtls1_get_processed_record(s) \
dtls1_retrieve_buffered_record((s), \