diff options
Diffstat (limited to 'src/lib/libssl/d1_pkt.c')
-rw-r--r-- | src/lib/libssl/d1_pkt.c | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c index 987af60835..cfe4524553 100644 --- a/src/lib/libssl/d1_pkt.c +++ b/src/lib/libssl/d1_pkt.c | |||
@@ -376,15 +376,11 @@ static int | |||
376 | dtls1_process_record(SSL *s) | 376 | dtls1_process_record(SSL *s) |
377 | { | 377 | { |
378 | int i,al; | 378 | int i,al; |
379 | int clear=0; | ||
380 | int enc_err; | 379 | int enc_err; |
381 | SSL_SESSION *sess; | 380 | SSL_SESSION *sess; |
382 | SSL3_RECORD *rr; | 381 | SSL3_RECORD *rr; |
383 | unsigned int mac_size; | 382 | unsigned int mac_size, orig_len; |
384 | unsigned char md[EVP_MAX_MD_SIZE]; | 383 | unsigned char md[EVP_MAX_MD_SIZE]; |
385 | int decryption_failed_or_bad_record_mac = 0; | ||
386 | unsigned char *mac = NULL; | ||
387 | |||
388 | 384 | ||
389 | rr= &(s->s3->rrec); | 385 | rr= &(s->s3->rrec); |
390 | sess = s->session; | 386 | sess = s->session; |
@@ -416,12 +412,16 @@ dtls1_process_record(SSL *s) | |||
416 | rr->data=rr->input; | 412 | rr->data=rr->input; |
417 | 413 | ||
418 | enc_err = s->method->ssl3_enc->enc(s,0); | 414 | enc_err = s->method->ssl3_enc->enc(s,0); |
419 | if (enc_err <= 0) | 415 | /* enc_err is: |
416 | * 0: (in non-constant time) if the record is publically invalid. | ||
417 | * 1: if the padding is valid | ||
418 | * -1: if the padding is invalid */ | ||
419 | if (enc_err == 0) | ||
420 | { | 420 | { |
421 | /* To minimize information leaked via timing, we will always | 421 | /* For DTLS we simply ignore bad packets. */ |
422 | * perform all computations before discarding the message. | 422 | rr->length = 0; |
423 | */ | 423 | s->packet_length = 0; |
424 | decryption_failed_or_bad_record_mac = 1; | 424 | goto err; |
425 | } | 425 | } |
426 | 426 | ||
427 | #ifdef TLS_DEBUG | 427 | #ifdef TLS_DEBUG |
@@ -431,45 +431,62 @@ printf("\n"); | |||
431 | #endif | 431 | #endif |
432 | 432 | ||
433 | /* r->length is now the compressed data plus mac */ | 433 | /* r->length is now the compressed data plus mac */ |
434 | if ( (sess == NULL) || | 434 | if ((sess != NULL) && |
435 | (s->enc_read_ctx == NULL) || | 435 | (s->enc_read_ctx != NULL) && |
436 | (s->read_hash == NULL)) | 436 | (EVP_MD_CTX_md(s->read_hash) != NULL)) |
437 | clear=1; | ||
438 | |||
439 | if (!clear) | ||
440 | { | 437 | { |
441 | /* !clear => s->read_hash != NULL => mac_size != -1 */ | 438 | /* s->read_hash != NULL => mac_size != -1 */ |
442 | int t; | 439 | unsigned char *mac = NULL; |
443 | t=EVP_MD_CTX_size(s->read_hash); | 440 | unsigned char mac_tmp[EVP_MAX_MD_SIZE]; |
444 | OPENSSL_assert(t >= 0); | 441 | mac_size=EVP_MD_CTX_size(s->read_hash); |
445 | mac_size=t; | 442 | OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); |
446 | 443 | ||
447 | if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) | 444 | /* kludge: *_cbc_remove_padding passes padding length in rr->type */ |
445 | orig_len = rr->length+((unsigned int)rr->type>>8); | ||
446 | |||
447 | /* orig_len is the length of the record before any padding was | ||
448 | * removed. This is public information, as is the MAC in use, | ||
449 | * therefore we can safely process the record in a different | ||
450 | * amount of time if it's too short to possibly contain a MAC. | ||
451 | */ | ||
452 | if (orig_len < mac_size || | ||
453 | /* CBC records must have a padding length byte too. */ | ||
454 | (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && | ||
455 | orig_len < mac_size+1)) | ||
448 | { | 456 | { |
449 | #if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ | 457 | al=SSL_AD_DECODE_ERROR; |
450 | al=SSL_AD_RECORD_OVERFLOW; | 458 | SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); |
451 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); | ||
452 | goto f_err; | 459 | goto f_err; |
453 | #else | ||
454 | decryption_failed_or_bad_record_mac = 1; | ||
455 | #endif | ||
456 | } | 460 | } |
457 | /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ | 461 | |
458 | if (rr->length >= mac_size) | 462 | if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) |
459 | { | 463 | { |
464 | /* We update the length so that the TLS header bytes | ||
465 | * can be constructed correctly but we need to extract | ||
466 | * the MAC in constant time from within the record, | ||
467 | * without leaking the contents of the padding bytes. | ||
468 | * */ | ||
469 | mac = mac_tmp; | ||
470 | ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); | ||
460 | rr->length -= mac_size; | 471 | rr->length -= mac_size; |
461 | mac = &rr->data[rr->length]; | ||
462 | } | 472 | } |
463 | else | 473 | else |
464 | rr->length = 0; | ||
465 | i=s->method->ssl3_enc->mac(s,md,0); | ||
466 | if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0) | ||
467 | { | 474 | { |
468 | decryption_failed_or_bad_record_mac = 1; | 475 | /* In this case there's no padding, so |orig_len| |
476 | * equals |rec->length| and we checked that there's | ||
477 | * enough bytes for |mac_size| above. */ | ||
478 | rr->length -= mac_size; | ||
479 | mac = &rr->data[rr->length]; | ||
469 | } | 480 | } |
481 | |||
482 | i=s->method->ssl3_enc->mac(s,md,0 /* not send */); | ||
483 | if (i < 0 || mac == NULL || timingsafe_bcmp(md, mac, (size_t)mac_size) != 0) | ||
484 | enc_err = -1; | ||
485 | if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) | ||
486 | enc_err = -1; | ||
470 | } | 487 | } |
471 | 488 | ||
472 | if (decryption_failed_or_bad_record_mac) | 489 | if (enc_err < 0) |
473 | { | 490 | { |
474 | /* decryption failed, silently discard message */ | 491 | /* decryption failed, silently discard message */ |
475 | rr->length = 0; | 492 | rr->length = 0; |