{
EVP_CIPHER_CTX *ciph_ctx;
EVP_PKEY *mac_key;
+ int enc = (rl->direction == OSSL_RECORD_DIRECTION_WRITE) ? 1 : 0;
if (level != OSSL_RECORD_PROTECTION_LEVEL_APPLICATION)
return OSSL_RECORD_RETURN_FATAL;
}
#ifndef OPENSSL_NO_COMP
if (comp != NULL) {
- rl->expand = COMP_CTX_new(comp->method);
- if (rl->expand == NULL) {
+ rl->compctx = COMP_CTX_new(comp->method);
+ if (rl->compctx == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
}
if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_GCM_MODE) {
- if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, NULL)
+ if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, NULL, enc)
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_GCM_SET_IV_FIXED,
(int)ivlen, iv) <= 0) {
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
} else if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) {
- if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, NULL, NULL)
+ if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, enc)
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, 12,
NULL) <= 0
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG,
(int)taglen, NULL) <= 0
|| EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_CCM_SET_IV_FIXED,
(int)ivlen, iv) <= 0
- || !EVP_DecryptInit_ex(ciph_ctx, NULL, NULL, key, NULL)) {
+ || !EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, enc)) {
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
} else {
- if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, iv)) {
+ if (!EVP_CipherInit_ex(ciph_ctx, ciph, NULL, key, iv, enc)) {
ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return OSSL_RECORD_RETURN_FATAL;
}
&& !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md))
return OSSL_RECORD_RETURN_FATAL;
+ /* Calculate the explict IV length */
+ if (RLAYER_USE_EXPLICIT_IV(rl)) {
+ int mode = EVP_CIPHER_CTX_get_mode(ciph_ctx);
+ int eivlen = 0;
+
+ if (mode == EVP_CIPH_CBC_MODE) {
+ eivlen = EVP_CIPHER_CTX_get_iv_length(ciph_ctx);
+ if (eivlen < 0) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG);
+ return OSSL_RECORD_RETURN_FATAL;
+ }
+ if (eivlen <= 1)
+ eivlen = 0;
+ } else if (mode == EVP_CIPH_GCM_MODE) {
+ /* Need explicit part of IV for GCM mode */
+ eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ } else if (mode == EVP_CIPH_CCM_MODE) {
+ eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
+ }
+ rl->eivlen = (size_t)eivlen;
+ }
+
return OSSL_RECORD_RETURN_SUCCESS;
}
defltlen = ssl_get_max_send_fragment(s)
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
#ifndef OPENSSL_NO_COMP
- if (ssl_allow_compression(s))
+ if (tls_allow_compression(rl))
defltlen += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
if (!(rl->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
* If OPENSSL_NO_COMP is defined then SSL3_RT_MAX_ENCRYPTED_LENGTH
* does not include the compression overhead anyway.
*/
- if (rl->expand == NULL)
+ if (rl->compctx == NULL)
len -= SSL3_RT_MAX_COMPRESSED_OVERHEAD;
#endif
return 1;
}
+static int tls_do_compress(OSSL_RECORD_LAYER *rl, SSL3_RECORD *wr)
+{
+#ifndef OPENSSL_NO_COMP
+ int i;
+
+ i = COMP_compress_block(rl->compctx, wr->data,
+ (int)(wr->length + SSL3_RT_MAX_COMPRESSED_OVERHEAD),
+ wr->input, (int)wr->length);
+ if (i < 0)
+ return 0;
+
+ wr->length = i;
+ wr->input = wr->data;
+ return 1;
+#else
+ return 0;
+#endif
+}
+
int tls_do_uncompress(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
#ifndef OPENSSL_NO_COMP
if (rec->comp == NULL)
return 0;
- i = COMP_expand_block(rl->expand, rec->comp, SSL3_RT_MAX_PLAIN_LENGTH,
+ i = COMP_expand_block(rl->compctx, rec->comp, SSL3_RT_MAX_PLAIN_LENGTH,
rec->data, (int)rec->length);
if (i < 0)
return 0;
/* Shared by tlsany_meth, ssl3_meth and tls1_meth */
int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec)
{
- if (rl->expand != NULL) {
+ if (rl->compctx != NULL) {
if (rec->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW,
SSL_R_COMPRESSED_LENGTH_TOO_LONG);
EVP_CIPHER_CTX_free(rl->enc_ctx);
EVP_MD_CTX_free(rl->md_ctx);
#ifndef OPENSSL_NO_COMP
- COMP_CTX_free(rl->expand);
+ COMP_CTX_free(rl->compctx);
#endif
if (rl->version == SSL3_VERSION)
WPACKET *thispkt;
SSL3_RECORD *thiswr;
unsigned char *recordstart;
- int mac_size, clear = 0, ret = 0;
- int eivlen = 0;
+ int mac_size = 0, ret = 0;
size_t align = 0;
SSL3_BUFFER *wb;
- SSL_SESSION *sess;
size_t len, wpinited = 0;
size_t j, prefix = 0;
int using_ktls;
OSSL_RECORD_TEMPLATE prefixtempl;
OSSL_RECORD_TEMPLATE *thistempl;
- sess = s->session;
-
- if ((sess == NULL)
- || (s->enc_write_ctx == NULL)
- || (EVP_MD_CTX_get0_md(s->write_hash) == NULL)) {
- clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */
- mac_size = 0;
+ /*
+ * TODO(RECLAYER): Remove this once SSLv3/TLSv1.3/DTLS crypto has
+ * been moved to the new write record layer.
+ */
+ if (rl->version == SSL3_VERSION
+ || rl->version == TLS1_3_VERSION
+ || rl->isdtls) {
+ SSL_SESSION *sess = s->session;
+
+ if ((sess == NULL)
+ || (s->enc_write_ctx == NULL)
+ || (EVP_MD_CTX_get0_md(s->write_hash) == NULL)) {
+ mac_size = 0;
+ } else {
+ mac_size = EVP_MD_CTX_get_size(s->write_hash);
+ if (mac_size < 0) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
} else {
- mac_size = EVP_MD_CTX_get_size(s->write_hash);
- if (mac_size < 0) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
+ if (rl->md_ctx != NULL && EVP_MD_CTX_get0_md(rl->md_ctx) != NULL) {
+ mac_size = EVP_MD_CTX_get_size(rl->md_ctx);
+ if (mac_size < 0) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
}
}
-
- /*
- * 'create_empty_fragment' is true only when we have recursively called
- * ourselves.
- * Do we need to do that recursion in order to add an empty record prefix?
- */
+ /* Do we need to add an empty record prefix? */
prefix = rl->need_empty_fragments
- && !clear
&& templates[0].type == SSL3_RT_APPLICATION_DATA;
/*
}
}
- if (!using_ktls) {
- /* Explicit IV length, block ciphers appropriate version flag */
- if (s->enc_write_ctx != NULL && RLAYER_USE_EXPLICIT_IV(rl)
- && rl->version != TLS1_3_VERSION) {
- int mode = EVP_CIPHER_CTX_get_mode(s->enc_write_ctx);
- if (mode == EVP_CIPH_CBC_MODE) {
- eivlen = EVP_CIPHER_CTX_get_iv_length(s->enc_write_ctx);
- if (eivlen < 0) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG);
- goto err;
- }
- if (eivlen <= 1)
- eivlen = 0;
- } else if (mode == EVP_CIPH_GCM_MODE) {
- /* Need explicit part of IV for GCM mode */
- eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
- } else if (mode == EVP_CIPH_CCM_MODE) {
- eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
- }
- }
- }
-
/* Clear our SSL3_RECORD structures */
memset(wr, 0, sizeof(wr));
for (j = 0; j < numtempl + prefix; j++) {
SSL3_RECORD_set_rec_version(thiswr, thistempl->version);
maxcomplen = thistempl->buflen;
- if (s->compress != NULL)
+ if (rl->compctx != NULL)
maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
/*
&& (!WPACKET_put_bytes_u8(thispkt, rectype)
|| !WPACKET_put_bytes_u16(thispkt, thistempl->version)
|| !WPACKET_start_sub_packet_u16(thispkt)
- || (eivlen > 0
- && !WPACKET_allocate_bytes(thispkt, eivlen, NULL))
+ || (rl->eivlen > 0
+ && !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL))
|| (maxcomplen > 0
&& !WPACKET_reserve_bytes(thispkt, maxcomplen,
&compressdata)))) {
*/
/* first we compress */
- if (s->compress != NULL) {
- if (!ssl3_do_compress(s, thiswr)
+ if (rl->compctx != NULL) {
+ if (!tls_do_compress(rl, thiswr)
|| !WPACKET_allocate_bytes(thispkt, thiswr->length, NULL)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE);
goto err;
if (!using_ktls && !rl->use_etm && mac_size != 0) {
unsigned char *mac;
- if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
- || !ssl->method->ssl3_enc->mac(s, thiswr, mac, 1)) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
+ /*
+ * TODO(RECLAYER): Remove this once SSLv3/TLSv1.3/DTLS crypto has
+ * been moved to the new write record layer.
+ */
+ if (rl->version == SSL3_VERSION
+ || rl->version == TLS1_3_VERSION
+ || rl->isdtls) {
+ if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+ || !ssl->method->ssl3_enc->mac(s, thiswr, mac, 1)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ } else {
+ if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+ || !rl->funcs->mac(rl, thiswr, mac, 1)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
}
}
} else {
if (!using_ktls) {
if (prefix) {
- if (ssl->method->ssl3_enc->enc(s, wr, 1, 1, NULL, mac_size) < 1) {
+ /*
+ * TODO(RECLAYER): Remove this once SSLv3 crypto has been moved
+ * to the new write record layer.
+ */
+ if (rl->version == SSL3_VERSION) {
+ if (ssl->method->ssl3_enc->enc(s, wr, 1, 1, NULL, mac_size) < 1) {
+ if (!ossl_statem_in_error(s))
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ } else {
+ if (rl->funcs->cipher(rl, wr, 1, 1, NULL, mac_size) < 1) {
+ if (!ossl_statem_in_error(s))
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+ }
+ /*
+ * TODO(RECLAYER): Remove this once SSLv3/TLSv1.3/DTLS crypto has
+ * been moved to the new write record layer.
+ */
+ if (rl->version == SSL3_VERSION
+ || rl->version == TLS1_3_VERSION
+ || rl->isdtls) {
+ if (ssl->method->ssl3_enc->enc(s, wr + prefix, numtempl, 1, NULL,
+ mac_size) < 1) {
+ if (!ossl_statem_in_error(s))
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ } else {
+ if (rl->funcs->cipher(rl, wr + prefix, numtempl, 1, NULL,
+ mac_size) < 1) {
if (!ossl_statem_in_error(s))
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
- }
- if (ssl->method->ssl3_enc->enc(s, wr + prefix, numtempl, 1, NULL,
- mac_size) < 1) {
- if (!ossl_statem_in_error(s))
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
}
}
}
if (rl->use_etm && mac_size != 0) {
unsigned char *mac;
- if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
- || !ssl->method->ssl3_enc->mac(s, thiswr, mac, 1)) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- goto err;
+ /*
+ * TODO(RECLAYER): Remove this once SSLv3/TLSv1.3/DTLS crypto has
+ * been moved to the new write record layer.
+ */
+ if (rl->version == SSL3_VERSION
+ || rl->version == TLS1_3_VERSION
+ || rl->isdtls) {
+ if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+ || !ssl->method->ssl3_enc->mac(s, thiswr, mac, 1)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ } else {
+ if (!WPACKET_allocate_bytes(thispkt, mac_size, &mac)
+ || !rl->funcs->mac(rl, thiswr, mac, 1)) {
+ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
}
+
SSL3_RECORD_add_length(thiswr, mac_size);
}
size_t len, size_t fraglen)
{
#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
- /* TODO(RECLAYER): REMOVE ME */
- SSL_CONNECTION *s = rl->cbarg;
-
if (type == SSL3_RT_APPLICATION_DATA
&& len >= 4 * fraglen
- && s->compress == NULL
+ && rl->compctx == NULL
&& rl->msg_callback == NULL
&& !rl->use_etm
&& RLAYER_USE_EXPLICIT_IV(rl)
- && !BIO_get_ktls_send(s->wbio)
- && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(s->enc_write_ctx))
+ && !BIO_get_ktls_send(rl->bio)
+ && (EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(rl->enc_ctx))
& EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) != 0)
return 1;
#endif
size_t i;
size_t totlen;
SSL3_BUFFER *wb;
- /* TODO(RECLAYER): Remove me */
- SSL_CONNECTION *s = rl->cbarg;
unsigned char aad[13];
EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
size_t packlen;
* multiblock write in the call to tls_setup_write_buffer() - the different
* buffer sizes will be spotted and the buffer reallocated.
*/
- packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
- EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE,
- (int)templates[0].buflen, NULL);
+ packlen = EVP_CIPHER_CTX_ctrl(rl->enc_ctx,
+ EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE,
+ (int)templates[0].buflen, NULL);
packlen *= numtempl;
if (!tls_setup_write_buffer(rl, 1, packlen, packlen)) {
/* RLAYERfatal() already called */
wb = &rl->wbuf[0];
mb_param.interleave = numtempl;
- memcpy(aad, s->rlayer.write_sequence, 8);
+ memcpy(aad, rl->sequence, 8);
aad[8] = templates[0].type;
aad[9] = (unsigned char)(templates[0].version >> 8);
aad[10] = (unsigned char)(templates[0].version);
mb_param.inp = aad;
mb_param.len = totlen;
- packleni = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
- EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
- sizeof(mb_param), &mb_param);
+ packleni = EVP_CIPHER_CTX_ctrl(rl->enc_ctx,
+ EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
+ sizeof(mb_param), &mb_param);
packlen = (size_t)packleni;
if (packleni <= 0 || packlen > wb->len) { /* never happens */
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
mb_param.inp = templates[0].buf;
mb_param.len = totlen;
- if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+ if (EVP_CIPHER_CTX_ctrl(rl->enc_ctx,
EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
sizeof(mb_param), &mb_param) <= 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return -1;
}
- s->rlayer.write_sequence[7] += mb_param.interleave;
- if (s->rlayer.write_sequence[7] < mb_param.interleave) {
+ rl->sequence[7] += mb_param.interleave;
+ if (rl->sequence[7] < mb_param.interleave) {
int j = 6;
- while (j >= 0 && (++s->rlayer.write_sequence[j--]) == 0) ;
+ while (j >= 0 && (++rl->sequence[j--]) == 0) ;
}
wb->offset = 0;