diff options
author | jsing <> | 2020-10-03 17:35:17 +0000 |
---|---|---|
committer | jsing <> | 2020-10-03 17:35:17 +0000 |
commit | 3058247715ff89d092334e9137126e12b7220589 (patch) | |
tree | f4def91d73228cb651f854abf6bf23f4d3c22025 /src/lib/libssl/ssl_pkt.c | |
parent | 0f1f8d13de82c94a30254ca849b3933f8356101b (diff) | |
download | openbsd-3058247715ff89d092334e9137126e12b7220589.tar.gz openbsd-3058247715ff89d092334e9137126e12b7220589.tar.bz2 openbsd-3058247715ff89d092334e9137126e12b7220589.zip |
Reimplement the TLSv1.2 record handling for the read side.
This is the next step in replacing the TLSv1.2 record layer.
The existing record handling code does decryption and processing in
place, which is not ideal for various reasons, however it is retained
for now as other code depends on this behaviour. Additionally, CBC
requires special handling to avoid timing oracles - for now the
existing timing safe code is largely retained.
ok beck@ inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/ssl_pkt.c')
-rw-r--r-- | src/lib/libssl/ssl_pkt.c | 166 |
1 files changed, 33 insertions, 133 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index c9c86471d3..02a476ea82 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.31 2020/08/30 15:40:20 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.32 2020/10/03 17:35:16 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 | * |
@@ -149,15 +149,14 @@ ssl_force_want_read(SSL *s) | |||
149 | static int | 149 | static int |
150 | ssl3_read_n(SSL *s, int n, int max, int extend) | 150 | ssl3_read_n(SSL *s, int n, int max, int extend) |
151 | { | 151 | { |
152 | SSL3_BUFFER_INTERNAL *rb = &(S3I(s)->rbuf); | ||
152 | int i, len, left; | 153 | int i, len, left; |
153 | size_t align; | 154 | size_t align; |
154 | unsigned char *pkt; | 155 | unsigned char *pkt; |
155 | SSL3_BUFFER_INTERNAL *rb; | ||
156 | 156 | ||
157 | if (n <= 0) | 157 | if (n <= 0) |
158 | return n; | 158 | return n; |
159 | 159 | ||
160 | rb = &(S3I(s)->rbuf); | ||
161 | if (rb->buf == NULL) | 160 | if (rb->buf == NULL) |
162 | if (!ssl3_setup_read_buffer(s)) | 161 | if (!ssl3_setup_read_buffer(s)) |
163 | return -1; | 162 | return -1; |
@@ -327,15 +326,13 @@ ssl3_packet_extend(SSL *s, int plen) | |||
327 | static int | 326 | static int |
328 | ssl3_get_record(SSL *s) | 327 | ssl3_get_record(SSL *s) |
329 | { | 328 | { |
330 | int al; | 329 | SSL3_BUFFER_INTERNAL *rb = &(S3I(s)->rbuf); |
331 | int enc_err, n, i, ret = -1; | 330 | SSL3_RECORD_INTERNAL *rr = &(S3I(s)->rrec); |
332 | SSL3_RECORD_INTERNAL *rr; | 331 | uint8_t alert_desc; |
333 | SSL_SESSION *sess; | 332 | uint8_t *out; |
334 | unsigned char md[EVP_MAX_MD_SIZE]; | 333 | size_t out_len; |
335 | unsigned int mac_size, orig_len; | 334 | int al, n; |
336 | 335 | int ret = -1; | |
337 | rr = &(S3I(s)->rrec); | ||
338 | sess = s->session; | ||
339 | 336 | ||
340 | again: | 337 | again: |
341 | /* check if we have the header */ | 338 | /* check if we have the header */ |
@@ -387,17 +384,13 @@ ssl3_get_record(SSL *s) | |||
387 | goto err; | 384 | goto err; |
388 | } | 385 | } |
389 | 386 | ||
390 | if (rr->length > S3I(s)->rbuf.len - SSL3_RT_HEADER_LENGTH) { | 387 | if (rr->length > rb->len - SSL3_RT_HEADER_LENGTH) { |
391 | al = SSL_AD_RECORD_OVERFLOW; | 388 | al = SSL_AD_RECORD_OVERFLOW; |
392 | SSLerror(s, SSL_R_PACKET_LENGTH_TOO_LONG); | 389 | SSLerror(s, SSL_R_PACKET_LENGTH_TOO_LONG); |
393 | goto f_err; | 390 | goto f_err; |
394 | } | 391 | } |
395 | |||
396 | /* now s->internal->rstate == SSL_ST_READ_BODY */ | ||
397 | } | 392 | } |
398 | 393 | ||
399 | /* s->internal->rstate == SSL_ST_READ_BODY, get and decode the data */ | ||
400 | |||
401 | n = ssl3_packet_extend(s, SSL3_RT_HEADER_LENGTH + rr->length); | 394 | n = ssl3_packet_extend(s, SSL3_RT_HEADER_LENGTH + rr->length); |
402 | if (n <= 0) | 395 | if (n <= 0) |
403 | return (n); | 396 | return (n); |
@@ -406,133 +399,40 @@ ssl3_get_record(SSL *s) | |||
406 | 399 | ||
407 | s->internal->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ | 400 | s->internal->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ |
408 | 401 | ||
409 | /* At this point, s->internal->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, | 402 | /* |
410 | * and we have that many bytes in s->internal->packet | 403 | * A full record has now been read from the wire, which now needs |
404 | * to be processed. | ||
411 | */ | 405 | */ |
412 | rr->input = &(s->internal->packet[SSL3_RT_HEADER_LENGTH]); | 406 | tls12_record_layer_set_version(s->internal->rl, s->version); |
413 | |||
414 | /* ok, we can now read from 's->internal->packet' data into 'rr' | ||
415 | * rr->input points at rr->length bytes, which | ||
416 | * need to be copied into rr->data by either | ||
417 | * the decryption or by the decompression | ||
418 | * When the data is 'copied' into the rr->data buffer, | ||
419 | * rr->input will be pointed at the new buffer */ | ||
420 | |||
421 | /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] | ||
422 | * rr->length bytes of encrypted compressed stuff. */ | ||
423 | |||
424 | /* check is not needed I believe */ | ||
425 | if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { | ||
426 | al = SSL_AD_RECORD_OVERFLOW; | ||
427 | SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | ||
428 | goto f_err; | ||
429 | } | ||
430 | |||
431 | /* decrypt in place in 'rr->input' */ | ||
432 | rr->data = rr->input; | ||
433 | 407 | ||
434 | /* enc_err is: | 408 | if (!tls12_record_layer_open_record(s->internal->rl, s->internal->packet, |
435 | * 0: (in non-constant time) if the record is publically invalid. | 409 | s->internal->packet_length, &out, &out_len)) { |
436 | * 1: if the padding is valid | 410 | tls12_record_layer_alert(s->internal->rl, &alert_desc); |
437 | * -1: if the padding is invalid */ | ||
438 | if ((enc_err = tls1_enc(s, 0)) == 0) { | ||
439 | al = SSL_AD_BAD_RECORD_MAC; | ||
440 | SSLerror(s, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); | ||
441 | goto f_err; | ||
442 | } | ||
443 | |||
444 | /* r->length is now the compressed data plus mac */ | ||
445 | if ((sess != NULL) && (s->enc_read_ctx != NULL) && | ||
446 | (EVP_MD_CTX_md(s->read_hash) != NULL)) { | ||
447 | /* s->read_hash != NULL => mac_size != -1 */ | ||
448 | unsigned char *mac = NULL; | ||
449 | unsigned char mac_tmp[EVP_MAX_MD_SIZE]; | ||
450 | |||
451 | mac_size = EVP_MD_CTX_size(s->read_hash); | ||
452 | OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); | ||
453 | |||
454 | orig_len = rr->length + rr->padding_length; | ||
455 | 411 | ||
456 | /* orig_len is the length of the record before any padding was | 412 | if (alert_desc == 0) |
457 | * removed. This is public information, as is the MAC in use, | 413 | goto err; |
458 | * therefore we can safely process the record in a different | ||
459 | * amount of time if it's too short to possibly contain a MAC. | ||
460 | */ | ||
461 | if (orig_len < mac_size || | ||
462 | /* CBC records must have a padding length byte too. */ | ||
463 | (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && | ||
464 | orig_len < mac_size + 1)) { | ||
465 | al = SSL_AD_DECODE_ERROR; | ||
466 | SSLerror(s, SSL_R_LENGTH_TOO_SHORT); | ||
467 | goto f_err; | ||
468 | } | ||
469 | |||
470 | if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { | ||
471 | /* We update the length so that the TLS header bytes | ||
472 | * can be constructed correctly but we need to extract | ||
473 | * the MAC in constant time from within the record, | ||
474 | * without leaking the contents of the padding bytes. | ||
475 | * */ | ||
476 | mac = mac_tmp; | ||
477 | ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); | ||
478 | rr->length -= mac_size; | ||
479 | } else { | ||
480 | /* In this case there's no padding, so |orig_len| | ||
481 | * equals |rec->length| and we checked that there's | ||
482 | * enough bytes for |mac_size| above. */ | ||
483 | rr->length -= mac_size; | ||
484 | mac = &rr->data[rr->length]; | ||
485 | } | ||
486 | 414 | ||
487 | i = tls1_mac(s,md,0 /* not send */); | 415 | if (alert_desc == SSL_AD_RECORD_OVERFLOW) |
488 | if (i < 0 || mac == NULL || | 416 | SSLerror(s, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); |
489 | timingsafe_memcmp(md, mac, (size_t)mac_size) != 0) | 417 | else if (alert_desc == SSL_AD_BAD_RECORD_MAC) |
490 | enc_err = -1; | 418 | SSLerror(s, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); |
491 | if (rr->length > | ||
492 | SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) | ||
493 | enc_err = -1; | ||
494 | } | ||
495 | 419 | ||
496 | if (enc_err < 0) { | 420 | al = alert_desc; |
497 | /* | ||
498 | * A separate 'decryption_failed' alert was introduced with | ||
499 | * TLS 1.0, SSL 3.0 only has 'bad_record_mac'. But unless a | ||
500 | * decryption failure is directly visible from the ciphertext | ||
501 | * anyway, we should not reveal which kind of error | ||
502 | * occurred -- this might become visible to an attacker | ||
503 | * (e.g. via a logfile) | ||
504 | */ | ||
505 | al = SSL_AD_BAD_RECORD_MAC; | ||
506 | SSLerror(s, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); | ||
507 | goto f_err; | ||
508 | } | ||
509 | |||
510 | if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { | ||
511 | al = SSL_AD_RECORD_OVERFLOW; | ||
512 | SSLerror(s, SSL_R_DATA_LENGTH_TOO_LONG); | ||
513 | goto f_err; | 421 | goto f_err; |
514 | } | 422 | } |
515 | 423 | ||
424 | rr->data = out; | ||
425 | rr->length = out_len; | ||
516 | rr->off = 0; | 426 | rr->off = 0; |
517 | /* | ||
518 | * So at this point the following is true | ||
519 | * | ||
520 | * ssl->s3->internal->rrec.type is the type of record | ||
521 | * ssl->s3->internal->rrec.length == number of bytes in record | ||
522 | * ssl->s3->internal->rrec.off == offset to first valid byte | ||
523 | * ssl->s3->internal->rrec.data == where to take bytes from, increment | ||
524 | * after use :-). | ||
525 | */ | ||
526 | 427 | ||
527 | /* we have pulled in a full packet so zero things */ | 428 | /* we have pulled in a full packet so zero things */ |
528 | s->internal->packet_length = 0; | 429 | s->internal->packet_length = 0; |
529 | 430 | ||
530 | if (rr->length == 0) { | 431 | if (rr->length == 0) { |
531 | /* | 432 | /* |
532 | * CBC countermeasures for known IV weaknesses | 433 | * CBC countermeasures for known IV weaknesses can legitimately |
533 | * can legitimately insert a single empty record, | 434 | * insert a single empty record, so we allow ourselves to read |
534 | * so we allow ourselves to read once past a single | 435 | * once past a single empty record without forcing want_read. |
535 | * empty record without forcing want_read. | ||
536 | */ | 436 | */ |
537 | if (s->internal->empty_record_count++ > SSL_MAX_EMPTY_RECORDS) { | 437 | if (s->internal->empty_record_count++ > SSL_MAX_EMPTY_RECORDS) { |
538 | SSLerror(s, SSL_R_PEER_BEHAVING_BADLY); | 438 | SSLerror(s, SSL_R_PEER_BEHAVING_BADLY); |
@@ -543,15 +443,15 @@ ssl3_get_record(SSL *s) | |||
543 | return -1; | 443 | return -1; |
544 | } | 444 | } |
545 | goto again; | 445 | goto again; |
546 | } else { | ||
547 | s->internal->empty_record_count = 0; | ||
548 | } | 446 | } |
549 | 447 | ||
448 | s->internal->empty_record_count = 0; | ||
449 | |||
550 | return (1); | 450 | return (1); |
551 | 451 | ||
552 | f_err: | 452 | f_err: |
553 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 453 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
554 | err: | 454 | err: |
555 | return (ret); | 455 | return (ret); |
556 | } | 456 | } |
557 | 457 | ||