diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/t1_enc.c | 157 |
1 files changed, 74 insertions, 83 deletions
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index f7bdeb3b9d..448eef274f 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c | |||
| @@ -667,12 +667,21 @@ err: | |||
| 667 | return(ret); | 667 | return(ret); |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | /* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. | ||
| 671 | * | ||
| 672 | * Returns: | ||
| 673 | * 0: (in non-constant time) if the record is publically invalid (i.e. too | ||
| 674 | * short etc). | ||
| 675 | * 1: if the record's padding is valid / the encryption was successful. | ||
| 676 | * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, | ||
| 677 | * an internal error occured. | ||
| 678 | */ | ||
| 670 | int tls1_enc(SSL *s, int send) | 679 | int tls1_enc(SSL *s, int send) |
| 671 | { | 680 | { |
| 672 | SSL3_RECORD *rec; | 681 | SSL3_RECORD *rec; |
| 673 | EVP_CIPHER_CTX *ds; | 682 | EVP_CIPHER_CTX *ds; |
| 674 | unsigned long l; | 683 | unsigned long l; |
| 675 | int bs,i,ii,j,k,pad=0; | 684 | int bs,i,j,k,pad=0,ret,mac_size=0; |
| 676 | const EVP_CIPHER *enc; | 685 | const EVP_CIPHER *enc; |
| 677 | 686 | ||
| 678 | if (send) | 687 | if (send) |
| @@ -729,11 +738,11 @@ int tls1_enc(SSL *s, int send) | |||
| 729 | printf("tls1_enc(%d)\n", send); | 738 | printf("tls1_enc(%d)\n", send); |
| 730 | #endif /* KSSL_DEBUG */ | 739 | #endif /* KSSL_DEBUG */ |
| 731 | 740 | ||
| 732 | if ((s->session == NULL) || (ds == NULL) || | 741 | if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) |
| 733 | (enc == NULL)) | ||
| 734 | { | 742 | { |
| 735 | memmove(rec->data,rec->input,rec->length); | 743 | memmove(rec->data,rec->input,rec->length); |
| 736 | rec->input=rec->data; | 744 | rec->input=rec->data; |
| 745 | ret = 1; | ||
| 737 | } | 746 | } |
| 738 | else | 747 | else |
| 739 | { | 748 | { |
| @@ -797,13 +806,13 @@ int tls1_enc(SSL *s, int send) | |||
| 797 | 806 | ||
| 798 | #ifdef KSSL_DEBUG | 807 | #ifdef KSSL_DEBUG |
| 799 | { | 808 | { |
| 800 | unsigned long ui; | 809 | unsigned long ui; |
| 801 | printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", | 810 | printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", |
| 802 | ds,rec->data,rec->input,l); | 811 | ds,rec->data,rec->input,l); |
| 803 | printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", | 812 | printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", |
| 804 | ds->buf_len, ds->cipher->key_len, | 813 | ds->buf_len, ds->cipher->key_len, |
| 805 | DES_KEY_SZ, DES_SCHEDULE_SZ, | 814 | DES_KEY_SZ, DES_SCHEDULE_SZ, |
| 806 | ds->cipher->iv_len); | 815 | ds->cipher->iv_len); |
| 807 | printf("\t\tIV: "); | 816 | printf("\t\tIV: "); |
| 808 | for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); | 817 | for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); |
| 809 | printf("\n"); | 818 | printf("\n"); |
| @@ -816,13 +825,7 @@ int tls1_enc(SSL *s, int send) | |||
| 816 | if (!send) | 825 | if (!send) |
| 817 | { | 826 | { |
| 818 | if (l == 0 || l%bs != 0) | 827 | if (l == 0 || l%bs != 0) |
| 819 | { | ||
| 820 | if (s->version >= TLS1_1_VERSION) | ||
| 821 | return -1; | ||
| 822 | SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); | ||
| 823 | ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); | ||
| 824 | return 0; | 828 | return 0; |
| 825 | } | ||
| 826 | } | 829 | } |
| 827 | 830 | ||
| 828 | i = EVP_Cipher(ds,rec->data,rec->input,l); | 831 | i = EVP_Cipher(ds,rec->data,rec->input,l); |
| @@ -839,68 +842,24 @@ int tls1_enc(SSL *s, int send) | |||
| 839 | 842 | ||
| 840 | #ifdef KSSL_DEBUG | 843 | #ifdef KSSL_DEBUG |
| 841 | { | 844 | { |
| 842 | unsigned long i; | 845 | unsigned long i; |
| 843 | printf("\trec->data="); | 846 | printf("\trec->data="); |
| 844 | for (i=0; i<l; i++) | 847 | for (i=0; i<l; i++) |
| 845 | printf(" %02x", rec->data[i]); printf("\n"); | 848 | printf(" %02x", rec->data[i]); printf("\n"); |
| 846 | } | 849 | } |
| 847 | #endif /* KSSL_DEBUG */ | 850 | #endif /* KSSL_DEBUG */ |
| 848 | 851 | ||
| 852 | ret = 1; | ||
| 853 | if (EVP_MD_CTX_md(s->read_hash) != NULL) | ||
| 854 | mac_size = EVP_MD_CTX_size(s->read_hash); | ||
| 849 | if ((bs != 1) && !send) | 855 | if ((bs != 1) && !send) |
| 850 | { | 856 | ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); |
| 851 | ii=i=rec->data[l-1]; /* padding_length */ | ||
| 852 | i++; | ||
| 853 | /* NB: if compression is in operation the first packet | ||
| 854 | * may not be of even length so the padding bug check | ||
| 855 | * cannot be performed. This bug workaround has been | ||
| 856 | * around since SSLeay so hopefully it is either fixed | ||
| 857 | * now or no buggy implementation supports compression | ||
| 858 | * [steve] | ||
| 859 | */ | ||
| 860 | if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) | ||
| 861 | && !s->expand) | ||
| 862 | { | ||
| 863 | /* First packet is even in size, so check */ | ||
| 864 | if ((memcmp(s->s3->read_sequence, | ||
| 865 | "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) | ||
| 866 | s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; | ||
| 867 | if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) | ||
| 868 | i--; | ||
| 869 | } | ||
| 870 | /* TLS 1.0 does not bound the number of padding bytes by the block size. | ||
| 871 | * All of them must have value 'padding_length'. */ | ||
| 872 | if (i > (int)rec->length) | ||
| 873 | { | ||
| 874 | /* Incorrect padding. SSLerr() and ssl3_alert are done | ||
| 875 | * by caller: we don't want to reveal whether this is | ||
| 876 | * a decryption error or a MAC verification failure | ||
| 877 | * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ | ||
| 878 | return -1; | ||
| 879 | } | ||
| 880 | for (j=(int)(l-i); j<(int)l; j++) | ||
| 881 | { | ||
| 882 | if (rec->data[j] != ii) | ||
| 883 | { | ||
| 884 | /* Incorrect padding */ | ||
| 885 | return -1; | ||
| 886 | } | ||
| 887 | } | ||
| 888 | rec->length -=i; | ||
| 889 | if (s->version >= TLS1_1_VERSION | ||
| 890 | && EVP_CIPHER_CTX_mode(ds) == EVP_CIPH_CBC_MODE) | ||
| 891 | { | ||
| 892 | if (bs > (int)rec->length) | ||
| 893 | return -1; | ||
| 894 | rec->data += bs; /* skip the explicit IV */ | ||
| 895 | rec->input += bs; | ||
| 896 | rec->length -= bs; | ||
| 897 | } | ||
| 898 | } | ||
| 899 | if (pad && !send) | 857 | if (pad && !send) |
| 900 | rec->length -= pad; | 858 | rec->length -= pad; |
| 901 | } | 859 | } |
| 902 | return(1); | 860 | return ret; |
| 903 | } | 861 | } |
| 862 | |||
| 904 | int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) | 863 | int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) |
| 905 | { | 864 | { |
| 906 | unsigned int ret; | 865 | unsigned int ret; |
| @@ -990,10 +949,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) | |||
| 990 | SSL3_RECORD *rec; | 949 | SSL3_RECORD *rec; |
| 991 | unsigned char *seq; | 950 | unsigned char *seq; |
| 992 | EVP_MD_CTX *hash; | 951 | EVP_MD_CTX *hash; |
| 993 | size_t md_size; | 952 | size_t md_size, orig_len; |
| 994 | int i; | 953 | int i; |
| 995 | EVP_MD_CTX hmac, *mac_ctx; | 954 | EVP_MD_CTX hmac, *mac_ctx; |
| 996 | unsigned char buf[5]; | 955 | unsigned char header[13]; |
| 997 | int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM)); | 956 | int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM)); |
| 998 | int t; | 957 | int t; |
| 999 | 958 | ||
| @@ -1014,12 +973,6 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) | |||
| 1014 | OPENSSL_assert(t >= 0); | 973 | OPENSSL_assert(t >= 0); |
| 1015 | md_size=t; | 974 | md_size=t; |
| 1016 | 975 | ||
| 1017 | buf[0]=rec->type; | ||
| 1018 | buf[1]=(unsigned char)(ssl->version>>8); | ||
| 1019 | buf[2]=(unsigned char)(ssl->version); | ||
| 1020 | buf[3]=rec->length>>8; | ||
| 1021 | buf[4]=rec->length&0xff; | ||
| 1022 | |||
| 1023 | /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ | 976 | /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ |
| 1024 | if (stream_mac) | 977 | if (stream_mac) |
| 1025 | { | 978 | { |
| @@ -1038,17 +991,55 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) | |||
| 1038 | s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); | 991 | s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p); |
| 1039 | memcpy (p,&seq[2],6); | 992 | memcpy (p,&seq[2],6); |
| 1040 | 993 | ||
| 1041 | EVP_DigestSignUpdate(mac_ctx,dtlsseq,8); | 994 | memcpy(header, dtlsseq, 8); |
| 1042 | } | 995 | } |
| 1043 | else | 996 | else |
| 1044 | EVP_DigestSignUpdate(mac_ctx,seq,8); | 997 | memcpy(header, seq, 8); |
| 1045 | 998 | ||
| 1046 | EVP_DigestSignUpdate(mac_ctx,buf,5); | 999 | /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */ |
| 1047 | EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); | 1000 | orig_len = rec->length+md_size+((unsigned int)rec->type>>8); |
| 1048 | t=EVP_DigestSignFinal(mac_ctx,md,&md_size); | 1001 | rec->type &= 0xff; |
| 1049 | OPENSSL_assert(t > 0); | 1002 | |
| 1003 | header[8]=rec->type; | ||
| 1004 | header[9]=(unsigned char)(ssl->version>>8); | ||
| 1005 | header[10]=(unsigned char)(ssl->version); | ||
| 1006 | header[11]=(rec->length)>>8; | ||
| 1007 | header[12]=(rec->length)&0xff; | ||
| 1008 | |||
| 1009 | if (!send && | ||
| 1010 | EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && | ||
| 1011 | ssl3_cbc_record_digest_supported(mac_ctx)) | ||
| 1012 | { | ||
| 1013 | /* This is a CBC-encrypted record. We must avoid leaking any | ||
| 1014 | * timing-side channel information about how many blocks of | ||
| 1015 | * data we are hashing because that gives an attacker a | ||
| 1016 | * timing-oracle. */ | ||
| 1017 | ssl3_cbc_digest_record( | ||
| 1018 | mac_ctx, | ||
| 1019 | md, &md_size, | ||
| 1020 | header, rec->input, | ||
| 1021 | rec->length + md_size, orig_len, | ||
| 1022 | ssl->s3->read_mac_secret, | ||
| 1023 | ssl->s3->read_mac_secret_size, | ||
| 1024 | 0 /* not SSLv3 */); | ||
| 1025 | } | ||
| 1026 | else | ||
| 1027 | { | ||
| 1028 | EVP_DigestSignUpdate(mac_ctx,header,sizeof(header)); | ||
| 1029 | EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length); | ||
| 1030 | t=EVP_DigestSignFinal(mac_ctx,md,&md_size); | ||
| 1031 | OPENSSL_assert(t > 0); | ||
| 1032 | #ifdef OPENSSL_FIPS | ||
| 1033 | if (!send && FIPS_mode()) | ||
| 1034 | tls_fips_digest_extra( | ||
| 1035 | ssl->enc_read_ctx, | ||
| 1036 | mac_ctx, rec->input, | ||
| 1037 | rec->length, orig_len); | ||
| 1038 | #endif | ||
| 1039 | } | ||
| 1050 | 1040 | ||
| 1051 | if (!stream_mac) EVP_MD_CTX_cleanup(&hmac); | 1041 | if (!stream_mac) |
| 1042 | EVP_MD_CTX_cleanup(&hmac); | ||
| 1052 | #ifdef TLS_DEBUG | 1043 | #ifdef TLS_DEBUG |
| 1053 | printf("sec="); | 1044 | printf("sec="); |
| 1054 | {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); } | 1045 | {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); } |
