diff options
Diffstat (limited to 'src/lib/libssl/t1_enc.c')
-rw-r--r-- | src/lib/libssl/t1_enc.c | 109 |
1 files changed, 81 insertions, 28 deletions
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 5d95419e7e..53570b2d4f 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.84 2016/03/06 14:52:15 beck Exp $ */ | 1 | /* $OpenBSD: t1_enc.c,v 1.85 2016/04/28 16:39:45 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 | * |
@@ -471,14 +471,26 @@ tls1_change_cipher_state_aead(SSL *s, char is_read, const unsigned char *key, | |||
471 | aead_ctx->variable_nonce_in_record = | 471 | aead_ctx->variable_nonce_in_record = |
472 | (s->s3->tmp.new_cipher->algorithm2 & | 472 | (s->s3->tmp.new_cipher->algorithm2 & |
473 | SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD) != 0; | 473 | SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD) != 0; |
474 | if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len != | 474 | aead_ctx->xor_fixed_nonce = |
475 | EVP_AEAD_nonce_length(aead)) { | 475 | s->s3->tmp.new_cipher->algorithm_enc == SSL_CHACHA20POLY1305; |
476 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, | ||
477 | ERR_R_INTERNAL_ERROR); | ||
478 | return (0); | ||
479 | } | ||
480 | aead_ctx->tag_len = EVP_AEAD_max_overhead(aead); | 476 | aead_ctx->tag_len = EVP_AEAD_max_overhead(aead); |
481 | 477 | ||
478 | if (aead_ctx->xor_fixed_nonce) { | ||
479 | if (aead_ctx->fixed_nonce_len != EVP_AEAD_nonce_length(aead) || | ||
480 | aead_ctx->variable_nonce_len > EVP_AEAD_nonce_length(aead)) { | ||
481 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, | ||
482 | ERR_R_INTERNAL_ERROR); | ||
483 | return (0); | ||
484 | } | ||
485 | } else { | ||
486 | if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len != | ||
487 | EVP_AEAD_nonce_length(aead)) { | ||
488 | SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, | ||
489 | ERR_R_INTERNAL_ERROR); | ||
490 | return (0); | ||
491 | } | ||
492 | } | ||
493 | |||
482 | return (1); | 494 | return (1); |
483 | } | 495 | } |
484 | 496 | ||
@@ -819,8 +831,8 @@ tls1_enc(SSL *s, int send) | |||
819 | 831 | ||
820 | if (aead) { | 832 | if (aead) { |
821 | unsigned char ad[13], *in, *out, nonce[16]; | 833 | unsigned char ad[13], *in, *out, nonce[16]; |
822 | unsigned nonce_used; | 834 | size_t out_len, pad_len = 0; |
823 | size_t out_len; | 835 | unsigned int nonce_used; |
824 | 836 | ||
825 | if (SSL_IS_DTLS(s)) { | 837 | if (SSL_IS_DTLS(s)) { |
826 | dtls1_build_sequence_number(ad, seq, | 838 | dtls1_build_sequence_number(ad, seq, |
@@ -834,13 +846,20 @@ tls1_enc(SSL *s, int send) | |||
834 | ad[9] = (unsigned char)(s->version >> 8); | 846 | ad[9] = (unsigned char)(s->version >> 8); |
835 | ad[10] = (unsigned char)(s->version); | 847 | ad[10] = (unsigned char)(s->version); |
836 | 848 | ||
837 | if (aead->fixed_nonce_len + | 849 | if (aead->variable_nonce_len > 8 || |
838 | aead->variable_nonce_len > sizeof(nonce) || | 850 | aead->variable_nonce_len > sizeof(nonce)) |
839 | aead->variable_nonce_len > 8) | 851 | return -1; |
840 | return -1; /* internal error - should never happen. */ | ||
841 | 852 | ||
842 | memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len); | 853 | if (aead->xor_fixed_nonce) { |
843 | nonce_used = aead->fixed_nonce_len; | 854 | if (aead->fixed_nonce_len > sizeof(nonce) || |
855 | aead->variable_nonce_len > aead->fixed_nonce_len) | ||
856 | return -1; /* Should never happen. */ | ||
857 | pad_len = aead->fixed_nonce_len - aead->variable_nonce_len; | ||
858 | } else { | ||
859 | if (aead->fixed_nonce_len + | ||
860 | aead->variable_nonce_len > sizeof(nonce)) | ||
861 | return -1; /* Should never happen. */ | ||
862 | } | ||
844 | 863 | ||
845 | if (send) { | 864 | if (send) { |
846 | size_t len = rec->length; | 865 | size_t len = rec->length; |
@@ -848,15 +867,30 @@ tls1_enc(SSL *s, int send) | |||
848 | in = rec->input; | 867 | in = rec->input; |
849 | out = rec->data; | 868 | out = rec->data; |
850 | 869 | ||
851 | /* | 870 | if (aead->xor_fixed_nonce) { |
852 | * When sending we use the sequence number as the | 871 | /* |
853 | * variable part of the nonce. | 872 | * The sequence number is left zero |
854 | */ | 873 | * padded, then xored with the fixed |
855 | if (aead->variable_nonce_len > 8) | 874 | * nonce. |
856 | return -1; | 875 | */ |
857 | memcpy(nonce + nonce_used, ad, | 876 | memset(nonce, 0, pad_len); |
858 | aead->variable_nonce_len); | 877 | memcpy(nonce + pad_len, ad, |
859 | nonce_used += aead->variable_nonce_len; | 878 | aead->variable_nonce_len); |
879 | for (i = 0; i < aead->fixed_nonce_len; i++) | ||
880 | nonce[i] ^= aead->fixed_nonce[i]; | ||
881 | nonce_used = aead->fixed_nonce_len; | ||
882 | } else { | ||
883 | /* | ||
884 | * When sending we use the sequence number as | ||
885 | * the variable part of the nonce. | ||
886 | */ | ||
887 | memcpy(nonce, aead->fixed_nonce, | ||
888 | aead->fixed_nonce_len); | ||
889 | nonce_used = aead->fixed_nonce_len; | ||
890 | memcpy(nonce + nonce_used, ad, | ||
891 | aead->variable_nonce_len); | ||
892 | nonce_used += aead->variable_nonce_len; | ||
893 | } | ||
860 | 894 | ||
861 | /* | 895 | /* |
862 | * In do_ssl3_write, rec->input is moved forward by | 896 | * In do_ssl3_write, rec->input is moved forward by |
@@ -890,10 +924,29 @@ tls1_enc(SSL *s, int send) | |||
890 | 924 | ||
891 | if (len < aead->variable_nonce_len) | 925 | if (len < aead->variable_nonce_len) |
892 | return 0; | 926 | return 0; |
893 | memcpy(nonce + nonce_used, | 927 | |
894 | aead->variable_nonce_in_record ? in : ad, | 928 | if (aead->xor_fixed_nonce) { |
895 | aead->variable_nonce_len); | 929 | /* |
896 | nonce_used += aead->variable_nonce_len; | 930 | * The sequence number is left zero |
931 | * padded, then xored with the fixed | ||
932 | * nonce. | ||
933 | */ | ||
934 | memset(nonce, 0, pad_len); | ||
935 | memcpy(nonce + pad_len, ad, | ||
936 | aead->variable_nonce_len); | ||
937 | for (i = 0; i < aead->fixed_nonce_len; i++) | ||
938 | nonce[i] ^= aead->fixed_nonce[i]; | ||
939 | nonce_used = aead->fixed_nonce_len; | ||
940 | } else { | ||
941 | memcpy(nonce, aead->fixed_nonce, | ||
942 | aead->fixed_nonce_len); | ||
943 | nonce_used = aead->fixed_nonce_len; | ||
944 | |||
945 | memcpy(nonce + nonce_used, | ||
946 | aead->variable_nonce_in_record ? in : ad, | ||
947 | aead->variable_nonce_len); | ||
948 | nonce_used += aead->variable_nonce_len; | ||
949 | } | ||
897 | 950 | ||
898 | if (aead->variable_nonce_in_record) { | 951 | if (aead->variable_nonce_in_record) { |
899 | in += aead->variable_nonce_len; | 952 | in += aead->variable_nonce_len; |