diff options
author | jsing <> | 2021-01-19 19:07:39 +0000 |
---|---|---|
committer | jsing <> | 2021-01-19 19:07:39 +0000 |
commit | e99005f53b351b3c662664891d988adaa02c4d0b (patch) | |
tree | 05f28e11dfa0755554909e35637b6e3f6f3a076b /src | |
parent | eb720c630d40660f4bf00d58faa6f6d59ba82ea2 (diff) | |
download | openbsd-e99005f53b351b3c662664891d988adaa02c4d0b.tar.gz openbsd-e99005f53b351b3c662664891d988adaa02c4d0b.tar.bz2 openbsd-e99005f53b351b3c662664891d988adaa02c4d0b.zip |
Add code to handle change of cipher state in the new TLSv1.2 record layer.
This provides the basic framework for handling change of cipher state in
the new TLSv1.2 record layer, creating new record protection. In the DTLS
case we retain the previous write record protection and can switch back to
it when retransmitting. This will allow the record layer to start owning
sequence numbers and encryption/decryption state.
ok inoguchi@ tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/d1_both.c | 11 | ||||
-rw-r--r-- | src/lib/libssl/d1_pkt.c | 4 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 12 | ||||
-rw-r--r-- | src/lib/libssl/t1_enc.c | 20 | ||||
-rw-r--r-- | src/lib/libssl/tls12_record_layer.c | 107 |
5 files changed, 137 insertions, 17 deletions
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c index d6bf6dfd1b..8c4fec589f 100644 --- a/src/lib/libssl/d1_both.c +++ b/src/lib/libssl/d1_both.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_both.c,v 1.64 2021/01/19 18:51:08 jsing Exp $ */ | 1 | /* $OpenBSD: d1_both.c,v 1.65 2021/01/19 19:07:39 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
@@ -1055,9 +1055,8 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | |||
1055 | /* restore state in which the message was originally sent */ | 1055 | /* restore state in which the message was originally sent */ |
1056 | s->session = frag->msg_header.saved_retransmit_state.session; | 1056 | s->session = frag->msg_header.saved_retransmit_state.session; |
1057 | D1I(s)->w_epoch = frag->msg_header.saved_retransmit_state.epoch; | 1057 | D1I(s)->w_epoch = frag->msg_header.saved_retransmit_state.epoch; |
1058 | if (!tls12_record_layer_set_write_cipher_hash(s->internal->rl, | 1058 | |
1059 | frag->msg_header.saved_retransmit_state.enc_write_ctx, | 1059 | if (!tls12_record_layer_use_write_epoch(s->internal->rl, D1I(s)->w_epoch)) |
1060 | frag->msg_header.saved_retransmit_state.write_hash, 0)) | ||
1061 | return 0; | 1060 | return 0; |
1062 | 1061 | ||
1063 | if (frag->msg_header.saved_retransmit_state.epoch == | 1062 | if (frag->msg_header.saved_retransmit_state.epoch == |
@@ -1074,8 +1073,8 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | |||
1074 | /* restore current state */ | 1073 | /* restore current state */ |
1075 | s->session = saved_state.session; | 1074 | s->session = saved_state.session; |
1076 | D1I(s)->w_epoch = saved_state.epoch; | 1075 | D1I(s)->w_epoch = saved_state.epoch; |
1077 | if (!tls12_record_layer_set_write_cipher_hash(s->internal->rl, | 1076 | |
1078 | s->internal->enc_write_ctx, s->internal->write_hash, 0)) | 1077 | if (!tls12_record_layer_use_write_epoch(s->internal->rl, D1I(s)->w_epoch)) |
1079 | return 0; | 1078 | return 0; |
1080 | 1079 | ||
1081 | if (frag->msg_header.saved_retransmit_state.epoch == | 1080 | if (frag->msg_header.saved_retransmit_state.epoch == |
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 14ff8221be..bde13c99e5 100644 --- a/src/lib/libssl/d1_pkt.c +++ b/src/lib/libssl/d1_pkt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: d1_pkt.c,v 1.89 2021/01/19 18:57:09 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.90 2021/01/19 19:07:39 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * DTLS implementation written by Nagendra Modadugu | 3 | * DTLS implementation written by Nagendra Modadugu |
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
@@ -1105,7 +1105,6 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1105 | goto err; | 1105 | goto err; |
1106 | 1106 | ||
1107 | tls12_record_layer_set_version(s->internal->rl, s->version); | 1107 | tls12_record_layer_set_version(s->internal->rl, s->version); |
1108 | tls12_record_layer_set_write_epoch(s->internal->rl, D1I(s)->w_epoch); | ||
1109 | 1108 | ||
1110 | if (!tls12_record_layer_seal_record(s->internal->rl, type, buf, len, &cbb)) | 1109 | if (!tls12_record_layer_seal_record(s->internal->rl, type, buf, len, &cbb)) |
1111 | goto err; | 1110 | goto err; |
@@ -1245,6 +1244,7 @@ dtls1_reset_seq_numbers(SSL *s, int rw) | |||
1245 | memset(S3I(s)->read_sequence, 0, sizeof(S3I(s)->read_sequence)); | 1244 | memset(S3I(s)->read_sequence, 0, sizeof(S3I(s)->read_sequence)); |
1246 | } else { | 1245 | } else { |
1247 | D1I(s)->w_epoch++; | 1246 | D1I(s)->w_epoch++; |
1247 | tls12_record_layer_set_write_epoch(s->internal->rl, D1I(s)->w_epoch); | ||
1248 | memcpy(D1I(s)->last_write_sequence, S3I(s)->write_sequence, | 1248 | memcpy(D1I(s)->last_write_sequence, S3I(s)->write_sequence, |
1249 | sizeof(S3I(s)->write_sequence)); | 1249 | sizeof(S3I(s)->write_sequence)); |
1250 | memset(S3I(s)->write_sequence, 0, sizeof(S3I(s)->write_sequence)); | 1250 | memset(S3I(s)->write_sequence, 0, sizeof(S3I(s)->write_sequence)); |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index e0a4c49ccb..5a3e3ff726 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_locl.h,v 1.314 2021/01/19 18:57:09 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.315 2021/01/19 19:07:39 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 | * |
@@ -485,6 +485,10 @@ void tls12_record_layer_set_version(struct tls12_record_layer *rl, | |||
485 | uint16_t version); | 485 | uint16_t version); |
486 | void tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, | 486 | void tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, |
487 | uint16_t epoch); | 487 | uint16_t epoch); |
488 | int tls12_record_layer_use_write_epoch(struct tls12_record_layer *rl, | ||
489 | uint16_t epoch); | ||
490 | void tls12_record_layer_write_epoch_done(struct tls12_record_layer *rl, | ||
491 | uint16_t epoch); | ||
488 | void tls12_record_layer_clear_read_state(struct tls12_record_layer *rl); | 492 | void tls12_record_layer_clear_read_state(struct tls12_record_layer *rl); |
489 | void tls12_record_layer_clear_write_state(struct tls12_record_layer *rl); | 493 | void tls12_record_layer_clear_write_state(struct tls12_record_layer *rl); |
490 | void tls12_record_layer_set_read_seq_num(struct tls12_record_layer *rl, | 494 | void tls12_record_layer_set_read_seq_num(struct tls12_record_layer *rl, |
@@ -501,6 +505,12 @@ int tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl, | |||
501 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac); | 505 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac); |
502 | int tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl, | 506 | int tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl, |
503 | const uint8_t *mac_key, size_t mac_key_len); | 507 | const uint8_t *mac_key, size_t mac_key_len); |
508 | int tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl, | ||
509 | const uint8_t *mac_key, size_t mac_key_len, const uint8_t *key, | ||
510 | size_t key_len, const uint8_t *iv, size_t iv_len); | ||
511 | int tls12_record_layer_change_write_cipher_state(struct tls12_record_layer *rl, | ||
512 | const uint8_t *mac_key, size_t mac_key_len, const uint8_t *key, | ||
513 | size_t key_len, const uint8_t *iv, size_t iv_len); | ||
504 | int tls12_record_layer_open_record(struct tls12_record_layer *rl, | 514 | int tls12_record_layer_open_record(struct tls12_record_layer *rl, |
505 | uint8_t *buf, size_t buf_len, uint8_t **out, size_t *out_len); | 515 | uint8_t *buf, size_t buf_len, uint8_t **out, size_t *out_len); |
506 | int tls12_record_layer_seal_record(struct tls12_record_layer *rl, | 516 | int tls12_record_layer_seal_record(struct tls12_record_layer *rl, |
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 6c376be2e0..875aae36b0 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.128 2021/01/07 15:32:59 jsing Exp $ */ | 1 | /* $OpenBSD: t1_enc.c,v 1.129 2021/01/19 19:07:39 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 | * |
@@ -562,7 +562,21 @@ tls1_change_cipher_state(SSL *s, int which) | |||
562 | 562 | ||
563 | if (key_block - S3I(s)->hs.key_block != S3I(s)->hs.key_block_len) { | 563 | if (key_block - S3I(s)->hs.key_block != S3I(s)->hs.key_block_len) { |
564 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 564 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
565 | goto err2; | 565 | goto err; |
566 | } | ||
567 | |||
568 | if (is_read) { | ||
569 | if (!tls12_record_layer_change_read_cipher_state(s->internal->rl, | ||
570 | mac_secret, mac_secret_size, key, key_len, iv, iv_len)) | ||
571 | goto err; | ||
572 | tls12_record_layer_set_read_seq_num(s->internal->rl, | ||
573 | S3I(s)->read_sequence); | ||
574 | } else { | ||
575 | if (!tls12_record_layer_change_write_cipher_state(s->internal->rl, | ||
576 | mac_secret, mac_secret_size, key, key_len, iv, iv_len)) | ||
577 | goto err; | ||
578 | tls12_record_layer_set_write_seq_num(s->internal->rl, | ||
579 | S3I(s)->write_sequence); | ||
566 | } | 580 | } |
567 | 581 | ||
568 | if (aead != NULL) { | 582 | if (aead != NULL) { |
@@ -573,7 +587,7 @@ tls1_change_cipher_state(SSL *s, int which) | |||
573 | return tls1_change_cipher_state_cipher(s, is_read, | 587 | return tls1_change_cipher_state_cipher(s, is_read, |
574 | mac_secret, mac_secret_size, key, key_len, iv, iv_len); | 588 | mac_secret, mac_secret_size, key, key_len, iv, iv_len); |
575 | 589 | ||
576 | err2: | 590 | err: |
577 | return (0); | 591 | return (0); |
578 | } | 592 | } |
579 | 593 | ||
diff --git a/src/lib/libssl/tls12_record_layer.c b/src/lib/libssl/tls12_record_layer.c index affc5375a2..83d71d1c7a 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.12 2021/01/19 18:57:09 jsing Exp $ */ | 1 | /* $OpenBSD: tls12_record_layer.c,v 1.13 2021/01/19 19:07:39 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -132,8 +132,13 @@ struct tls12_record_layer { | |||
132 | 132 | ||
133 | uint8_t alert_desc; | 133 | uint8_t alert_desc; |
134 | 134 | ||
135 | /* Pointers to active record protection (memory is not owned). */ | ||
135 | struct tls12_record_protection *read; | 136 | struct tls12_record_protection *read; |
136 | struct tls12_record_protection *write; | 137 | struct tls12_record_protection *write; |
138 | |||
139 | struct tls12_record_protection *read_current; | ||
140 | struct tls12_record_protection *write_current; | ||
141 | struct tls12_record_protection *write_previous; | ||
137 | }; | 142 | }; |
138 | 143 | ||
139 | struct tls12_record_layer * | 144 | struct tls12_record_layer * |
@@ -143,11 +148,14 @@ tls12_record_layer_new(void) | |||
143 | 148 | ||
144 | if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL) | 149 | if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL) |
145 | goto err; | 150 | goto err; |
146 | if ((rl->read = tls12_record_protection_new()) == NULL) | 151 | if ((rl->read_current = tls12_record_protection_new()) == NULL) |
147 | goto err; | 152 | goto err; |
148 | if ((rl->write = tls12_record_protection_new()) == NULL) | 153 | if ((rl->write_current = tls12_record_protection_new()) == NULL) |
149 | goto err; | 154 | goto err; |
150 | 155 | ||
156 | rl->read = rl->read_current; | ||
157 | rl->write = rl->write_current; | ||
158 | |||
151 | return rl; | 159 | return rl; |
152 | 160 | ||
153 | err: | 161 | err: |
@@ -162,8 +170,9 @@ tls12_record_layer_free(struct tls12_record_layer *rl) | |||
162 | if (rl == NULL) | 170 | if (rl == NULL) |
163 | return; | 171 | return; |
164 | 172 | ||
165 | tls12_record_protection_free(rl->read); | 173 | tls12_record_protection_free(rl->read_current); |
166 | tls12_record_protection_free(rl->write); | 174 | tls12_record_protection_free(rl->write_current); |
175 | tls12_record_protection_free(rl->write_previous); | ||
167 | 176 | ||
168 | freezero(rl, sizeof(struct tls12_record_layer)); | 177 | freezero(rl, sizeof(struct tls12_record_layer)); |
169 | } | 178 | } |
@@ -226,6 +235,37 @@ tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, uint16_t epoch | |||
226 | rl->write->epoch = epoch; | 235 | rl->write->epoch = epoch; |
227 | } | 236 | } |
228 | 237 | ||
238 | int | ||
239 | tls12_record_layer_use_write_epoch(struct tls12_record_layer *rl, uint16_t epoch) | ||
240 | { | ||
241 | if (rl->write->epoch == epoch) | ||
242 | return 1; | ||
243 | |||
244 | if (rl->write_current->epoch == epoch) { | ||
245 | rl->write = rl->write_current; | ||
246 | return 1; | ||
247 | } | ||
248 | |||
249 | if (rl->write_previous != NULL && rl->write_previous->epoch == epoch) { | ||
250 | rl->write = rl->write_previous; | ||
251 | return 1; | ||
252 | } | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | void | ||
258 | tls12_record_layer_write_epoch_done(struct tls12_record_layer *rl, uint16_t epoch) | ||
259 | { | ||
260 | if (rl->write_previous == NULL || rl->write_previous->epoch != epoch) | ||
261 | return; | ||
262 | |||
263 | rl->write = rl->write_current; | ||
264 | |||
265 | tls12_record_protection_free(rl->write_previous); | ||
266 | rl->write_previous = NULL; | ||
267 | } | ||
268 | |||
229 | static void | 269 | static void |
230 | tls12_record_layer_set_read_state(struct tls12_record_layer *rl, | 270 | tls12_record_layer_set_read_state(struct tls12_record_layer *rl, |
231 | SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, | 271 | SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, |
@@ -263,6 +303,9 @@ tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) | |||
263 | { | 303 | { |
264 | tls12_record_layer_set_write_state(rl, NULL, NULL, NULL, 0); | 304 | tls12_record_layer_set_write_state(rl, NULL, NULL, NULL, 0); |
265 | rl->write->seq_num = NULL; | 305 | rl->write->seq_num = NULL; |
306 | |||
307 | tls12_record_protection_free(rl->write_previous); | ||
308 | rl->write_previous = NULL; | ||
266 | } | 309 | } |
267 | 310 | ||
268 | void | 311 | void |
@@ -337,6 +380,60 @@ tls12_record_layer_set_read_mac_key(struct tls12_record_layer *rl, | |||
337 | return 1; | 380 | return 1; |
338 | } | 381 | } |
339 | 382 | ||
383 | int | ||
384 | tls12_record_layer_change_read_cipher_state(struct tls12_record_layer *rl, | ||
385 | const uint8_t *mac_key, size_t mac_key_len, const uint8_t *key, | ||
386 | size_t key_len, const uint8_t *iv, size_t iv_len) | ||
387 | { | ||
388 | struct tls12_record_protection *read_new = NULL; | ||
389 | int ret = 0; | ||
390 | |||
391 | if ((read_new = tls12_record_protection_new()) == NULL) | ||
392 | goto err; | ||
393 | |||
394 | /* XXX - change cipher state. */ | ||
395 | |||
396 | tls12_record_protection_free(rl->read_current); | ||
397 | rl->read = rl->read_current = read_new; | ||
398 | read_new = NULL; | ||
399 | |||
400 | ret = 1; | ||
401 | |||
402 | err: | ||
403 | tls12_record_protection_free(read_new); | ||
404 | |||
405 | return ret; | ||
406 | } | ||
407 | |||
408 | int | ||
409 | tls12_record_layer_change_write_cipher_state(struct tls12_record_layer *rl, | ||
410 | const uint8_t *mac_key, size_t mac_key_len, const uint8_t *key, | ||
411 | size_t key_len, const uint8_t *iv, size_t iv_len) | ||
412 | { | ||
413 | struct tls12_record_protection *write_new; | ||
414 | int ret = 0; | ||
415 | |||
416 | if ((write_new = tls12_record_protection_new()) == NULL) | ||
417 | goto err; | ||
418 | |||
419 | /* XXX - change cipher state. */ | ||
420 | |||
421 | if (rl->dtls) { | ||
422 | tls12_record_protection_free(rl->write_previous); | ||
423 | rl->write_previous = rl->write_current; | ||
424 | rl->write_current = NULL; | ||
425 | } | ||
426 | tls12_record_protection_free(rl->write_current); | ||
427 | rl->write = rl->write_current = write_new; | ||
428 | write_new = NULL; | ||
429 | |||
430 | ret = 1; | ||
431 | |||
432 | err: | ||
433 | tls12_record_protection_free(write_new); | ||
434 | |||
435 | return ret; | ||
436 | } | ||
340 | static int | 437 | static int |
341 | tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb, | 438 | tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb, |
342 | uint16_t epoch, uint8_t *seq_num, size_t seq_num_len) | 439 | uint16_t epoch, uint8_t *seq_num, size_t seq_num_len) |