summaryrefslogtreecommitdiff
path: root/src/lib/libssl/t1_enc.c
diff options
context:
space:
mode:
authorjsing <>2020-10-03 17:35:17 +0000
committerjsing <>2020-10-03 17:35:17 +0000
commit3058247715ff89d092334e9137126e12b7220589 (patch)
treef4def91d73228cb651f854abf6bf23f4d3c22025 /src/lib/libssl/t1_enc.c
parent0f1f8d13de82c94a30254ca849b3933f8356101b (diff)
downloadopenbsd-3058247715ff89d092334e9137126e12b7220589.tar.gz
openbsd-3058247715ff89d092334e9137126e12b7220589.tar.bz2
openbsd-3058247715ff89d092334e9137126e12b7220589.zip
Reimplement the TLSv1.2 record handling for the read side.
This is the next step in replacing the TLSv1.2 record layer. The existing record handling code does decryption and processing in place, which is not ideal for various reasons, however it is retained for now as other code depends on this behaviour. Additionally, CBC requires special handling to avoid timing oracles - for now the existing timing safe code is largely retained. ok beck@ inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/t1_enc.c')
-rw-r--r--src/lib/libssl/t1_enc.c339
1 files changed, 5 insertions, 334 deletions
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index a66c82bdca..7a71a08434 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_enc.c,v 1.123 2020/08/30 15:40:20 jsing Exp $ */ 1/* $OpenBSD: t1_enc.c,v 1.124 2020/10/03 17:35:16 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 *
@@ -440,6 +440,10 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read,
440 if (!tls12_record_layer_set_read_cipher_hash(s->internal->rl, 440 if (!tls12_record_layer_set_read_cipher_hash(s->internal->rl,
441 cipher_ctx, mac_ctx, stream_mac)) 441 cipher_ctx, mac_ctx, stream_mac))
442 goto err; 442 goto err;
443
444 if (!tls12_record_layer_set_read_mac_key(s->internal->rl,
445 S3I(s)->read_mac_secret, mac_secret_size))
446 goto err;
443 } else { 447 } else {
444 if (stream_mac) 448 if (stream_mac)
445 s->internal->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; 449 s->internal->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
@@ -672,260 +676,6 @@ tls1_setup_key_block(SSL *s)
672 return (ret); 676 return (ret);
673} 677}
674 678
675/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
676 *
677 * Returns:
678 * 0: (in non-constant time) if the record is publically invalid (i.e. too
679 * short etc).
680 * 1: if the record's padding is valid / the encryption was successful.
681 * -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
682 * an internal error occured.
683 */
684int
685tls1_enc(SSL *s, int send)
686{
687 const SSL_AEAD_CTX *aead;
688 const EVP_CIPHER *enc;
689 EVP_CIPHER_CTX *ds;
690 SSL3_RECORD_INTERNAL *rec;
691 unsigned char *seq;
692 unsigned long l;
693 int bs, i, j, k, ret, mac_size = 0;
694
695 if (send) {
696 /* No longer supported. */
697 return -1;
698 } else {
699 aead = s->internal->aead_read_ctx;
700 rec = &S3I(s)->rrec;
701 seq = S3I(s)->read_sequence;
702 }
703
704 if (aead) {
705 unsigned char ad[13], *in, *out, nonce[16];
706 size_t out_len, pad_len = 0;
707 unsigned int nonce_used;
708
709 if (SSL_IS_DTLS(s)) {
710 dtls1_build_sequence_number(ad, seq,
711 send ? D1I(s)->w_epoch : D1I(s)->r_epoch);
712 } else {
713 memcpy(ad, seq, SSL3_SEQUENCE_SIZE);
714 tls1_record_sequence_increment(seq);
715 }
716
717 ad[8] = rec->type;
718 ad[9] = (unsigned char)(s->version >> 8);
719 ad[10] = (unsigned char)(s->version);
720
721 if (aead->variable_nonce_len > 8 ||
722 aead->variable_nonce_len > sizeof(nonce))
723 return -1;
724
725 if (aead->xor_fixed_nonce) {
726 if (aead->fixed_nonce_len > sizeof(nonce) ||
727 aead->variable_nonce_len > aead->fixed_nonce_len)
728 return -1; /* Should never happen. */
729 pad_len = aead->fixed_nonce_len - aead->variable_nonce_len;
730 } else {
731 if (aead->fixed_nonce_len +
732 aead->variable_nonce_len > sizeof(nonce))
733 return -1; /* Should never happen. */
734 }
735
736 if (send) {
737 size_t len = rec->length;
738 size_t eivlen = 0;
739 in = rec->input;
740 out = rec->data;
741
742 if (aead->xor_fixed_nonce) {
743 /*
744 * The sequence number is left zero
745 * padded, then xored with the fixed
746 * nonce.
747 */
748 memset(nonce, 0, pad_len);
749 memcpy(nonce + pad_len, ad,
750 aead->variable_nonce_len);
751 for (i = 0; i < aead->fixed_nonce_len; i++)
752 nonce[i] ^= aead->fixed_nonce[i];
753 nonce_used = aead->fixed_nonce_len;
754 } else {
755 /*
756 * When sending we use the sequence number as
757 * the variable part of the nonce.
758 */
759 memcpy(nonce, aead->fixed_nonce,
760 aead->fixed_nonce_len);
761 nonce_used = aead->fixed_nonce_len;
762 memcpy(nonce + nonce_used, ad,
763 aead->variable_nonce_len);
764 nonce_used += aead->variable_nonce_len;
765 }
766
767 /*
768 * In do_ssl3_write, rec->input is moved forward by
769 * variable_nonce_len in order to leave space for the
770 * variable nonce. Thus we can copy the sequence number
771 * bytes into place without overwriting any of the
772 * plaintext.
773 */
774 if (aead->variable_nonce_in_record) {
775 memcpy(out, ad, aead->variable_nonce_len);
776 len -= aead->variable_nonce_len;
777 eivlen = aead->variable_nonce_len;
778 }
779
780 ad[11] = len >> 8;
781 ad[12] = len & 0xff;
782
783 if (!EVP_AEAD_CTX_seal(&aead->ctx,
784 out + eivlen, &out_len, len + aead->tag_len, nonce,
785 nonce_used, in + eivlen, len, ad, sizeof(ad)))
786 return -1;
787 if (aead->variable_nonce_in_record)
788 out_len += aead->variable_nonce_len;
789 } else {
790 /* receive */
791 size_t len = rec->length;
792
793 if (rec->data != rec->input)
794 return -1; /* internal error - should never happen. */
795 out = in = rec->input;
796
797 if (len < aead->variable_nonce_len)
798 return 0;
799
800 if (aead->xor_fixed_nonce) {
801 /*
802 * The sequence number is left zero
803 * padded, then xored with the fixed
804 * nonce.
805 */
806 memset(nonce, 0, pad_len);
807 memcpy(nonce + pad_len, ad,
808 aead->variable_nonce_len);
809 for (i = 0; i < aead->fixed_nonce_len; i++)
810 nonce[i] ^= aead->fixed_nonce[i];
811 nonce_used = aead->fixed_nonce_len;
812 } else {
813 memcpy(nonce, aead->fixed_nonce,
814 aead->fixed_nonce_len);
815 nonce_used = aead->fixed_nonce_len;
816
817 memcpy(nonce + nonce_used,
818 aead->variable_nonce_in_record ? in : ad,
819 aead->variable_nonce_len);
820 nonce_used += aead->variable_nonce_len;
821 }
822
823 if (aead->variable_nonce_in_record) {
824 in += aead->variable_nonce_len;
825 len -= aead->variable_nonce_len;
826 out += aead->variable_nonce_len;
827 }
828
829 if (len < aead->tag_len)
830 return 0;
831 len -= aead->tag_len;
832
833 ad[11] = len >> 8;
834 ad[12] = len & 0xff;
835
836 if (!EVP_AEAD_CTX_open(&aead->ctx, out, &out_len, len,
837 nonce, nonce_used, in, len + aead->tag_len, ad,
838 sizeof(ad)))
839 return -1;
840
841 rec->data = rec->input = out;
842 }
843
844 rec->length = out_len;
845
846 return 1;
847 }
848
849 if (send) {
850 if (EVP_MD_CTX_md(s->internal->write_hash)) {
851 int n = EVP_MD_CTX_size(s->internal->write_hash);
852 OPENSSL_assert(n >= 0);
853 }
854 ds = s->internal->enc_write_ctx;
855 if (s->internal->enc_write_ctx == NULL)
856 enc = NULL;
857 else {
858 int ivlen = 0;
859 enc = EVP_CIPHER_CTX_cipher(s->internal->enc_write_ctx);
860 if (SSL_USE_EXPLICIT_IV(s) &&
861 EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
862 ivlen = EVP_CIPHER_iv_length(enc);
863 if (ivlen > 1) {
864 if (rec->data != rec->input) {
865#ifdef DEBUG
866 /* we can't write into the input stream:
867 * Can this ever happen?? (steve)
868 */
869 fprintf(stderr,
870 "%s:%d: rec->data != rec->input\n",
871 __FILE__, __LINE__);
872#endif
873 } else
874 arc4random_buf(rec->input, ivlen);
875 }
876 }
877 } else {
878 if (EVP_MD_CTX_md(s->read_hash)) {
879 int n = EVP_MD_CTX_size(s->read_hash);
880 OPENSSL_assert(n >= 0);
881 }
882 ds = s->enc_read_ctx;
883 if (s->enc_read_ctx == NULL)
884 enc = NULL;
885 else
886 enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
887 }
888
889 if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
890 memmove(rec->data, rec->input, rec->length);
891 rec->input = rec->data;
892 ret = 1;
893 } else {
894 l = rec->length;
895 bs = EVP_CIPHER_block_size(ds->cipher);
896
897 if (bs != 1 && send) {
898 i = bs - ((int)l % bs);
899
900 /* Add weird padding of upto 256 bytes */
901
902 /* we need to add 'i' padding bytes of value j */
903 j = i - 1;
904 for (k = (int)l; k < (int)(l + i); k++)
905 rec->input[k] = j;
906 l += i;
907 rec->length += i;
908 }
909
910 if (!send) {
911 if (l == 0 || l % bs != 0)
912 return 0;
913 }
914
915 i = EVP_Cipher(ds, rec->data, rec->input, l);
916 if ((EVP_CIPHER_flags(ds->cipher) &
917 EVP_CIPH_FLAG_CUSTOM_CIPHER) ? (i < 0) : (i == 0))
918 return -1; /* AEAD can fail to verify MAC */
919
920 ret = 1;
921 if (EVP_MD_CTX_md(s->read_hash) != NULL)
922 mac_size = EVP_MD_CTX_size(s->read_hash);
923 if ((bs != 1) && !send)
924 ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
925 }
926 return ret;
927}
928
929int 679int
930tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out) 680tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out)
931{ 681{
@@ -947,85 +697,6 @@ tls1_final_finish_mac(SSL *s, const char *str, int str_len, unsigned char *out)
947} 697}
948 698
949int 699int
950tls1_mac(SSL *ssl, unsigned char *md, int send)
951{
952 SSL3_RECORD_INTERNAL *rec;
953 unsigned char *seq;
954 EVP_MD_CTX *hash;
955 size_t md_size, orig_len;
956 EVP_MD_CTX hmac, *mac_ctx;
957 unsigned char header[13];
958 int stream_mac = (send ?
959 (ssl->internal->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) :
960 (ssl->internal->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
961 int t;
962
963 if (send) {
964 /* No longer supported. */
965 return -1;
966 } else {
967 rec = &(ssl->s3->internal->rrec);
968 seq = &(ssl->s3->internal->read_sequence[0]);
969 hash = ssl->read_hash;
970 }
971
972 t = EVP_MD_CTX_size(hash);
973 OPENSSL_assert(t >= 0);
974 md_size = t;
975
976 /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
977 if (stream_mac) {
978 mac_ctx = hash;
979 } else {
980 if (!EVP_MD_CTX_copy(&hmac, hash))
981 return -1;
982 mac_ctx = &hmac;
983 }
984
985 if (SSL_IS_DTLS(ssl))
986 dtls1_build_sequence_number(header, seq,
987 send ? D1I(ssl)->w_epoch : D1I(ssl)->r_epoch);
988 else
989 memcpy(header, seq, SSL3_SEQUENCE_SIZE);
990
991 orig_len = rec->length + md_size + rec->padding_length;
992
993 header[8] = rec->type;
994 header[9] = (unsigned char)(ssl->version >> 8);
995 header[10] = (unsigned char)(ssl->version);
996 header[11] = (rec->length) >> 8;
997 header[12] = (rec->length) & 0xff;
998
999 if (!send &&
1000 EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
1001 ssl3_cbc_record_digest_supported(mac_ctx)) {
1002 /* This is a CBC-encrypted record. We must avoid leaking any
1003 * timing-side channel information about how many blocks of
1004 * data we are hashing because that gives an attacker a
1005 * timing-oracle. */
1006 if (!ssl3_cbc_digest_record(mac_ctx,
1007 md, &md_size, header, rec->input,
1008 rec->length + md_size, orig_len,
1009 ssl->s3->internal->read_mac_secret,
1010 ssl->s3->internal->read_mac_secret_size))
1011 return -1;
1012 } else {
1013 EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
1014 EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
1015 t = EVP_DigestSignFinal(mac_ctx, md, &md_size);
1016 OPENSSL_assert(t > 0);
1017 }
1018
1019 if (!stream_mac)
1020 EVP_MD_CTX_cleanup(&hmac);
1021
1022 if (!SSL_IS_DTLS(ssl))
1023 tls1_record_sequence_increment(seq);
1024
1025 return (md_size);
1026}
1027
1028int
1029tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, 700tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
1030 int len) 701 int len)
1031{ 702{