diff options
author | jsing <> | 2021-08-30 19:00:49 +0000 |
---|---|---|
committer | jsing <> | 2021-08-30 19:00:49 +0000 |
commit | abf6f6607dda2d28fb254cd45e519fec1091fc0d (patch) | |
tree | a1974e163ff741c9eaced5a834e2944d8aac3a5c | |
parent | 37732ca538fda5adb9e386dccdee41595d23c8d8 (diff) | |
download | openbsd-abf6f6607dda2d28fb254cd45e519fec1091fc0d.tar.gz openbsd-abf6f6607dda2d28fb254cd45e519fec1091fc0d.tar.bz2 openbsd-abf6f6607dda2d28fb254cd45e519fec1091fc0d.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@
-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 | } |