diff options
Diffstat (limited to 'src')
| -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 | } | ||
