summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_pkt.c
diff options
context:
space:
mode:
authorjsing <>2020-02-19 18:22:54 +0000
committerjsing <>2020-02-19 18:22:54 +0000
commit694792031e2b5887b3d073ebd3dabfa6e7a60fad (patch)
treec4b2636bacbae90e01b0d5b98ce6d9d3491875ee /src/lib/libssl/ssl_pkt.c
parent67f0f449c8bd353252d1a7498100c115256c6979 (diff)
downloadopenbsd-694792031e2b5887b3d073ebd3dabfa6e7a60fad.tar.gz
openbsd-694792031e2b5887b3d073ebd3dabfa6e7a60fad.tar.bz2
openbsd-694792031e2b5887b3d073ebd3dabfa6e7a60fad.zip
Refactor do_ssl3_write().
When empty fragments were added as a countermeasure against chosen plaintext attacks on CBC, it was done by adding a recursive call to do_ssl3_write(). This makes the code more complex and difficult to change. Split the record creation code into a separate ssl3_create_record() function, which do_ssl3_write() calls. In the case where an empty fragment is needed, ssl3_create_record() is simply called twice, removing the need for recursion. ok inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/ssl_pkt.c')
-rw-r--r--src/lib/libssl/ssl_pkt.c195
1 files changed, 98 insertions, 97 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 2a0dd68acb..e7bbf37bcd 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.16 2019/03/19 16:53:03 jsing Exp $ */ 1/* $OpenBSD: ssl_pkt.c,v 1.17 2020/02/19 18:22:54 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 *
@@ -120,7 +120,7 @@
120#include "bytestring.h" 120#include "bytestring.h"
121 121
122static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, 122static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
123 unsigned int len, int create_empty_fragment); 123 unsigned int len);
124static int ssl3_get_record(SSL *s); 124static int ssl3_get_record(SSL *s);
125 125
126/* 126/*
@@ -596,7 +596,7 @@ ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
596 else 596 else
597 nw = n; 597 nw = n;
598 598
599 i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); 599 i = do_ssl3_write(s, type, &(buf[tot]), nw);
600 if (i <= 0) { 600 if (i <= 0) {
601 S3I(s)->wnum = tot; 601 S3I(s)->wnum = tot;
602 return i; 602 return i;
@@ -620,44 +620,14 @@ ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
620} 620}
621 621
622static int 622static int
623do_ssl3_write(SSL *s, int type, const unsigned char *buf, 623ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf,
624 unsigned int len, int create_empty_fragment) 624 unsigned int len)
625{ 625{
626 unsigned char *p, *plen; 626 SSL3_RECORD *wr = &(S3I(s)->wrec);
627 int i, mac_size, clear = 0; 627 SSL_SESSION *sess = s->session;
628 int prefix_len = 0; 628 unsigned char *plen;
629 int eivlen; 629 int eivlen, mac_size;
630 size_t align; 630 int clear = 0;
631 SSL3_RECORD *wr;
632 SSL3_BUFFER *wb = &(S3I(s)->wbuf);
633 SSL_SESSION *sess;
634
635 if (wb->buf == NULL)
636 if (!ssl3_setup_write_buffer(s))
637 return -1;
638
639 /* first check if there is a SSL3_BUFFER still being written
640 * out. This will happen with non blocking IO */
641 if (wb->left != 0)
642 return (ssl3_write_pending(s, type, buf, len));
643
644 /* If we have an alert to send, lets send it */
645 if (S3I(s)->alert_dispatch) {
646 i = s->method->ssl_dispatch_alert(s);
647 if (i <= 0)
648 return (i);
649 /* if it went, fall through and send more stuff */
650 /* we may have released our buffer, so get it again */
651 if (wb->buf == NULL)
652 if (!ssl3_setup_write_buffer(s))
653 return -1;
654 }
655
656 if (len == 0 && !create_empty_fragment)
657 return 0;
658
659 wr = &(S3I(s)->wrec);
660 sess = s->session;
661 631
662 if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || 632 if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) ||
663 (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { 633 (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) {
@@ -669,56 +639,6 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf,
669 goto err; 639 goto err;
670 } 640 }
671 641
672 /*
673 * 'create_empty_fragment' is true only when this function calls
674 * itself.
675 */
676 if (!clear && !create_empty_fragment && !S3I(s)->empty_fragment_done) {
677 /*
678 * Countermeasure against known-IV weakness in CBC ciphersuites
679 * (see http://www.openssl.org/~bodo/tls-cbc.txt)
680 */
681 if (S3I(s)->need_empty_fragments &&
682 type == SSL3_RT_APPLICATION_DATA) {
683 /* recursive function call with 'create_empty_fragment' set;
684 * this prepares and buffers the data for an empty fragment
685 * (these 'prefix_len' bytes are sent out later
686 * together with the actual payload) */
687 prefix_len = do_ssl3_write(s, type, buf, 0, 1);
688 if (prefix_len <= 0)
689 goto err;
690
691 if (prefix_len >
692 (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
693 /* insufficient space */
694 SSLerror(s, ERR_R_INTERNAL_ERROR);
695 goto err;
696 }
697 }
698
699 S3I(s)->empty_fragment_done = 1;
700 }
701
702 if (create_empty_fragment) {
703 /* extra fragment would be couple of cipher blocks,
704 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
705 * if we want to align the real payload, then we can
706 * just pretent we simply have two headers. */
707 align = (size_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH;
708 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
709
710 p = wb->buf + align;
711 wb->offset = align;
712 } else if (prefix_len) {
713 p = wb->buf + wb->offset + prefix_len;
714 } else {
715 align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH;
716 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
717
718 p = wb->buf + align;
719 wb->offset = align;
720 }
721
722 /* write the header */ 642 /* write the header */
723 643
724 *(p++) = type&0xff; 644 *(p++) = type&0xff;
@@ -767,8 +687,7 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf,
767 * wr->data still points in the wb->buf */ 687 * wr->data still points in the wb->buf */
768 688
769 if (mac_size != 0) { 689 if (mac_size != 0) {
770 if (tls1_mac(s, 690 if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0)
771 &(p[wr->length + eivlen]), 1) < 0)
772 goto err; 691 goto err;
773 wr->length += mac_size; 692 wr->length += mac_size;
774 } 693 }
@@ -795,13 +714,95 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf,
795 wr->type=type; /* not needed but helps for debugging */ 714 wr->type=type; /* not needed but helps for debugging */
796 wr->length += SSL3_RT_HEADER_LENGTH; 715 wr->length += SSL3_RT_HEADER_LENGTH;
797 716
798 if (create_empty_fragment) { 717 return 1;
799 /* we are in a recursive call; 718
800 * just return the length, don't write out anything here 719 err:
720 return 0;
721}
722
723static int
724do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len)
725{
726 SSL3_RECORD *wr = &(S3I(s)->wrec);
727 SSL3_BUFFER *wb = &(S3I(s)->wbuf);
728 SSL_SESSION *sess = s->session;
729 unsigned char *p;
730 int i, clear = 0;
731 int prefix_len = 0;
732 size_t align;
733
734 if (wb->buf == NULL)
735 if (!ssl3_setup_write_buffer(s))
736 return -1;
737
738 /* first check if there is a SSL3_BUFFER still being written
739 * out. This will happen with non blocking IO */
740 if (wb->left != 0)
741 return (ssl3_write_pending(s, type, buf, len));
742
743 /* If we have an alert to send, lets send it */
744 if (S3I(s)->alert_dispatch) {
745 i = s->method->ssl_dispatch_alert(s);
746 if (i <= 0)
747 return (i);
748 /* if it went, fall through and send more stuff */
749 /* we may have released our buffer, so get it again */
750 if (wb->buf == NULL)
751 if (!ssl3_setup_write_buffer(s))
752 return -1;
753 }
754
755 if (len == 0)
756 return 0;
757
758 align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH;
759 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
760
761 p = wb->buf + align;
762 wb->offset = align;
763
764 if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) ||
765 (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) {
766 clear = s->internal->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */
767 }
768
769 if (!clear && !S3I(s)->empty_fragment_done) {
770 /*
771 * Countermeasure against known-IV weakness in CBC ciphersuites
772 * (see http://www.openssl.org/~bodo/tls-cbc.txt)
801 */ 773 */
802 return wr->length; 774 if (S3I(s)->need_empty_fragments &&
775 type == SSL3_RT_APPLICATION_DATA) {
776 /* extra fragment would be couple of cipher blocks,
777 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
778 * if we want to align the real payload, then we can
779 * just pretent we simply have two headers. */
780 align = (size_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH;
781 align = (-align) & (SSL3_ALIGN_PAYLOAD - 1);
782
783 p = wb->buf + align;
784 wb->offset = align;
785
786 if (!ssl3_create_record(s, p, type, buf, 0))
787 goto err;
788
789 prefix_len = wr->length;
790 if (prefix_len > (SSL3_RT_HEADER_LENGTH +
791 SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
792 /* insufficient space */
793 SSLerror(s, ERR_R_INTERNAL_ERROR);
794 goto err;
795 }
796
797 p = wb->buf + wb->offset + prefix_len;
798 }
799
800 S3I(s)->empty_fragment_done = 1;
803 } 801 }
804 802
803 if (!ssl3_create_record(s, p, type, buf, len))
804 goto err;
805
805 /* now let's set up wb */ 806 /* now let's set up wb */
806 wb->left = prefix_len + wr->length; 807 wb->left = prefix_len + wr->length;
807 808
@@ -1421,7 +1422,7 @@ ssl3_dispatch_alert(SSL *s)
1421 void (*cb)(const SSL *ssl, int type, int val) = NULL; 1422 void (*cb)(const SSL *ssl, int type, int val) = NULL;
1422 1423
1423 S3I(s)->alert_dispatch = 0; 1424 S3I(s)->alert_dispatch = 0;
1424 i = do_ssl3_write(s, SSL3_RT_ALERT, &S3I(s)->send_alert[0], 2, 0); 1425 i = do_ssl3_write(s, SSL3_RT_ALERT, &S3I(s)->send_alert[0], 2);
1425 if (i <= 0) { 1426 if (i <= 0) {
1426 S3I(s)->alert_dispatch = 1; 1427 S3I(s)->alert_dispatch = 1;
1427 } else { 1428 } else {