summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2020-08-09 16:02:58 +0000
committerjsing <>2020-08-09 16:02:58 +0000
commitb3dbcda2404dbe31481fae8d6817cbc0a3362031 (patch)
tree1bce0663b79d08c1bf38e62b09a464cbcc5bd6ce /src
parente770512d626b103f809dfdecb1ba758a92b5f57b (diff)
downloadopenbsd-b3dbcda2404dbe31481fae8d6817cbc0a3362031.tar.gz
openbsd-b3dbcda2404dbe31481fae8d6817cbc0a3362031.tar.bz2
openbsd-b3dbcda2404dbe31481fae8d6817cbc0a3362031.zip
Use CBB more correctly when writing SSL3/DTLS records.
Previously we used CBB to build the record headers, but not the entire record. Use CBB_init_fixed() upfront, then build the record header and add space for the record content. However, in order to do this we need to determine the length of the record upfront. This simplifies the code, removes a number of manual bounds checks and makes way for further improvements. ok inoguchi@ tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/d1_pkt.c68
-rw-r--r--src/lib/libssl/ssl_pkt.c90
2 files changed, 92 insertions, 66 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c
index 5bbdf5f738..dd7d9aa76c 100644
--- a/src/lib/libssl/d1_pkt.c
+++ b/src/lib/libssl/d1_pkt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: d1_pkt.c,v 1.77 2020/08/09 15:46:28 jsing Exp $ */ 1/* $OpenBSD: d1_pkt.c,v 1.78 2020/08/09 16:02:58 jsing Exp $ */
2/* 2/*
3 * DTLS implementation written by Nagendra Modadugu 3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -1177,10 +1177,12 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
1177 SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); 1177 SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec);
1178 SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); 1178 SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf);
1179 SSL_SESSION *sess = s->session; 1179 SSL_SESSION *sess = s->session;
1180 int eivlen = 0, mac_size = 0; 1180 int block_size = 0, eivlen = 0, mac_size = 0;
1181 unsigned char *p; 1181 size_t pad_len, record_len;
1182 CBB cbb, fragment;
1183 size_t out_len;
1184 uint8_t *p;
1182 int ret; 1185 int ret;
1183 CBB cbb;
1184 1186
1185 memset(&cbb, 0, sizeof(cbb)); 1187 memset(&cbb, 0, sizeof(cbb));
1186 1188
@@ -1209,12 +1211,38 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
1209 goto err; 1211 goto err;
1210 } 1212 }
1211 1213
1214 /* Explicit IV length. */
1215 if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
1216 int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx);
1217 if (mode == EVP_CIPH_CBC_MODE) {
1218 eivlen = EVP_CIPHER_CTX_iv_length(s->internal->enc_write_ctx);
1219 if (eivlen <= 1)
1220 eivlen = 0;
1221 }
1222 } else if (s->internal->aead_write_ctx != NULL &&
1223 s->internal->aead_write_ctx->variable_nonce_in_record) {
1224 eivlen = s->internal->aead_write_ctx->variable_nonce_len;
1225 }
1226
1227 /* Determine length of record fragment. */
1228 record_len = eivlen + len + mac_size;
1229 if (s->internal->enc_write_ctx != NULL) {
1230 block_size = EVP_CIPHER_CTX_block_size(s->internal->enc_write_ctx);
1231 if (block_size <= 0 || block_size > EVP_MAX_BLOCK_LENGTH)
1232 goto err;
1233 if (block_size > 1) {
1234 pad_len = block_size - (record_len % block_size);
1235 record_len += pad_len;
1236 }
1237 } else if (s->internal->aead_write_ctx != NULL) {
1238 record_len += s->internal->aead_write_ctx->tag_len;
1239 }
1240
1212 /* DTLS implements explicit IV, so no need for empty fragments. */ 1241 /* DTLS implements explicit IV, so no need for empty fragments. */
1213 1242
1214 p = wb->buf;
1215 wb->offset = 0; 1243 wb->offset = 0;
1216 1244
1217 if (!CBB_init_fixed(&cbb, p, DTLS1_RT_HEADER_LENGTH)) 1245 if (!CBB_init_fixed(&cbb, wb->buf, wb->len))
1218 goto err; 1246 goto err;
1219 1247
1220 /* Write the header. */ 1248 /* Write the header. */
@@ -1226,21 +1254,10 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
1226 goto err; 1254 goto err;
1227 if (!CBB_add_bytes(&cbb, &(S3I(s)->write_sequence[2]), 6)) 1255 if (!CBB_add_bytes(&cbb, &(S3I(s)->write_sequence[2]), 6))
1228 goto err; 1256 goto err;
1229 1257 if (!CBB_add_u16_length_prefixed(&cbb, &fragment))
1230 p += DTLS1_RT_HEADER_LENGTH; 1258 goto err;
1231 1259 if (!CBB_add_space(&fragment, &p, record_len))
1232 /* Explicit IV length. */ 1260 goto err;
1233 if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
1234 int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx);
1235 if (mode == EVP_CIPH_CBC_MODE) {
1236 eivlen = EVP_CIPHER_CTX_iv_length(s->internal->enc_write_ctx);
1237 if (eivlen <= 1)
1238 eivlen = 0;
1239 }
1240 } else if (s->internal->aead_write_ctx != NULL &&
1241 s->internal->aead_write_ctx->variable_nonce_in_record) {
1242 eivlen = s->internal->aead_write_ctx->variable_nonce_len;
1243 }
1244 1261
1245 wr->type = type; 1262 wr->type = type;
1246 wr->data = p + eivlen; 1263 wr->data = p + eivlen;
@@ -1262,11 +1279,14 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
1262 if (tls1_enc(s, 1) != 1) 1279 if (tls1_enc(s, 1) != 1)
1263 goto err; 1280 goto err;
1264 1281
1265 if (!CBB_add_u16(&cbb, wr->length)) 1282 if (wr->length != record_len)
1266 goto err; 1283 goto err;
1267 if (!CBB_finish(&cbb, NULL, NULL)) 1284
1285 if (!CBB_finish(&cbb, NULL, &out_len))
1268 goto err; 1286 goto err;
1269 1287
1288 wb->left = out_len;
1289
1270 /* 1290 /*
1271 * We should now have wr->data pointing to the encrypted data, 1291 * We should now have wr->data pointing to the encrypted data,
1272 * which is wr->length long. 1292 * which is wr->length long.
@@ -1276,8 +1296,6 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
1276 1296
1277 tls1_record_sequence_increment(S3I(s)->write_sequence); 1297 tls1_record_sequence_increment(S3I(s)->write_sequence);
1278 1298
1279 wb->left = wr->length;
1280
1281 /* 1299 /*
1282 * Memorize arguments so that ssl3_write_pending can detect 1300 * Memorize arguments so that ssl3_write_pending can detect
1283 * bad write retries later. 1301 * bad write retries later.
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 39ce46381d..da059915f2 100644
--- a/src/lib/libssl/ssl_pkt.c
+++ b/src/lib/libssl/ssl_pkt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_pkt.c,v 1.28 2020/08/02 07:33:15 jsing Exp $ */ 1/* $OpenBSD: ssl_pkt.c,v 1.29 2020/08/09 16:02:58 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -617,15 +617,15 @@ ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
617} 617}
618 618
619static int 619static int
620ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type, 620ssl3_create_record(SSL *s, CBB *cbb, uint16_t version, uint8_t type,
621 const unsigned char *buf, unsigned int len) 621 const unsigned char *buf, unsigned int len)
622{ 622{
623 SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); 623 SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec);
624 SSL_SESSION *sess = s->session; 624 SSL_SESSION *sess = s->session;
625 int eivlen = 0, mac_size = 0; 625 int block_size = 0, eivlen = 0, mac_size = 0;
626 CBB cbb; 626 size_t pad_len, record_len;
627 627 CBB fragment;
628 memset(&cbb, 0, sizeof(cbb)); 628 uint8_t *p;
629 629
630 if (sess != NULL && s->internal->enc_write_ctx != NULL && 630 if (sess != NULL && s->internal->enc_write_ctx != NULL &&
631 EVP_MD_CTX_md(s->internal->write_hash) != NULL) { 631 EVP_MD_CTX_md(s->internal->write_hash) != NULL) {
@@ -633,17 +633,6 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
633 goto err; 633 goto err;
634 } 634 }
635 635
636 if (!CBB_init_fixed(&cbb, p, SSL3_RT_HEADER_LENGTH))
637 goto err;
638
639 /* Write the header. */
640 if (!CBB_add_u8(&cbb, type))
641 goto err;
642 if (!CBB_add_u16(&cbb, version))
643 goto err;
644
645 p += SSL3_RT_HEADER_LENGTH;
646
647 /* Explicit IV length. */ 636 /* Explicit IV length. */
648 if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { 637 if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
649 int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx); 638 int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx);
@@ -657,6 +646,31 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
657 eivlen = s->internal->aead_write_ctx->variable_nonce_len; 646 eivlen = s->internal->aead_write_ctx->variable_nonce_len;
658 } 647 }
659 648
649 /* Determine length of record fragment. */
650 record_len = eivlen + len + mac_size;
651 if (s->internal->enc_write_ctx != NULL) {
652 block_size = EVP_CIPHER_CTX_block_size(s->internal->enc_write_ctx);
653 if (block_size <= 0 || block_size > EVP_MAX_BLOCK_LENGTH)
654 goto err;
655 if (block_size > 1) {
656 pad_len = block_size - (record_len % block_size);
657 record_len += pad_len;
658 }
659 } else if (s->internal->aead_write_ctx != NULL) {
660 record_len += s->internal->aead_write_ctx->tag_len;
661 }
662
663 /* Write the header. */
664 if (!CBB_add_u8(cbb, type))
665 goto err;
666 if (!CBB_add_u16(cbb, version))
667 goto err;
668 if (!CBB_add_u16_length_prefixed(cbb, &fragment))
669 goto err;
670 if (!CBB_add_space(&fragment, &p, record_len))
671 goto err;
672
673 /* Set up the record. */
660 wr->type = type; 674 wr->type = type;
661 wr->data = p + eivlen; 675 wr->data = p + eivlen;
662 wr->length = (int)len; 676 wr->length = (int)len;
@@ -677,10 +691,10 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
677 if (tls1_enc(s, 1) != 1) 691 if (tls1_enc(s, 1) != 1)
678 goto err; 692 goto err;
679 693
680 /* record length after mac and block padding */ 694 if (wr->length != record_len)
681 if (!CBB_add_u16(&cbb, wr->length))
682 goto err; 695 goto err;
683 if (!CBB_finish(&cbb, NULL, NULL)) 696
697 if (!CBB_flush(cbb))
684 goto err; 698 goto err;
685 699
686 /* 700 /*
@@ -693,24 +707,22 @@ ssl3_create_record(SSL *s, unsigned char *p, uint16_t version, uint8_t type,
693 return 1; 707 return 1;
694 708
695 err: 709 err:
696 CBB_cleanup(&cbb);
697
698 return 0; 710 return 0;
699} 711}
700 712
701static int 713static int
702do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) 714do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
703{ 715{
704 SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec);
705 SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); 716 SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf);
706 SSL_SESSION *sess = s->session; 717 SSL_SESSION *sess = s->session;
707 unsigned char *p;
708 int need_empty_fragment = 0; 718 int need_empty_fragment = 0;
709 int prefix_len = 0; 719 size_t align, out_len;
710 uint16_t version; 720 uint16_t version;
711 size_t align; 721 CBB cbb;
712 int ret; 722 int ret;
713 723
724 memset(&cbb, 0, sizeof(cbb));
725
714 if (wb->buf == NULL) 726 if (wb->buf == NULL)
715 if (!ssl3_setup_write_buffer(s)) 727 if (!ssl3_setup_write_buffer(s))
716 return -1; 728 return -1;
@@ -768,30 +780,24 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
768 if (need_empty_fragment) 780 if (need_empty_fragment)
769 align += SSL3_RT_HEADER_LENGTH; 781 align += SSL3_RT_HEADER_LENGTH;
770 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); 782 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
771
772 p = wb->buf + align;
773 wb->offset = align; 783 wb->offset = align;
774 784
775 if (need_empty_fragment) { 785 if (!CBB_init_fixed(&cbb, wb->buf + align, wb->len - align))
776 if (!ssl3_create_record(s, p, version, type, buf, 0)) 786 goto err;
777 goto err;
778 787
779 prefix_len = wr->length; 788 if (need_empty_fragment) {
780 if (prefix_len > (SSL3_RT_HEADER_LENGTH + 789 if (!ssl3_create_record(s, &cbb, version, type, buf, 0))
781 SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
782 /* insufficient space */
783 SSLerror(s, ERR_R_INTERNAL_ERROR);
784 goto err; 790 goto err;
785 }
786 p = wb->buf + wb->offset + prefix_len;
787
788 S3I(s)->empty_fragment_done = 1; 791 S3I(s)->empty_fragment_done = 1;
789 } 792 }
790 793
791 if (!ssl3_create_record(s, p, version, type, buf, len)) 794 if (!ssl3_create_record(s, &cbb, version, type, buf, len))
792 goto err; 795 goto err;
793 796
794 wb->left = prefix_len + wr->length; 797 if (!CBB_finish(&cbb, NULL, &out_len))
798 goto err;
799
800 wb->left = out_len;
795 801
796 /* 802 /*
797 * Memorize arguments so that ssl3_write_pending can detect 803 * Memorize arguments so that ssl3_write_pending can detect
@@ -806,6 +812,8 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
806 return ssl3_write_pending(s, type, buf, len); 812 return ssl3_write_pending(s, type, buf, len);
807 813
808 err: 814 err:
815 CBB_cleanup(&cbb);
816
809 return -1; 817 return -1;
810} 818}
811 819