summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_pkt.c
diff options
context:
space:
mode:
authorjsing <>2020-07-30 16:53:01 +0000
committerjsing <>2020-07-30 16:53:01 +0000
commit8ff4976278b8287ec84e713ef782be6f4989ce06 (patch)
tree2261e7d086b3d5261d8ee4bae427be3d75698dd4 /src/lib/libssl/ssl_pkt.c
parentc83de9bf1a5deaa83030eac8eb7a2ce4749d120d (diff)
downloadopenbsd-8ff4976278b8287ec84e713ef782be6f4989ce06.tar.gz
openbsd-8ff4976278b8287ec84e713ef782be6f4989ce06.tar.bz2
openbsd-8ff4976278b8287ec84e713ef782be6f4989ce06.zip
Clean up and simplify some of the SSL3/DTLS1 record writing code.
This will allow for further changes to be made with less complexity and easier review. In particular, decide if we need an empty fragment early on and only do the alignment calculation once (rather than in two separate parts of the function. ok tb@ inoguchi@
Diffstat (limited to 'src/lib/libssl/ssl_pkt.c')
-rw-r--r--src/lib/libssl/ssl_pkt.c115
1 files changed, 58 insertions, 57 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 157dd9895b..02282778a2 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.24 2020/03/16 15:25:14 tb Exp $ */ 1/* $OpenBSD: ssl_pkt.c,v 1.25 2020/07/30 16:53:01 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 *
@@ -622,18 +622,15 @@ ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf,
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, mac_size; 625 int eivlen, mac_size = 0;
626 uint16_t version; 626 uint16_t version;
627 CBB cbb; 627 CBB cbb;
628 628
629 memset(&cbb, 0, sizeof(cbb)); 629 memset(&cbb, 0, sizeof(cbb));
630 630
631 if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || 631 if (sess != NULL && s->internal->enc_write_ctx != NULL &&
632 (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { 632 EVP_MD_CTX_md(s->internal->write_hash) != NULL) {
633 mac_size = 0; 633 if ((mac_size = EVP_MD_CTX_size(s->internal->write_hash)) < 0)
634 } else {
635 mac_size = EVP_MD_CTX_size(s->internal->write_hash);
636 if (mac_size < 0)
637 goto err; 634 goto err;
638 } 635 }
639 636
@@ -682,9 +679,11 @@ ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf,
682 memcpy(wr->data, wr->input, wr->length); 679 memcpy(wr->data, wr->input, wr->length);
683 wr->input = wr->data; 680 wr->input = wr->data;
684 681
685 /* we should still have the output to wr->data and the input 682 /*
683 * We should still have the output to wr->data and the input
686 * from wr->input. Length should be wr->length. 684 * from wr->input. Length should be wr->length.
687 * wr->data still points in the wb->buf */ 685 * wr->data still points in the wb->buf.
686 */
688 687
689 if (mac_size != 0) { 688 if (mac_size != 0) {
690 if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0) 689 if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0)
@@ -732,26 +731,29 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
732 SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); 731 SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf);
733 SSL_SESSION *sess = s->session; 732 SSL_SESSION *sess = s->session;
734 unsigned char *p; 733 unsigned char *p;
735 int i, clear = 0; 734 int need_empty_fragment = 0;
736 int prefix_len = 0; 735 int prefix_len = 0;
737 size_t align; 736 size_t align;
737 int ret;
738 738
739 if (wb->buf == NULL) 739 if (wb->buf == NULL)
740 if (!ssl3_setup_write_buffer(s)) 740 if (!ssl3_setup_write_buffer(s))
741 return -1; 741 return -1;
742 742
743 /* first check if there is a SSL3_BUFFER_INTERNAL still being written 743 /*
744 * out. This will happen with non blocking IO */ 744 * First check if there is a SSL3_BUFFER_INTERNAL still being written
745 * out. This will happen with non blocking IO.
746 */
745 if (wb->left != 0) 747 if (wb->left != 0)
746 return (ssl3_write_pending(s, type, buf, len)); 748 return (ssl3_write_pending(s, type, buf, len));
747 749
748 /* If we have an alert to send, lets send it */ 750 /* If we have an alert to send, let's send it. */
749 if (S3I(s)->alert_dispatch) { 751 if (S3I(s)->alert_dispatch) {
750 i = s->method->ssl_dispatch_alert(s); 752 if ((ret = s->method->ssl_dispatch_alert(s)) <= 0)
751 if (i <= 0) 753 return (ret);
752 return (i); 754 /* If it went, fall through and send more stuff. */
753 /* if it went, fall through and send more stuff */ 755
754 /* we may have released our buffer, so get it again */ 756 /* We may have released our buffer, if so get it again. */
755 if (wb->buf == NULL) 757 if (wb->buf == NULL)
756 if (!ssl3_setup_write_buffer(s)) 758 if (!ssl3_setup_write_buffer(s))
757 return -1; 759 return -1;
@@ -760,47 +762,44 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
760 if (len == 0) 762 if (len == 0)
761 return 0; 763 return 0;
762 764
765 /*
766 * Countermeasure against known-IV weakness in CBC ciphersuites
767 * (see http://www.openssl.org/~bodo/tls-cbc.txt). Note that this
768 * is unnecessary for AEAD.
769 */
770 if (sess != NULL && s->internal->enc_write_ctx != NULL &&
771 EVP_MD_CTX_md(s->internal->write_hash) != NULL) {
772 if (S3I(s)->need_empty_fragments &&
773 !S3I(s)->empty_fragment_done &&
774 type == SSL3_RT_APPLICATION_DATA)
775 need_empty_fragment = 1;
776 }
777
778 /*
779 * An extra fragment would be a couple of cipher blocks, which would
780 * be a multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real
781 * payload, then we can just simply pretend we have two headers.
782 */
763 align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; 783 align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH;
784 if (need_empty_fragment)
785 align += SSL3_RT_HEADER_LENGTH;
764 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); 786 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
765 787
766 p = wb->buf + align; 788 p = wb->buf + align;
767 wb->offset = align; 789 wb->offset = align;
768 790
769 if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || 791 if (need_empty_fragment) {
770 (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { 792 if (!ssl3_create_record(s, p, type, buf, 0))
771 clear = s->internal->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ 793 goto err;
772 }
773
774 if (!clear && !S3I(s)->empty_fragment_done) {
775 /*
776 * Countermeasure against known-IV weakness in CBC ciphersuites
777 * (see http://www.openssl.org/~bodo/tls-cbc.txt)
778 */
779 if (S3I(s)->need_empty_fragments &&
780 type == SSL3_RT_APPLICATION_DATA) {
781 /* extra fragment would be couple of cipher blocks,
782 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
783 * if we want to align the real payload, then we can
784 * just pretent we simply have two headers. */
785 align = (size_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH;
786 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
787
788 p = wb->buf + align;
789 wb->offset = align;
790
791 if (!ssl3_create_record(s, p, type, buf, 0))
792 goto err;
793
794 prefix_len = wr->length;
795 if (prefix_len > (SSL3_RT_HEADER_LENGTH +
796 SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
797 /* insufficient space */
798 SSLerror(s, ERR_R_INTERNAL_ERROR);
799 goto err;
800 }
801 794
802 p = wb->buf + wb->offset + prefix_len; 795 prefix_len = wr->length;
796 if (prefix_len > (SSL3_RT_HEADER_LENGTH +
797 SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
798 /* insufficient space */
799 SSLerror(s, ERR_R_INTERNAL_ERROR);
800 goto err;
803 } 801 }
802 p = wb->buf + wb->offset + prefix_len;
804 803
805 S3I(s)->empty_fragment_done = 1; 804 S3I(s)->empty_fragment_done = 1;
806 } 805 }
@@ -808,19 +807,21 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
808 if (!ssl3_create_record(s, p, type, buf, len)) 807 if (!ssl3_create_record(s, p, type, buf, len))
809 goto err; 808 goto err;
810 809
811 /* now let's set up wb */
812 wb->left = prefix_len + wr->length; 810 wb->left = prefix_len + wr->length;
813 811
814 /* memorize arguments so that ssl3_write_pending can detect 812 /*
815 * bad write retries later */ 813 * Memorize arguments so that ssl3_write_pending can detect
814 * bad write retries later.
815 */
816 S3I(s)->wpend_tot = len; 816 S3I(s)->wpend_tot = len;
817 S3I(s)->wpend_buf = buf; 817 S3I(s)->wpend_buf = buf;
818 S3I(s)->wpend_type = type; 818 S3I(s)->wpend_type = type;
819 S3I(s)->wpend_ret = len; 819 S3I(s)->wpend_ret = len;
820 820
821 /* we now just need to write the buffer */ 821 /* We now just need to write the buffer. */
822 return ssl3_write_pending(s, type, buf, len); 822 return ssl3_write_pending(s, type, buf, len);
823err: 823
824 err:
824 return -1; 825 return -1;
825} 826}
826 827