diff options
| author | jsing <> | 2021-08-30 19:00:49 +0000 |
|---|---|---|
| committer | jsing <> | 2021-08-30 19:00:49 +0000 |
| commit | b347f8c43ea97ba3f02662b050477c1d7c4ee6e4 (patch) | |
| tree | a1974e163ff741c9eaced5a834e2944d8aac3a5c /src | |
| parent | 447f1c2b595ba3da3932bbb5ec4313a80587c746 (diff) | |
| download | openbsd-b347f8c43ea97ba3f02662b050477c1d7c4ee6e4.tar.gz openbsd-b347f8c43ea97ba3f02662b050477c1d7c4ee6e4.tar.bz2 openbsd-b347f8c43ea97ba3f02662b050477c1d7c4ee6e4.zip | |
Move to an AEAD nonce allocated in the TLSv1.2 record layer.
There is little to gain by mallocing and freeing the AEAD nonce for each
record - move to an AEAD nonce allocated for the record layer, which
matches what we do for TLSv1.3.
ok inoguchi@ tb@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/tls12_record_layer.c | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/src/lib/libssl/tls12_record_layer.c b/src/lib/libssl/tls12_record_layer.c index 43edb6f0f5..f59364bb67 100644 --- a/src/lib/libssl/tls12_record_layer.c +++ b/src/lib/libssl/tls12_record_layer.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls12_record_layer.c,v 1.32 2021/06/19 16:52:47 jsing Exp $ */ | 1 | /* $OpenBSD: tls12_record_layer.c,v 1.33 2021/08/30 19:00:49 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -31,6 +31,9 @@ struct tls12_record_protection { | |||
| 31 | 31 | ||
| 32 | EVP_AEAD_CTX *aead_ctx; | 32 | EVP_AEAD_CTX *aead_ctx; |
| 33 | 33 | ||
| 34 | uint8_t *aead_nonce; | ||
| 35 | size_t aead_nonce_len; | ||
| 36 | |||
| 34 | uint8_t *aead_fixed_nonce; | 37 | uint8_t *aead_fixed_nonce; |
| 35 | size_t aead_fixed_nonce_len; | 38 | size_t aead_fixed_nonce_len; |
| 36 | 39 | ||
| @@ -63,6 +66,7 @@ tls12_record_protection_clear(struct tls12_record_protection *rp) | |||
| 63 | freezero(rp->aead_ctx, sizeof(*rp->aead_ctx)); | 66 | freezero(rp->aead_ctx, sizeof(*rp->aead_ctx)); |
| 64 | } | 67 | } |
| 65 | 68 | ||
| 69 | freezero(rp->aead_nonce, rp->aead_nonce_len); | ||
| 66 | freezero(rp->aead_fixed_nonce, rp->aead_fixed_nonce_len); | 70 | freezero(rp->aead_fixed_nonce, rp->aead_fixed_nonce_len); |
| 67 | 71 | ||
| 68 | EVP_CIPHER_CTX_free(rp->cipher_ctx); | 72 | EVP_CIPHER_CTX_free(rp->cipher_ctx); |
| @@ -423,8 +427,6 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl, | |||
| 423 | struct tls12_record_protection *rp, int is_write, CBS *mac_key, CBS *key, | 427 | struct tls12_record_protection *rp, int is_write, CBS *mac_key, CBS *key, |
| 424 | CBS *iv) | 428 | CBS *iv) |
| 425 | { | 429 | { |
| 426 | size_t aead_nonce_len; | ||
| 427 | |||
| 428 | if (!tls12_record_protection_unused(rp)) | 430 | if (!tls12_record_protection_unused(rp)) |
| 429 | return 0; | 431 | return 0; |
| 430 | 432 | ||
| @@ -443,21 +445,24 @@ tls12_record_layer_ccs_aead(struct tls12_record_layer *rl, | |||
| 443 | if (!CBS_stow(iv, &rp->aead_fixed_nonce, &rp->aead_fixed_nonce_len)) | 445 | if (!CBS_stow(iv, &rp->aead_fixed_nonce, &rp->aead_fixed_nonce_len)) |
| 444 | return 0; | 446 | return 0; |
| 445 | 447 | ||
| 446 | rp->aead_tag_len = EVP_AEAD_max_overhead(rl->aead); | 448 | rp->aead_nonce = calloc(1, EVP_AEAD_nonce_length(rl->aead)); |
| 447 | rp->aead_variable_nonce_len = 8; | 449 | if (rp->aead_nonce == NULL) |
| 450 | return 0; | ||
| 448 | 451 | ||
| 449 | aead_nonce_len = EVP_AEAD_nonce_length(rl->aead); | 452 | rp->aead_nonce_len = EVP_AEAD_nonce_length(rl->aead); |
| 453 | rp->aead_tag_len = EVP_AEAD_max_overhead(rl->aead); | ||
| 454 | rp->aead_variable_nonce_len = TLS12_RECORD_SEQ_NUM_LEN; | ||
| 450 | 455 | ||
| 451 | if (rp->aead_xor_nonces) { | 456 | if (rp->aead_xor_nonces) { |
| 452 | /* Fixed nonce length must match, variable must not exceed. */ | 457 | /* Fixed nonce length must match, variable must not exceed. */ |
| 453 | if (rp->aead_fixed_nonce_len != aead_nonce_len) | 458 | if (rp->aead_fixed_nonce_len != rp->aead_nonce_len) |
| 454 | return 0; | 459 | return 0; |
| 455 | if (rp->aead_variable_nonce_len > aead_nonce_len) | 460 | if (rp->aead_variable_nonce_len > rp->aead_nonce_len) |
| 456 | return 0; | 461 | return 0; |
| 457 | } else { | 462 | } else { |
| 458 | /* Concatenated nonce length must equal AEAD nonce length. */ | 463 | /* Concatenated nonce length must equal AEAD nonce length. */ |
| 459 | if (rp->aead_fixed_nonce_len + | 464 | if (rp->aead_fixed_nonce_len + |
| 460 | rp->aead_variable_nonce_len != aead_nonce_len) | 465 | rp->aead_variable_nonce_len != rp->aead_nonce_len) |
| 461 | return 0; | 466 | return 0; |
| 462 | } | 467 | } |
| 463 | 468 | ||
| @@ -796,8 +801,7 @@ tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb, | |||
| 796 | 801 | ||
| 797 | static int | 802 | static int |
| 798 | tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, | 803 | tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, |
| 799 | struct tls12_record_protection *rp, CBS *seq_num, | 804 | struct tls12_record_protection *rp, CBS *seq_num) |
| 800 | uint8_t **out, size_t *out_len) | ||
| 801 | { | 805 | { |
| 802 | CBB cbb; | 806 | CBB cbb; |
| 803 | 807 | ||
| @@ -805,7 +809,7 @@ tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, | |||
| 805 | return 0; | 809 | return 0; |
| 806 | 810 | ||
| 807 | /* Fixed nonce and variable nonce (sequence number) are concatenated. */ | 811 | /* Fixed nonce and variable nonce (sequence number) are concatenated. */ |
| 808 | if (!CBB_init(&cbb, 16)) | 812 | if (!CBB_init_fixed(&cbb, rp->aead_nonce, rp->aead_nonce_len)) |
| 809 | goto err; | 813 | goto err; |
| 810 | if (!CBB_add_bytes(&cbb, rp->aead_fixed_nonce, | 814 | if (!CBB_add_bytes(&cbb, rp->aead_fixed_nonce, |
| 811 | rp->aead_fixed_nonce_len)) | 815 | rp->aead_fixed_nonce_len)) |
| @@ -813,7 +817,7 @@ tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, | |||
| 813 | if (!CBB_add_bytes(&cbb, CBS_data(seq_num), | 817 | if (!CBB_add_bytes(&cbb, CBS_data(seq_num), |
| 814 | rp->aead_variable_nonce_len)) | 818 | rp->aead_variable_nonce_len)) |
| 815 | goto err; | 819 | goto err; |
| 816 | if (!CBB_finish(&cbb, out, out_len)) | 820 | if (!CBB_finish(&cbb, NULL, NULL)) |
| 817 | goto err; | 821 | goto err; |
| 818 | 822 | ||
| 819 | return 1; | 823 | return 1; |
| @@ -826,11 +830,8 @@ tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, | |||
| 826 | 830 | ||
| 827 | static int | 831 | static int |
| 828 | tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, | 832 | tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, |
| 829 | struct tls12_record_protection *rp, CBS *seq_num, | 833 | struct tls12_record_protection *rp, CBS *seq_num) |
| 830 | uint8_t **out, size_t *out_len) | ||
| 831 | { | 834 | { |
| 832 | uint8_t *nonce = NULL; | ||
| 833 | size_t nonce_len = 0; | ||
| 834 | uint8_t *pad; | 835 | uint8_t *pad; |
| 835 | CBB cbb; | 836 | CBB cbb; |
| 836 | int i; | 837 | int i; |
| @@ -839,12 +840,14 @@ tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, | |||
| 839 | return 0; | 840 | return 0; |
| 840 | if (rp->aead_fixed_nonce_len < rp->aead_variable_nonce_len) | 841 | if (rp->aead_fixed_nonce_len < rp->aead_variable_nonce_len) |
| 841 | return 0; | 842 | return 0; |
| 843 | if (rp->aead_fixed_nonce_len != rp->aead_nonce_len) | ||
| 844 | return 0; | ||
| 842 | 845 | ||
| 843 | /* | 846 | /* |
| 844 | * Variable nonce (sequence number) is right padded, before the fixed | 847 | * Variable nonce (sequence number) is right padded, before the fixed |
| 845 | * nonce is XOR'd in. | 848 | * nonce is XOR'd in. |
| 846 | */ | 849 | */ |
| 847 | if (!CBB_init(&cbb, 16)) | 850 | if (!CBB_init_fixed(&cbb, rp->aead_nonce, rp->aead_nonce_len)) |
| 848 | goto err; | 851 | goto err; |
| 849 | if (!CBB_add_space(&cbb, &pad, | 852 | if (!CBB_add_space(&cbb, &pad, |
| 850 | rp->aead_fixed_nonce_len - rp->aead_variable_nonce_len)) | 853 | rp->aead_fixed_nonce_len - rp->aead_variable_nonce_len)) |
| @@ -852,20 +855,16 @@ tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, | |||
| 852 | if (!CBB_add_bytes(&cbb, CBS_data(seq_num), | 855 | if (!CBB_add_bytes(&cbb, CBS_data(seq_num), |
| 853 | rp->aead_variable_nonce_len)) | 856 | rp->aead_variable_nonce_len)) |
| 854 | goto err; | 857 | goto err; |
| 855 | if (!CBB_finish(&cbb, &nonce, &nonce_len)) | 858 | if (!CBB_finish(&cbb, NULL, NULL)) |
| 856 | goto err; | 859 | goto err; |
| 857 | 860 | ||
| 858 | for (i = 0; i < rp->aead_fixed_nonce_len; i++) | 861 | for (i = 0; i < rp->aead_fixed_nonce_len; i++) |
| 859 | nonce[i] ^= rp->aead_fixed_nonce[i]; | 862 | rp->aead_nonce[i] ^= rp->aead_fixed_nonce[i]; |
| 860 | |||
| 861 | *out = nonce; | ||
| 862 | *out_len = nonce_len; | ||
| 863 | 863 | ||
| 864 | return 1; | 864 | return 1; |
| 865 | 865 | ||
| 866 | err: | 866 | err: |
| 867 | CBB_cleanup(&cbb); | 867 | CBB_cleanup(&cbb); |
| 868 | freezero(nonce, nonce_len); | ||
| 869 | 868 | ||
| 870 | return 0; | 869 | return 0; |
| 871 | } | 870 | } |
| @@ -890,28 +889,24 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, | |||
| 890 | size_t *out_len) | 889 | size_t *out_len) |
| 891 | { | 890 | { |
| 892 | struct tls12_record_protection *rp = rl->read; | 891 | struct tls12_record_protection *rp = rl->read; |
| 893 | uint8_t *header = NULL, *nonce = NULL; | 892 | uint8_t *header = NULL; |
| 894 | size_t header_len = 0, nonce_len = 0; | 893 | size_t header_len = 0; |
| 895 | uint8_t *plain; | 894 | uint8_t *plain; |
| 896 | size_t plain_len; | 895 | size_t plain_len; |
| 897 | CBS var_nonce; | 896 | CBS var_nonce; |
| 898 | int ret = 0; | 897 | int ret = 0; |
| 899 | 898 | ||
| 900 | /* XXX - move to nonce allocated in record layer, matching TLSv1.3 */ | ||
| 901 | if (rp->aead_xor_nonces) { | 899 | if (rp->aead_xor_nonces) { |
| 902 | if (!tls12_record_layer_aead_xored_nonce(rl, rp, | 900 | if (!tls12_record_layer_aead_xored_nonce(rl, rp, seq_num)) |
| 903 | seq_num, &nonce, &nonce_len)) | ||
| 904 | goto err; | 901 | goto err; |
| 905 | } else if (rp->aead_variable_nonce_in_record) { | 902 | } else if (rp->aead_variable_nonce_in_record) { |
| 906 | if (!CBS_get_bytes(fragment, &var_nonce, | 903 | if (!CBS_get_bytes(fragment, &var_nonce, |
| 907 | rp->aead_variable_nonce_len)) | 904 | rp->aead_variable_nonce_len)) |
| 908 | goto err; | 905 | goto err; |
| 909 | if (!tls12_record_layer_aead_concat_nonce(rl, rp, | 906 | if (!tls12_record_layer_aead_concat_nonce(rl, rp, &var_nonce)) |
| 910 | &var_nonce, &nonce, &nonce_len)) | ||
| 911 | goto err; | 907 | goto err; |
| 912 | } else { | 908 | } else { |
| 913 | if (!tls12_record_layer_aead_concat_nonce(rl, rp, | 909 | if (!tls12_record_layer_aead_concat_nonce(rl, rp, seq_num)) |
| 914 | seq_num, &nonce, &nonce_len)) | ||
| 915 | goto err; | 910 | goto err; |
| 916 | } | 911 | } |
| 917 | 912 | ||
| @@ -934,8 +929,8 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, | |||
| 934 | goto err; | 929 | goto err; |
| 935 | 930 | ||
| 936 | if (!EVP_AEAD_CTX_open(rp->aead_ctx, plain, out_len, plain_len, | 931 | if (!EVP_AEAD_CTX_open(rp->aead_ctx, plain, out_len, plain_len, |
| 937 | nonce, nonce_len, CBS_data(fragment), CBS_len(fragment), | 932 | rp->aead_nonce, rp->aead_nonce_len, CBS_data(fragment), |
| 938 | header, header_len)) { | 933 | CBS_len(fragment), header, header_len)) { |
| 939 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; | 934 | rl->alert_desc = SSL_AD_BAD_RECORD_MAC; |
| 940 | goto err; | 935 | goto err; |
| 941 | } | 936 | } |
| @@ -954,7 +949,6 @@ tls12_record_layer_open_record_protected_aead(struct tls12_record_layer *rl, | |||
| 954 | 949 | ||
| 955 | err: | 950 | err: |
| 956 | freezero(header, header_len); | 951 | freezero(header, header_len); |
| 957 | freezero(nonce, nonce_len); | ||
| 958 | 952 | ||
| 959 | return ret; | 953 | return ret; |
| 960 | } | 954 | } |
| @@ -1154,20 +1148,17 @@ tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, | |||
| 1154 | size_t content_len, CBB *out) | 1148 | size_t content_len, CBB *out) |
| 1155 | { | 1149 | { |
| 1156 | struct tls12_record_protection *rp = rl->write; | 1150 | struct tls12_record_protection *rp = rl->write; |
| 1157 | uint8_t *header = NULL, *nonce = NULL; | 1151 | uint8_t *header = NULL; |
| 1158 | size_t header_len = 0, nonce_len = 0; | 1152 | size_t header_len = 0; |
| 1159 | size_t enc_record_len, out_len; | 1153 | size_t enc_record_len, out_len; |
| 1160 | uint8_t *enc_data; | 1154 | uint8_t *enc_data; |
| 1161 | int ret = 0; | 1155 | int ret = 0; |
| 1162 | 1156 | ||
| 1163 | /* XXX - move to nonce allocated in record layer, matching TLSv1.3 */ | ||
| 1164 | if (rp->aead_xor_nonces) { | 1157 | if (rp->aead_xor_nonces) { |
| 1165 | if (!tls12_record_layer_aead_xored_nonce(rl, rp, | 1158 | if (!tls12_record_layer_aead_xored_nonce(rl, rp, seq_num)) |
| 1166 | seq_num, &nonce, &nonce_len)) | ||
| 1167 | goto err; | 1159 | goto err; |
| 1168 | } else { | 1160 | } else { |
| 1169 | if (!tls12_record_layer_aead_concat_nonce(rl, rp, | 1161 | if (!tls12_record_layer_aead_concat_nonce(rl, rp, seq_num)) |
| 1170 | seq_num, &nonce, &nonce_len)) | ||
| 1171 | goto err; | 1162 | goto err; |
| 1172 | } | 1163 | } |
| 1173 | 1164 | ||
| @@ -1191,7 +1182,8 @@ tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, | |||
| 1191 | goto err; | 1182 | goto err; |
| 1192 | 1183 | ||
| 1193 | if (!EVP_AEAD_CTX_seal(rp->aead_ctx, enc_data, &out_len, enc_record_len, | 1184 | if (!EVP_AEAD_CTX_seal(rp->aead_ctx, enc_data, &out_len, enc_record_len, |
| 1194 | nonce, nonce_len, content, content_len, header, header_len)) | 1185 | rp->aead_nonce, rp->aead_nonce_len, content, content_len, header, |
| 1186 | header_len)) | ||
| 1195 | goto err; | 1187 | goto err; |
| 1196 | 1188 | ||
| 1197 | if (out_len != enc_record_len) | 1189 | if (out_len != enc_record_len) |
| @@ -1201,7 +1193,6 @@ tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, | |||
| 1201 | 1193 | ||
| 1202 | err: | 1194 | err: |
| 1203 | freezero(header, header_len); | 1195 | freezero(header, header_len); |
| 1204 | freezero(nonce, nonce_len); | ||
| 1205 | 1196 | ||
| 1206 | return ret; | 1197 | return ret; |
| 1207 | } | 1198 | } |
