diff options
author | jsing <> | 2020-08-30 15:40:20 +0000 |
---|---|---|
committer | jsing <> | 2020-08-30 15:40:20 +0000 |
commit | 09997f3d41692022beb138f1e238f51af93a8024 (patch) | |
tree | 18ad8015f1e0ba01f043e52b0e4feb24b04656f8 /src/lib | |
parent | 3a0362608e329661831d8a0de2005821d2cc1fe0 (diff) | |
download | openbsd-09997f3d41692022beb138f1e238f51af93a8024.tar.gz openbsd-09997f3d41692022beb138f1e238f51af93a8024.tar.bz2 openbsd-09997f3d41692022beb138f1e238f51af93a8024.zip |
Start replacing the existing TLSv1.2 record layer.
This takes the same design/approach used in TLSv1.3 and provides an
opaque struct that is self contained and cannot reach back into other
layers. For now this just implements/replaces the writing of records
for DTLSv1/TLSv1.0/TLSv1.1/TLSv1.2. In doing so we stop copying the
plaintext into the same buffer that is used to transmit to the wire.
ok inoguchi@ tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/Makefile | 3 | ||||
-rw-r--r-- | src/lib/libssl/d1_pkt.c | 90 | ||||
-rw-r--r-- | src/lib/libssl/ssl_lib.c | 15 | ||||
-rw-r--r-- | src/lib/libssl/ssl_locl.h | 33 | ||||
-rw-r--r-- | src/lib/libssl/ssl_pkt.c | 103 | ||||
-rw-r--r-- | src/lib/libssl/t1_enc.c | 32 | ||||
-rw-r--r-- | src/lib/libssl/tls12_record_layer.c | 533 |
7 files changed, 614 insertions, 195 deletions
diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile index c162e84b77..2e06f13e9c 100644 --- a/src/lib/libssl/Makefile +++ b/src/lib/libssl/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.66 2020/06/09 16:53:53 deraadt Exp $ | 1 | # $OpenBSD: Makefile,v 1.67 2020/08/30 15:40:19 jsing Exp $ |
2 | 2 | ||
3 | .include <bsd.own.mk> | 3 | .include <bsd.own.mk> |
4 | .ifndef NOMAN | 4 | .ifndef NOMAN |
@@ -69,6 +69,7 @@ SRCS= \ | |||
69 | ssl_versions.c \ | 69 | ssl_versions.c \ |
70 | t1_enc.c \ | 70 | t1_enc.c \ |
71 | t1_lib.c \ | 71 | t1_lib.c \ |
72 | tls12_record_layer.c \ | ||
72 | tls13_buffer.c \ | 73 | tls13_buffer.c \ |
73 | tls13_client.c \ | 74 | tls13_client.c \ |
74 | tls13_error.c \ | 75 | tls13_error.c \ |
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 4a6b3b7dcf..748ff988da 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.80 2020/08/11 19:21:54 jsing Exp $ */ | 1 | /* $OpenBSD: d1_pkt.c,v 1.81 2020/08/30 15:40:19 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. |
@@ -1174,14 +1174,9 @@ dtls1_write_bytes(SSL *s, int type, const void *buf, int len) | |||
1174 | int | 1174 | int |
1175 | do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | 1175 | do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) |
1176 | { | 1176 | { |
1177 | SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); | ||
1178 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); | 1177 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); |
1179 | SSL_SESSION *sess = s->session; | ||
1180 | int block_size = 0, eivlen = 0, mac_size = 0; | ||
1181 | size_t pad_len, record_len; | ||
1182 | CBB cbb, fragment; | ||
1183 | size_t out_len; | 1178 | size_t out_len; |
1184 | uint8_t *p; | 1179 | CBB cbb; |
1185 | int ret; | 1180 | int ret; |
1186 | 1181 | ||
1187 | memset(&cbb, 0, sizeof(cbb)); | 1182 | memset(&cbb, 0, sizeof(cbb)); |
@@ -1205,81 +1200,15 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1205 | if (len == 0) | 1200 | if (len == 0) |
1206 | return 0; | 1201 | return 0; |
1207 | 1202 | ||
1208 | if (sess != NULL && s->internal->enc_write_ctx != NULL && | ||
1209 | EVP_MD_CTX_md(s->internal->write_hash) != NULL) { | ||
1210 | if ((mac_size = EVP_MD_CTX_size(s->internal->write_hash)) < 0) | ||
1211 | goto err; | ||
1212 | } | ||
1213 | |||
1214 | /* Explicit IV length. */ | ||
1215 | if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { | ||
1216 | int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx); | ||
1217 | if (mode == EVP_CIPH_CBC_MODE) { | ||
1218 | eivlen = EVP_CIPHER_CTX_iv_length(s->internal->enc_write_ctx); | ||
1219 | if (eivlen <= 1) | ||
1220 | eivlen = 0; | ||
1221 | } | ||
1222 | } else if (s->internal->aead_write_ctx != NULL && | ||
1223 | s->internal->aead_write_ctx->variable_nonce_in_record) { | ||
1224 | eivlen = s->internal->aead_write_ctx->variable_nonce_len; | ||
1225 | } | ||
1226 | |||
1227 | /* Determine length of record fragment. */ | ||
1228 | record_len = eivlen + len + mac_size; | ||
1229 | if (s->internal->enc_write_ctx != NULL) { | ||
1230 | block_size = EVP_CIPHER_CTX_block_size(s->internal->enc_write_ctx); | ||
1231 | if (block_size <= 0 || block_size > EVP_MAX_BLOCK_LENGTH) | ||
1232 | goto err; | ||
1233 | if (block_size > 1) { | ||
1234 | pad_len = block_size - (record_len % block_size); | ||
1235 | record_len += pad_len; | ||
1236 | } | ||
1237 | } else if (s->internal->aead_write_ctx != NULL) { | ||
1238 | record_len += s->internal->aead_write_ctx->tag_len; | ||
1239 | } | ||
1240 | |||
1241 | /* DTLS implements explicit IV, so no need for empty fragments. */ | ||
1242 | |||
1243 | wb->offset = 0; | 1203 | wb->offset = 0; |
1244 | 1204 | ||
1245 | if (!CBB_init_fixed(&cbb, wb->buf, wb->len)) | 1205 | if (!CBB_init_fixed(&cbb, wb->buf, wb->len)) |
1246 | goto err; | 1206 | goto err; |
1247 | 1207 | ||
1248 | /* Write the header. */ | 1208 | tls12_record_layer_set_version(s->internal->rl, s->version); |
1249 | if (!CBB_add_u8(&cbb, type)) | 1209 | tls12_record_layer_set_write_epoch(s->internal->rl, D1I(s)->w_epoch); |
1250 | goto err; | ||
1251 | if (!CBB_add_u16(&cbb, s->version)) | ||
1252 | goto err; | ||
1253 | if (!CBB_add_u16(&cbb, D1I(s)->w_epoch)) | ||
1254 | goto err; | ||
1255 | if (!CBB_add_bytes(&cbb, &(S3I(s)->write_sequence[2]), 6)) | ||
1256 | goto err; | ||
1257 | if (!CBB_add_u16_length_prefixed(&cbb, &fragment)) | ||
1258 | goto err; | ||
1259 | if (!CBB_add_space(&fragment, &p, record_len)) | ||
1260 | goto err; | ||
1261 | |||
1262 | wr->type = type; | ||
1263 | wr->data = p + eivlen; | ||
1264 | wr->length = (int)len; | ||
1265 | wr->input = wr->data; | ||
1266 | |||
1267 | memcpy(wr->data, buf, len); | ||
1268 | |||
1269 | if (mac_size != 0) { | ||
1270 | if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0) | ||
1271 | goto err; | ||
1272 | wr->length += mac_size; | ||
1273 | } | ||
1274 | 1210 | ||
1275 | wr->data = p; | 1211 | if (!tls12_record_layer_seal_record(s->internal->rl, type, buf, len, &cbb)) |
1276 | wr->input = p; | ||
1277 | wr->length += eivlen; | ||
1278 | |||
1279 | if (tls1_enc(s, 1) != 1) | ||
1280 | goto err; | ||
1281 | |||
1282 | if (wr->length != record_len) | ||
1283 | goto err; | 1212 | goto err; |
1284 | 1213 | ||
1285 | if (!CBB_finish(&cbb, NULL, &out_len)) | 1214 | if (!CBB_finish(&cbb, NULL, &out_len)) |
@@ -1288,15 +1217,6 @@ do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
1288 | wb->left = out_len; | 1217 | wb->left = out_len; |
1289 | 1218 | ||
1290 | /* | 1219 | /* |
1291 | * We should now have wr->data pointing to the encrypted data, | ||
1292 | * which is wr->length long. | ||
1293 | */ | ||
1294 | wr->type = type; /* not needed but helps for debugging */ | ||
1295 | wr->length += DTLS1_RT_HEADER_LENGTH; | ||
1296 | |||
1297 | tls1_record_sequence_increment(S3I(s)->write_sequence); | ||
1298 | |||
1299 | /* | ||
1300 | * Memorize arguments so that ssl3_write_pending can detect | 1220 | * Memorize arguments so that ssl3_write_pending can detect |
1301 | * bad write retries later. | 1221 | * bad write retries later. |
1302 | */ | 1222 | */ |
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index bd3188cdf6..bf10cea685 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_lib.c,v 1.220 2020/08/11 18:39:40 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.221 2020/08/30 15:40:19 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 | * |
@@ -344,6 +344,9 @@ SSL_new(SSL_CTX *ctx) | |||
344 | if (!s->method->internal->ssl_new(s)) | 344 | if (!s->method->internal->ssl_new(s)) |
345 | goto err; | 345 | goto err; |
346 | 346 | ||
347 | if ((s->internal->rl = tls12_record_layer_new()) == NULL) | ||
348 | goto err; | ||
349 | |||
347 | s->references = 1; | 350 | s->references = 1; |
348 | s->server = (ctx->method->internal->ssl_accept == ssl_undefined_function) ? 0 : 1; | 351 | s->server = (ctx->method->internal->ssl_accept == ssl_undefined_function) ? 0 : 1; |
349 | 352 | ||
@@ -564,6 +567,8 @@ SSL_free(SSL *s) | |||
564 | sk_SRTP_PROTECTION_PROFILE_free(s->internal->srtp_profiles); | 567 | sk_SRTP_PROTECTION_PROFILE_free(s->internal->srtp_profiles); |
565 | #endif | 568 | #endif |
566 | 569 | ||
570 | tls12_record_layer_free(s->internal->rl); | ||
571 | |||
567 | free(s->internal); | 572 | free(s->internal); |
568 | free(s); | 573 | free(s); |
569 | } | 574 | } |
@@ -2535,6 +2540,10 @@ ssl_clear_cipher_read_state(SSL *s) | |||
2535 | EVP_MD_CTX_free(s->read_hash); | 2540 | EVP_MD_CTX_free(s->read_hash); |
2536 | s->read_hash = NULL; | 2541 | s->read_hash = NULL; |
2537 | 2542 | ||
2543 | tls12_record_layer_clear_read_state(s->internal->rl); | ||
2544 | tls12_record_layer_set_read_seq_num(s->internal->rl, | ||
2545 | S3I(s)->read_sequence); | ||
2546 | |||
2538 | if (s->internal->aead_read_ctx != NULL) { | 2547 | if (s->internal->aead_read_ctx != NULL) { |
2539 | EVP_AEAD_CTX_cleanup(&s->internal->aead_read_ctx->ctx); | 2548 | EVP_AEAD_CTX_cleanup(&s->internal->aead_read_ctx->ctx); |
2540 | free(s->internal->aead_read_ctx); | 2549 | free(s->internal->aead_read_ctx); |
@@ -2550,6 +2559,10 @@ ssl_clear_cipher_write_state(SSL *s) | |||
2550 | EVP_MD_CTX_free(s->internal->write_hash); | 2559 | EVP_MD_CTX_free(s->internal->write_hash); |
2551 | s->internal->write_hash = NULL; | 2560 | s->internal->write_hash = NULL; |
2552 | 2561 | ||
2562 | tls12_record_layer_clear_write_state(s->internal->rl); | ||
2563 | tls12_record_layer_set_write_seq_num(s->internal->rl, | ||
2564 | S3I(s)->write_sequence); | ||
2565 | |||
2553 | if (s->internal->aead_write_ctx != NULL) { | 2566 | if (s->internal->aead_write_ctx != NULL) { |
2554 | EVP_AEAD_CTX_cleanup(&s->internal->aead_write_ctx->ctx); | 2567 | EVP_AEAD_CTX_cleanup(&s->internal->aead_write_ctx->ctx); |
2555 | free(s->internal->aead_write_ctx); | 2568 | free(s->internal->aead_write_ctx); |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 676f404352..e41465419a 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.283 2020/08/11 18:40:24 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.284 2020/08/30 15:40:20 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 | * |
@@ -475,6 +475,34 @@ typedef struct ssl_handshake_tls13_st { | |||
475 | 475 | ||
476 | } SSL_HANDSHAKE_TLS13; | 476 | } SSL_HANDSHAKE_TLS13; |
477 | 477 | ||
478 | struct tls12_record_layer; | ||
479 | |||
480 | struct tls12_record_layer *tls12_record_layer_new(void); | ||
481 | void tls12_record_layer_free(struct tls12_record_layer *rl); | ||
482 | void tls12_record_layer_set_version(struct tls12_record_layer *rl, | ||
483 | uint16_t version); | ||
484 | void tls12_record_layer_set_read_epoch(struct tls12_record_layer *rl, | ||
485 | uint16_t epoch); | ||
486 | void tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, | ||
487 | uint16_t epoch); | ||
488 | 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); | ||
490 | void tls12_record_layer_set_read_seq_num(struct tls12_record_layer *rl, | ||
491 | uint8_t *seq_num); | ||
492 | void tls12_record_layer_set_write_seq_num(struct tls12_record_layer *rl, | ||
493 | uint8_t *seq_num); | ||
494 | int tls12_record_layer_set_read_aead(struct tls12_record_layer *rl, | ||
495 | SSL_AEAD_CTX *aead_ctx); | ||
496 | int tls12_record_layer_set_write_aead(struct tls12_record_layer *rl, | ||
497 | SSL_AEAD_CTX *aead_ctx); | ||
498 | int tls12_record_layer_set_read_cipher_hash(struct tls12_record_layer *rl, | ||
499 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac); | ||
500 | 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); | ||
502 | int tls12_record_layer_seal_record(struct tls12_record_layer *rl, | ||
503 | uint8_t content_type, const uint8_t *content, size_t content_len, | ||
504 | CBB *out); | ||
505 | |||
478 | typedef struct ssl_ctx_internal_st { | 506 | typedef struct ssl_ctx_internal_st { |
479 | uint16_t min_version; | 507 | uint16_t min_version; |
480 | uint16_t max_version; | 508 | uint16_t max_version; |
@@ -736,6 +764,8 @@ typedef struct ssl_internal_st { | |||
736 | EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ | 764 | EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ |
737 | EVP_MD_CTX *write_hash; /* used for mac generation */ | 765 | EVP_MD_CTX *write_hash; /* used for mac generation */ |
738 | 766 | ||
767 | struct tls12_record_layer *rl; | ||
768 | |||
739 | /* session info */ | 769 | /* session info */ |
740 | 770 | ||
741 | /* extra application data */ | 771 | /* extra application data */ |
@@ -826,7 +856,6 @@ typedef struct ssl3_state_internal_st { | |||
826 | int empty_fragment_done; | 856 | int empty_fragment_done; |
827 | 857 | ||
828 | SSL3_RECORD_INTERNAL rrec; /* each decoded record goes in here */ | 858 | SSL3_RECORD_INTERNAL rrec; /* each decoded record goes in here */ |
829 | SSL3_RECORD_INTERNAL wrec; /* goes out from here */ | ||
830 | 859 | ||
831 | /* storage for Alert/Handshake protocol data received but not | 860 | /* storage for Alert/Handshake protocol data received but not |
832 | * yet processed by ssl3_read_bytes: */ | 861 | * yet processed by ssl3_read_bytes: */ |
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index 5c9b3be2ff..c9c86471d3 100644 --- a/src/lib/libssl/ssl_pkt.c +++ b/src/lib/libssl/ssl_pkt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_pkt.c,v 1.30 2020/08/09 16:54:16 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.31 2020/08/30 15:40:20 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 | * |
@@ -617,100 +617,6 @@ ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) | |||
617 | } | 617 | } |
618 | 618 | ||
619 | static int | 619 | static int |
620 | ssl3_create_record(SSL *s, CBB *cbb, uint16_t version, uint8_t type, | ||
621 | const unsigned char *buf, unsigned int len) | ||
622 | { | ||
623 | SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); | ||
624 | SSL_SESSION *sess = s->session; | ||
625 | int block_size = 0, eivlen = 0, mac_size = 0; | ||
626 | size_t pad_len, record_len; | ||
627 | CBB fragment; | ||
628 | uint8_t *p; | ||
629 | |||
630 | if (sess != NULL && s->internal->enc_write_ctx != NULL && | ||
631 | EVP_MD_CTX_md(s->internal->write_hash) != NULL) { | ||
632 | if ((mac_size = EVP_MD_CTX_size(s->internal->write_hash)) < 0) | ||
633 | goto err; | ||
634 | } | ||
635 | |||
636 | /* Explicit IV length. */ | ||
637 | if (s->internal->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { | ||
638 | int mode = EVP_CIPHER_CTX_mode(s->internal->enc_write_ctx); | ||
639 | if (mode == EVP_CIPH_CBC_MODE) { | ||
640 | eivlen = EVP_CIPHER_CTX_iv_length(s->internal->enc_write_ctx); | ||
641 | if (eivlen <= 1) | ||
642 | eivlen = 0; | ||
643 | } | ||
644 | } else if (s->internal->aead_write_ctx != NULL && | ||
645 | s->internal->aead_write_ctx->variable_nonce_in_record) { | ||
646 | eivlen = s->internal->aead_write_ctx->variable_nonce_len; | ||
647 | } | ||
648 | |||
649 | /* Determine length of record fragment. */ | ||
650 | record_len = eivlen + len + mac_size; | ||
651 | if (s->internal->enc_write_ctx != NULL) { | ||
652 | block_size = EVP_CIPHER_CTX_block_size(s->internal->enc_write_ctx); | ||
653 | if (block_size <= 0 || block_size > EVP_MAX_BLOCK_LENGTH) | ||
654 | goto err; | ||
655 | if (block_size > 1) { | ||
656 | pad_len = block_size - (record_len % block_size); | ||
657 | record_len += pad_len; | ||
658 | } | ||
659 | } else if (s->internal->aead_write_ctx != NULL) { | ||
660 | record_len += s->internal->aead_write_ctx->tag_len; | ||
661 | } | ||
662 | |||
663 | /* Write the header. */ | ||
664 | if (!CBB_add_u8(cbb, type)) | ||
665 | goto err; | ||
666 | if (!CBB_add_u16(cbb, version)) | ||
667 | goto err; | ||
668 | if (!CBB_add_u16_length_prefixed(cbb, &fragment)) | ||
669 | goto err; | ||
670 | if (!CBB_add_space(&fragment, &p, record_len)) | ||
671 | goto err; | ||
672 | |||
673 | /* Set up the record. */ | ||
674 | wr->type = type; | ||
675 | wr->data = p + eivlen; | ||
676 | wr->length = (int)len; | ||
677 | wr->input = wr->data; | ||
678 | |||
679 | memcpy(wr->data, buf, len); | ||
680 | |||
681 | if (mac_size != 0) { | ||
682 | if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0) | ||
683 | goto err; | ||
684 | wr->length += mac_size; | ||
685 | } | ||
686 | |||
687 | wr->data = p; | ||
688 | wr->input = p; | ||
689 | wr->length += eivlen; | ||
690 | |||
691 | if (tls1_enc(s, 1) != 1) | ||
692 | goto err; | ||
693 | |||
694 | if (wr->length != record_len) | ||
695 | goto err; | ||
696 | |||
697 | if (!CBB_flush(cbb)) | ||
698 | goto err; | ||
699 | |||
700 | /* | ||
701 | * We should now have wr->data pointing to the encrypted data, | ||
702 | * which is wr->length long. | ||
703 | */ | ||
704 | wr->type = type; /* not needed but helps for debugging */ | ||
705 | wr->length += SSL3_RT_HEADER_LENGTH; | ||
706 | |||
707 | return 1; | ||
708 | |||
709 | err: | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int | ||
714 | do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | 620 | do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) |
715 | { | 621 | { |
716 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); | 622 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); |
@@ -785,13 +691,16 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
785 | if (!CBB_init_fixed(&cbb, wb->buf + align, wb->len - align)) | 691 | if (!CBB_init_fixed(&cbb, wb->buf + align, wb->len - align)) |
786 | goto err; | 692 | goto err; |
787 | 693 | ||
694 | tls12_record_layer_set_version(s->internal->rl, version); | ||
695 | |||
788 | if (need_empty_fragment) { | 696 | if (need_empty_fragment) { |
789 | if (!ssl3_create_record(s, &cbb, version, type, buf, 0)) | 697 | if (!tls12_record_layer_seal_record(s->internal->rl, type, |
698 | buf, 0, &cbb)) | ||
790 | goto err; | 699 | goto err; |
791 | S3I(s)->empty_fragment_done = 1; | 700 | S3I(s)->empty_fragment_done = 1; |
792 | } | 701 | } |
793 | 702 | ||
794 | if (!ssl3_create_record(s, &cbb, version, type, buf, len)) | 703 | if (!tls12_record_layer_seal_record(s->internal->rl, type, buf, len, &cbb)) |
795 | goto err; | 704 | goto err; |
796 | 705 | ||
797 | if (!CBB_finish(&cbb, NULL, &out_len)) | 706 | if (!CBB_finish(&cbb, NULL, &out_len)) |
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 2893e1d4dc..a66c82bdca 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.122 2020/03/16 15:25:14 tb Exp $ */ | 1 | /* $OpenBSD: t1_enc.c,v 1.123 2020/08/30 15:40:20 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 | * |
@@ -350,11 +350,17 @@ tls1_change_cipher_state_aead(SSL *s, char is_read, const unsigned char *key, | |||
350 | if (!tls1_aead_ctx_init(&s->internal->aead_read_ctx)) | 350 | if (!tls1_aead_ctx_init(&s->internal->aead_read_ctx)) |
351 | return 0; | 351 | return 0; |
352 | aead_ctx = s->internal->aead_read_ctx; | 352 | aead_ctx = s->internal->aead_read_ctx; |
353 | |||
354 | if (!tls12_record_layer_set_read_aead(s->internal->rl, aead_ctx)) | ||
355 | return 0; | ||
353 | } else { | 356 | } else { |
354 | ssl_clear_cipher_write_state(s); | 357 | ssl_clear_cipher_write_state(s); |
355 | if (!tls1_aead_ctx_init(&s->internal->aead_write_ctx)) | 358 | if (!tls1_aead_ctx_init(&s->internal->aead_write_ctx)) |
356 | return 0; | 359 | return 0; |
357 | aead_ctx = s->internal->aead_write_ctx; | 360 | aead_ctx = s->internal->aead_write_ctx; |
361 | |||
362 | if (!tls12_record_layer_set_write_aead(s->internal->rl, aead_ctx)) | ||
363 | return 0; | ||
358 | } | 364 | } |
359 | 365 | ||
360 | if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len, | 366 | if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len, |
@@ -408,14 +414,16 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, | |||
408 | EVP_MD_CTX *mac_ctx; | 414 | EVP_MD_CTX *mac_ctx; |
409 | EVP_PKEY *mac_key; | 415 | EVP_PKEY *mac_key; |
410 | const EVP_MD *mac; | 416 | const EVP_MD *mac; |
417 | int stream_mac; | ||
411 | int mac_type; | 418 | int mac_type; |
412 | 419 | ||
413 | cipher = S3I(s)->tmp.new_sym_enc; | 420 | cipher = S3I(s)->tmp.new_sym_enc; |
414 | mac = S3I(s)->tmp.new_hash; | 421 | mac = S3I(s)->tmp.new_hash; |
415 | mac_type = S3I(s)->tmp.new_mac_pkey_type; | 422 | mac_type = S3I(s)->tmp.new_mac_pkey_type; |
423 | stream_mac = S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC; | ||
416 | 424 | ||
417 | if (is_read) { | 425 | if (is_read) { |
418 | if (S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC) | 426 | if (stream_mac) |
419 | s->internal->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; | 427 | s->internal->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; |
420 | else | 428 | else |
421 | s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; | 429 | s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; |
@@ -428,8 +436,12 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, | |||
428 | if ((mac_ctx = EVP_MD_CTX_new()) == NULL) | 436 | if ((mac_ctx = EVP_MD_CTX_new()) == NULL) |
429 | goto err; | 437 | goto err; |
430 | s->read_hash = mac_ctx; | 438 | s->read_hash = mac_ctx; |
439 | |||
440 | if (!tls12_record_layer_set_read_cipher_hash(s->internal->rl, | ||
441 | cipher_ctx, mac_ctx, stream_mac)) | ||
442 | goto err; | ||
431 | } else { | 443 | } else { |
432 | if (S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC) | 444 | if (stream_mac) |
433 | s->internal->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; | 445 | s->internal->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; |
434 | else | 446 | else |
435 | s->internal->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; | 447 | s->internal->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; |
@@ -450,6 +462,10 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, | |||
450 | if ((mac_ctx = EVP_MD_CTX_new()) == NULL) | 462 | if ((mac_ctx = EVP_MD_CTX_new()) == NULL) |
451 | goto err; | 463 | goto err; |
452 | s->internal->write_hash = mac_ctx; | 464 | s->internal->write_hash = mac_ctx; |
465 | |||
466 | if (!tls12_record_layer_set_write_cipher_hash(s->internal->rl, | ||
467 | cipher_ctx, mac_ctx, stream_mac)) | ||
468 | goto err; | ||
453 | } | 469 | } |
454 | 470 | ||
455 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); | 471 | EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); |
@@ -677,9 +693,8 @@ tls1_enc(SSL *s, int send) | |||
677 | int bs, i, j, k, ret, mac_size = 0; | 693 | int bs, i, j, k, ret, mac_size = 0; |
678 | 694 | ||
679 | if (send) { | 695 | if (send) { |
680 | aead = s->internal->aead_write_ctx; | 696 | /* No longer supported. */ |
681 | rec = &S3I(s)->wrec; | 697 | return -1; |
682 | seq = S3I(s)->write_sequence; | ||
683 | } else { | 698 | } else { |
684 | aead = s->internal->aead_read_ctx; | 699 | aead = s->internal->aead_read_ctx; |
685 | rec = &S3I(s)->rrec; | 700 | rec = &S3I(s)->rrec; |
@@ -946,9 +961,8 @@ tls1_mac(SSL *ssl, unsigned char *md, int send) | |||
946 | int t; | 961 | int t; |
947 | 962 | ||
948 | if (send) { | 963 | if (send) { |
949 | rec = &(ssl->s3->internal->wrec); | 964 | /* No longer supported. */ |
950 | seq = &(ssl->s3->internal->write_sequence[0]); | 965 | return -1; |
951 | hash = ssl->internal->write_hash; | ||
952 | } else { | 966 | } else { |
953 | rec = &(ssl->s3->internal->rrec); | 967 | rec = &(ssl->s3->internal->rrec); |
954 | seq = &(ssl->s3->internal->read_sequence[0]); | 968 | seq = &(ssl->s3->internal->read_sequence[0]); |
diff --git a/src/lib/libssl/tls12_record_layer.c b/src/lib/libssl/tls12_record_layer.c new file mode 100644 index 0000000000..5e7a3a610c --- /dev/null +++ b/src/lib/libssl/tls12_record_layer.c | |||
@@ -0,0 +1,533 @@ | |||
1 | /* $OpenBSD: tls12_record_layer.c,v 1.1 2020/08/30 15:40:20 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include <stdlib.h> | ||
19 | |||
20 | #include <openssl/evp.h> | ||
21 | |||
22 | #include "ssl_locl.h" | ||
23 | |||
24 | struct tls12_record_layer { | ||
25 | uint16_t version; | ||
26 | int dtls; | ||
27 | |||
28 | uint16_t read_epoch; | ||
29 | uint16_t write_epoch; | ||
30 | |||
31 | int read_stream_mac; | ||
32 | int write_stream_mac; | ||
33 | |||
34 | /* | ||
35 | * XXX - for now these are just pointers to externally managed | ||
36 | * structs/memory. These should eventually be owned by the record layer. | ||
37 | */ | ||
38 | SSL_AEAD_CTX *read_aead_ctx; | ||
39 | SSL_AEAD_CTX *write_aead_ctx; | ||
40 | |||
41 | EVP_CIPHER_CTX *read_cipher_ctx; | ||
42 | EVP_MD_CTX *read_hash_ctx; | ||
43 | EVP_CIPHER_CTX *write_cipher_ctx; | ||
44 | EVP_MD_CTX *write_hash_ctx; | ||
45 | |||
46 | uint8_t *read_seq_num; | ||
47 | uint8_t *write_seq_num; | ||
48 | }; | ||
49 | |||
50 | struct tls12_record_layer * | ||
51 | tls12_record_layer_new(void) | ||
52 | { | ||
53 | struct tls12_record_layer *rl; | ||
54 | |||
55 | if ((rl = calloc(1, sizeof(struct tls12_record_layer))) == NULL) | ||
56 | return NULL; | ||
57 | |||
58 | return rl; | ||
59 | } | ||
60 | |||
61 | void | ||
62 | tls12_record_layer_free(struct tls12_record_layer *rl) | ||
63 | { | ||
64 | freezero(rl, sizeof(struct tls12_record_layer)); | ||
65 | } | ||
66 | |||
67 | void | ||
68 | tls12_record_layer_set_version(struct tls12_record_layer *rl, uint16_t version) | ||
69 | { | ||
70 | rl->version = version; | ||
71 | rl->dtls = (version == DTLS1_VERSION); | ||
72 | } | ||
73 | |||
74 | void | ||
75 | tls12_record_layer_set_read_epoch(struct tls12_record_layer *rl, uint16_t epoch) | ||
76 | { | ||
77 | rl->read_epoch = epoch; | ||
78 | } | ||
79 | |||
80 | void | ||
81 | tls12_record_layer_set_write_epoch(struct tls12_record_layer *rl, uint16_t epoch) | ||
82 | { | ||
83 | rl->write_epoch = epoch; | ||
84 | } | ||
85 | |||
86 | static void | ||
87 | tls12_record_layer_set_read_state(struct tls12_record_layer *rl, | ||
88 | SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, | ||
89 | int stream_mac) | ||
90 | { | ||
91 | rl->read_aead_ctx = aead_ctx; | ||
92 | |||
93 | rl->read_cipher_ctx = cipher_ctx; | ||
94 | rl->read_hash_ctx = hash_ctx; | ||
95 | rl->read_stream_mac = stream_mac; | ||
96 | } | ||
97 | |||
98 | static void | ||
99 | tls12_record_layer_set_write_state(struct tls12_record_layer *rl, | ||
100 | SSL_AEAD_CTX *aead_ctx, EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, | ||
101 | int stream_mac) | ||
102 | { | ||
103 | rl->write_aead_ctx = aead_ctx; | ||
104 | |||
105 | rl->write_cipher_ctx = cipher_ctx; | ||
106 | rl->write_hash_ctx = hash_ctx; | ||
107 | rl->write_stream_mac = stream_mac; | ||
108 | } | ||
109 | |||
110 | void | ||
111 | tls12_record_layer_clear_read_state(struct tls12_record_layer *rl) | ||
112 | { | ||
113 | tls12_record_layer_set_read_state(rl, NULL, NULL, NULL, 0); | ||
114 | rl->read_seq_num = NULL; | ||
115 | } | ||
116 | |||
117 | void | ||
118 | tls12_record_layer_clear_write_state(struct tls12_record_layer *rl) | ||
119 | { | ||
120 | tls12_record_layer_set_write_state(rl, NULL, NULL, NULL, 0); | ||
121 | rl->write_seq_num = NULL; | ||
122 | } | ||
123 | |||
124 | void | ||
125 | tls12_record_layer_set_read_seq_num(struct tls12_record_layer *rl, | ||
126 | uint8_t *seq_num) | ||
127 | { | ||
128 | rl->read_seq_num = seq_num; | ||
129 | } | ||
130 | |||
131 | void | ||
132 | tls12_record_layer_set_write_seq_num(struct tls12_record_layer *rl, | ||
133 | uint8_t *seq_num) | ||
134 | { | ||
135 | rl->write_seq_num = seq_num; | ||
136 | } | ||
137 | |||
138 | int | ||
139 | tls12_record_layer_set_read_aead(struct tls12_record_layer *rl, | ||
140 | SSL_AEAD_CTX *aead_ctx) | ||
141 | { | ||
142 | tls12_record_layer_set_read_state(rl, aead_ctx, NULL, NULL, 0); | ||
143 | |||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | int | ||
148 | tls12_record_layer_set_write_aead(struct tls12_record_layer *rl, | ||
149 | SSL_AEAD_CTX *aead_ctx) | ||
150 | { | ||
151 | tls12_record_layer_set_write_state(rl, aead_ctx, NULL, NULL, 0); | ||
152 | |||
153 | return 1; | ||
154 | } | ||
155 | |||
156 | int | ||
157 | tls12_record_layer_set_read_cipher_hash(struct tls12_record_layer *rl, | ||
158 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) | ||
159 | { | ||
160 | tls12_record_layer_set_read_state(rl, NULL, cipher_ctx, hash_ctx, | ||
161 | stream_mac); | ||
162 | |||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | int | ||
167 | tls12_record_layer_set_write_cipher_hash(struct tls12_record_layer *rl, | ||
168 | EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *hash_ctx, int stream_mac) | ||
169 | { | ||
170 | tls12_record_layer_set_write_state(rl, NULL, cipher_ctx, hash_ctx, | ||
171 | stream_mac); | ||
172 | |||
173 | return 1; | ||
174 | } | ||
175 | |||
176 | static int | ||
177 | tls12_record_layer_build_seq_num(struct tls12_record_layer *rl, CBB *cbb, | ||
178 | uint16_t epoch, uint8_t *seq_num, size_t seq_num_len) | ||
179 | { | ||
180 | CBS seq; | ||
181 | |||
182 | CBS_init(&seq, seq_num, seq_num_len); | ||
183 | |||
184 | if (rl->dtls) { | ||
185 | if (!CBB_add_u16(cbb, epoch)) | ||
186 | return 0; | ||
187 | if (!CBS_skip(&seq, 2)) | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | return CBB_add_bytes(cbb, CBS_data(&seq), CBS_len(&seq)); | ||
192 | } | ||
193 | |||
194 | static int | ||
195 | tls12_record_layer_pseudo_header(struct tls12_record_layer *rl, | ||
196 | uint8_t content_type, uint16_t record_len, uint16_t epoch, uint8_t *seq_num, | ||
197 | size_t seq_num_len, uint8_t **out, size_t *out_len) | ||
198 | { | ||
199 | CBB cbb; | ||
200 | |||
201 | *out = NULL; | ||
202 | *out_len = 0; | ||
203 | |||
204 | /* Build the pseudo-header used for MAC/AEAD. */ | ||
205 | if (!CBB_init(&cbb, 13)) | ||
206 | goto err; | ||
207 | |||
208 | if (!tls12_record_layer_build_seq_num(rl, &cbb, epoch, | ||
209 | seq_num, seq_num_len)) | ||
210 | goto err; | ||
211 | if (!CBB_add_u8(&cbb, content_type)) | ||
212 | goto err; | ||
213 | if (!CBB_add_u16(&cbb, rl->version)) | ||
214 | goto err; | ||
215 | if (!CBB_add_u16(&cbb, record_len)) | ||
216 | goto err; | ||
217 | |||
218 | if (!CBB_finish(&cbb, out, out_len)) | ||
219 | goto err; | ||
220 | |||
221 | return 1; | ||
222 | |||
223 | err: | ||
224 | CBB_cleanup(&cbb); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int | ||
230 | tls12_record_layer_write_mac(struct tls12_record_layer *rl, CBB *cbb, | ||
231 | uint8_t content_type, const uint8_t *content, size_t content_len, | ||
232 | size_t *out_len) | ||
233 | { | ||
234 | EVP_MD_CTX *mac_ctx = NULL; | ||
235 | uint8_t *header = NULL; | ||
236 | size_t header_len; | ||
237 | size_t mac_len; | ||
238 | uint8_t *mac; | ||
239 | int ret = 0; | ||
240 | |||
241 | if ((mac_ctx = EVP_MD_CTX_new()) == NULL) | ||
242 | goto err; | ||
243 | if (!EVP_MD_CTX_copy(mac_ctx, rl->write_hash_ctx)) | ||
244 | goto err; | ||
245 | |||
246 | if (!tls12_record_layer_pseudo_header(rl, content_type, content_len, | ||
247 | rl->write_epoch, rl->write_seq_num, SSL3_SEQUENCE_SIZE, | ||
248 | &header, &header_len)) | ||
249 | goto err; | ||
250 | |||
251 | if (EVP_DigestSignUpdate(mac_ctx, header, header_len) <= 0) | ||
252 | goto err; | ||
253 | if (EVP_DigestSignUpdate(mac_ctx, content, content_len) <= 0) | ||
254 | goto err; | ||
255 | if (EVP_DigestSignFinal(mac_ctx, NULL, &mac_len) <= 0) | ||
256 | goto err; | ||
257 | if (!CBB_add_space(cbb, &mac, mac_len)) | ||
258 | goto err; | ||
259 | if (EVP_DigestSignFinal(mac_ctx, mac, &mac_len) <= 0) | ||
260 | goto err; | ||
261 | |||
262 | if (rl->write_stream_mac) { | ||
263 | if (!EVP_MD_CTX_copy(rl->write_hash_ctx, mac_ctx)) | ||
264 | goto err; | ||
265 | } | ||
266 | |||
267 | *out_len = mac_len; | ||
268 | |||
269 | ret = 1; | ||
270 | |||
271 | err: | ||
272 | EVP_MD_CTX_free(mac_ctx); | ||
273 | free(header); | ||
274 | |||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | static int | ||
279 | tls12_record_layer_seal_record_plaintext(struct tls12_record_layer *rl, | ||
280 | uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out) | ||
281 | { | ||
282 | if (rl->write_aead_ctx != NULL || rl->write_cipher_ctx != NULL) | ||
283 | return 0; | ||
284 | |||
285 | return CBB_add_bytes(out, content, content_len); | ||
286 | } | ||
287 | |||
288 | static int | ||
289 | tls12_record_layer_aead_concat_nonce(struct tls12_record_layer *rl, | ||
290 | const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len) | ||
291 | { | ||
292 | CBB cbb; | ||
293 | |||
294 | if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE) | ||
295 | return 0; | ||
296 | |||
297 | /* Fixed nonce and variable nonce (sequence number) are concatenated. */ | ||
298 | if (!CBB_init(&cbb, 16)) | ||
299 | goto err; | ||
300 | if (!CBB_add_bytes(&cbb, aead->fixed_nonce, | ||
301 | aead->fixed_nonce_len)) | ||
302 | goto err; | ||
303 | if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len)) | ||
304 | goto err; | ||
305 | if (!CBB_finish(&cbb, out, out_len)) | ||
306 | goto err; | ||
307 | |||
308 | return 1; | ||
309 | |||
310 | err: | ||
311 | CBB_cleanup(&cbb); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int | ||
317 | tls12_record_layer_aead_xored_nonce(struct tls12_record_layer *rl, | ||
318 | const SSL_AEAD_CTX *aead, uint8_t *seq_num, uint8_t **out, size_t *out_len) | ||
319 | { | ||
320 | uint8_t *nonce = NULL; | ||
321 | size_t nonce_len = 0; | ||
322 | uint8_t *pad; | ||
323 | CBB cbb; | ||
324 | int i; | ||
325 | |||
326 | if (aead->variable_nonce_len > SSL3_SEQUENCE_SIZE) | ||
327 | return 0; | ||
328 | if (aead->fixed_nonce_len < aead->variable_nonce_len) | ||
329 | return 0; | ||
330 | |||
331 | /* | ||
332 | * Variable nonce (sequence number) is right padded, before the fixed | ||
333 | * nonce is XOR'd in. | ||
334 | */ | ||
335 | if (!CBB_init(&cbb, 16)) | ||
336 | goto err; | ||
337 | if (!CBB_add_space(&cbb, &pad, | ||
338 | aead->fixed_nonce_len - aead->variable_nonce_len)) | ||
339 | goto err; | ||
340 | if (!CBB_add_bytes(&cbb, seq_num, aead->variable_nonce_len)) | ||
341 | goto err; | ||
342 | if (!CBB_finish(&cbb, &nonce, &nonce_len)) | ||
343 | goto err; | ||
344 | |||
345 | for (i = 0; i < aead->fixed_nonce_len; i++) | ||
346 | nonce[i] ^= aead->fixed_nonce[i]; | ||
347 | |||
348 | *out = nonce; | ||
349 | *out_len = nonce_len; | ||
350 | |||
351 | return 1; | ||
352 | |||
353 | err: | ||
354 | CBB_cleanup(&cbb); | ||
355 | freezero(nonce, nonce_len); | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | static int | ||
361 | tls12_record_layer_seal_record_protected_aead(struct tls12_record_layer *rl, | ||
362 | uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out) | ||
363 | { | ||
364 | const SSL_AEAD_CTX *aead = rl->write_aead_ctx; | ||
365 | uint8_t *header = NULL, *nonce = NULL; | ||
366 | size_t header_len = 0, nonce_len = 0; | ||
367 | size_t enc_record_len, out_len; | ||
368 | uint16_t epoch = 0; | ||
369 | uint8_t *enc_data; | ||
370 | int ret = 0; | ||
371 | |||
372 | /* XXX - move to nonce allocated in record layer, matching TLSv1.3 */ | ||
373 | if (aead->xor_fixed_nonce) { | ||
374 | if (!tls12_record_layer_aead_xored_nonce(rl, aead, | ||
375 | rl->write_seq_num, &nonce, &nonce_len)) | ||
376 | goto err; | ||
377 | } else { | ||
378 | if (!tls12_record_layer_aead_concat_nonce(rl, aead, | ||
379 | rl->write_seq_num, &nonce, &nonce_len)) | ||
380 | goto err; | ||
381 | } | ||
382 | |||
383 | if (aead->variable_nonce_in_record) { | ||
384 | /* XXX - length check? */ | ||
385 | if (!CBB_add_bytes(out, rl->write_seq_num, aead->variable_nonce_len)) | ||
386 | goto err; | ||
387 | } | ||
388 | |||
389 | if (!tls12_record_layer_pseudo_header(rl, content_type, content_len, | ||
390 | epoch, rl->write_seq_num, SSL3_SEQUENCE_SIZE, &header, &header_len)) | ||
391 | goto err; | ||
392 | |||
393 | /* XXX EVP_AEAD_max_tag_len vs EVP_AEAD_CTX_tag_len. */ | ||
394 | enc_record_len = content_len + aead->tag_len; | ||
395 | if (enc_record_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) | ||
396 | goto err; | ||
397 | if (!CBB_add_space(out, &enc_data, enc_record_len)) | ||
398 | goto err; | ||
399 | |||
400 | if (!EVP_AEAD_CTX_seal(&aead->ctx, enc_data, &out_len, enc_record_len, | ||
401 | nonce, nonce_len, content, content_len, header, header_len)) | ||
402 | goto err; | ||
403 | |||
404 | if (out_len != enc_record_len) | ||
405 | goto err; | ||
406 | |||
407 | ret = 1; | ||
408 | |||
409 | err: | ||
410 | freezero(header, header_len); | ||
411 | freezero(nonce, nonce_len); | ||
412 | |||
413 | return ret; | ||
414 | } | ||
415 | |||
416 | static int | ||
417 | tls12_record_layer_seal_record_protected_cipher(struct tls12_record_layer *rl, | ||
418 | uint8_t content_type, const uint8_t *content, size_t content_len, CBB *out) | ||
419 | { | ||
420 | EVP_CIPHER_CTX *enc = rl->write_cipher_ctx; | ||
421 | size_t mac_len, pad_len; | ||
422 | int block_size, eiv_len; | ||
423 | uint8_t *enc_data, *eiv, *pad, pad_val; | ||
424 | uint8_t *plain = NULL; | ||
425 | size_t plain_len = 0; | ||
426 | int ret = 0; | ||
427 | CBB cbb; | ||
428 | |||
429 | if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH)) | ||
430 | goto err; | ||
431 | |||
432 | /* Add explicit IV if necessary. */ | ||
433 | eiv_len = 0; | ||
434 | if (rl->version != TLS1_VERSION && | ||
435 | EVP_CIPHER_CTX_mode(enc) == EVP_CIPH_CBC_MODE) | ||
436 | eiv_len = EVP_CIPHER_CTX_iv_length(enc); | ||
437 | if (eiv_len < 0 || eiv_len > EVP_MAX_IV_LENGTH) | ||
438 | goto err; | ||
439 | if (eiv_len > 0) { | ||
440 | if (!CBB_add_space(&cbb, &eiv, eiv_len)) | ||
441 | goto err; | ||
442 | arc4random_buf(eiv, eiv_len); | ||
443 | } | ||
444 | |||
445 | if (!CBB_add_bytes(&cbb, content, content_len)) | ||
446 | goto err; | ||
447 | |||
448 | mac_len = 0; | ||
449 | if (rl->write_hash_ctx != NULL) { | ||
450 | if (!tls12_record_layer_write_mac(rl, &cbb, content_type, | ||
451 | content, content_len, &mac_len)) | ||
452 | goto err; | ||
453 | } | ||
454 | |||
455 | plain_len = (size_t)eiv_len + content_len + mac_len; | ||
456 | |||
457 | /* Add padding to block size, if necessary. */ | ||
458 | block_size = EVP_CIPHER_CTX_block_size(enc); | ||
459 | if (block_size < 0 || block_size > EVP_MAX_BLOCK_LENGTH) | ||
460 | return 0; | ||
461 | if (block_size > 1) { | ||
462 | pad_len = block_size - (plain_len % block_size); | ||
463 | pad_val = pad_len - 1; | ||
464 | |||
465 | if (pad_len > 255) | ||
466 | goto err; | ||
467 | if (!CBB_add_space(&cbb, &pad, pad_len)) | ||
468 | goto err; | ||
469 | memset(pad, pad_val, pad_len); | ||
470 | } | ||
471 | |||
472 | if (!CBB_finish(&cbb, &plain, &plain_len)) | ||
473 | goto err; | ||
474 | |||
475 | if (plain_len % block_size != 0) | ||
476 | goto err; | ||
477 | if (plain_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) | ||
478 | goto err; | ||
479 | |||
480 | if (!CBB_add_space(out, &enc_data, plain_len)) | ||
481 | goto err; | ||
482 | if (!EVP_Cipher(enc, enc_data, plain, plain_len)) | ||
483 | goto err; | ||
484 | |||
485 | ret = 1; | ||
486 | |||
487 | err: | ||
488 | CBB_cleanup(&cbb); | ||
489 | freezero(plain, plain_len); | ||
490 | |||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | int | ||
495 | tls12_record_layer_seal_record(struct tls12_record_layer *rl, | ||
496 | uint8_t content_type, const uint8_t *content, size_t content_len, CBB *cbb) | ||
497 | { | ||
498 | CBB fragment; | ||
499 | |||
500 | if (!CBB_add_u8(cbb, content_type)) | ||
501 | return 0; | ||
502 | if (!CBB_add_u16(cbb, rl->version)) | ||
503 | return 0; | ||
504 | if (rl->dtls) { | ||
505 | if (!tls12_record_layer_build_seq_num(rl, cbb, | ||
506 | rl->write_epoch, rl->write_seq_num, | ||
507 | SSL3_SEQUENCE_SIZE)) | ||
508 | return 0; | ||
509 | } | ||
510 | if (!CBB_add_u16_length_prefixed(cbb, &fragment)) | ||
511 | return 0; | ||
512 | |||
513 | if (rl->write_aead_ctx != NULL) { | ||
514 | if (!tls12_record_layer_seal_record_protected_aead(rl, | ||
515 | content_type, content, content_len, &fragment)) | ||
516 | return 0; | ||
517 | } else if (rl->write_cipher_ctx != NULL) { | ||
518 | if (!tls12_record_layer_seal_record_protected_cipher(rl, | ||
519 | content_type, content, content_len, &fragment)) | ||
520 | return 0; | ||
521 | } else { | ||
522 | if (!tls12_record_layer_seal_record_plaintext(rl, | ||
523 | content_type, content, content_len, &fragment)) | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | if (!CBB_flush(cbb)) | ||
528 | return 0; | ||
529 | |||
530 | tls1_record_sequence_increment(rl->write_seq_num); | ||
531 | |||
532 | return 1; | ||
533 | } | ||