diff options
Diffstat (limited to 'src/lib/libssl/s3_pkt.c')
-rw-r--r-- | src/lib/libssl/s3_pkt.c | 98 |
1 files changed, 51 insertions, 47 deletions
diff --git a/src/lib/libssl/s3_pkt.c b/src/lib/libssl/s3_pkt.c index adf8c387cc..a7d2defbea 100644 --- a/src/lib/libssl/s3_pkt.c +++ b/src/lib/libssl/s3_pkt.c | |||
@@ -290,11 +290,8 @@ static int ssl3_get_record(SSL *s) | |||
290 | unsigned char *p; | 290 | unsigned char *p; |
291 | unsigned char md[EVP_MAX_MD_SIZE]; | 291 | unsigned char md[EVP_MAX_MD_SIZE]; |
292 | short version; | 292 | short version; |
293 | int mac_size; | 293 | unsigned mac_size, orig_len; |
294 | int clear=0; | ||
295 | size_t extra; | 294 | size_t extra; |
296 | int decryption_failed_or_bad_record_mac = 0; | ||
297 | unsigned char *mac = NULL; | ||
298 | 295 | ||
299 | rr= &(s->s3->rrec); | 296 | rr= &(s->s3->rrec); |
300 | sess=s->session; | 297 | sess=s->session; |
@@ -403,17 +400,15 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); | |||
403 | rr->data=rr->input; | 400 | rr->data=rr->input; |
404 | 401 | ||
405 | enc_err = s->method->ssl3_enc->enc(s,0); | 402 | enc_err = s->method->ssl3_enc->enc(s,0); |
406 | if (enc_err <= 0) | 403 | /* enc_err is: |
404 | * 0: (in non-constant time) if the record is publically invalid. | ||
405 | * 1: if the padding is valid | ||
406 | * -1: if the padding is invalid */ | ||
407 | if (enc_err == 0) | ||
407 | { | 408 | { |
408 | if (enc_err == 0) | 409 | al=SSL_AD_DECRYPTION_FAILED; |
409 | /* SSLerr() and ssl3_send_alert() have been called */ | 410 | SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); |
410 | goto err; | 411 | goto f_err; |
411 | |||
412 | /* Otherwise enc_err == -1, which indicates bad padding | ||
413 | * (rec->length has not been changed in this case). | ||
414 | * To minimize information leaked via timing, we will perform | ||
415 | * the MAC computation anyway. */ | ||
416 | decryption_failed_or_bad_record_mac = 1; | ||
417 | } | 412 | } |
418 | 413 | ||
419 | #ifdef TLS_DEBUG | 414 | #ifdef TLS_DEBUG |
@@ -423,53 +418,62 @@ printf("\n"); | |||
423 | #endif | 418 | #endif |
424 | 419 | ||
425 | /* r->length is now the compressed data plus mac */ | 420 | /* r->length is now the compressed data plus mac */ |
426 | if ( (sess == NULL) || | 421 | if ((sess != NULL) && |
427 | (s->enc_read_ctx == NULL) || | 422 | (s->enc_read_ctx != NULL) && |
428 | (EVP_MD_CTX_md(s->read_hash) == NULL)) | 423 | (EVP_MD_CTX_md(s->read_hash) != NULL)) |
429 | clear=1; | ||
430 | |||
431 | if (!clear) | ||
432 | { | 424 | { |
433 | /* !clear => s->read_hash != NULL => mac_size != -1 */ | 425 | /* s->read_hash != NULL => mac_size != -1 */ |
426 | unsigned char *mac = NULL; | ||
427 | unsigned char mac_tmp[EVP_MAX_MD_SIZE]; | ||
434 | mac_size=EVP_MD_CTX_size(s->read_hash); | 428 | mac_size=EVP_MD_CTX_size(s->read_hash); |
435 | OPENSSL_assert(mac_size >= 0); | 429 | OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); |
436 | 430 | ||
437 | if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) | 431 | /* kludge: *_cbc_remove_padding passes padding length in rr->type */ |
432 | orig_len = rr->length+((unsigned int)rr->type>>8); | ||
433 | |||
434 | /* orig_len is the length of the record before any padding was | ||
435 | * removed. This is public information, as is the MAC in use, | ||
436 | * therefore we can safely process the record in a different | ||
437 | * amount of time if it's too short to possibly contain a MAC. | ||
438 | */ | ||
439 | if (orig_len < mac_size || | ||
440 | /* CBC records must have a padding length byte too. */ | ||
441 | (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && | ||
442 | orig_len < mac_size+1)) | ||
438 | { | 443 | { |
439 | #if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ | 444 | al=SSL_AD_DECODE_ERROR; |
440 | al=SSL_AD_RECORD_OVERFLOW; | 445 | SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); |
441 | SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); | ||
442 | goto f_err; | 446 | goto f_err; |
443 | #else | ||
444 | decryption_failed_or_bad_record_mac = 1; | ||
445 | #endif | ||
446 | } | 447 | } |
447 | /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ | 448 | |
448 | if (rr->length >= (unsigned int)mac_size) | 449 | if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) |
449 | { | 450 | { |
451 | /* We update the length so that the TLS header bytes | ||
452 | * can be constructed correctly but we need to extract | ||
453 | * the MAC in constant time from within the record, | ||
454 | * without leaking the contents of the padding bytes. | ||
455 | * */ | ||
456 | mac = mac_tmp; | ||
457 | ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); | ||
450 | rr->length -= mac_size; | 458 | rr->length -= mac_size; |
451 | mac = &rr->data[rr->length]; | ||
452 | } | 459 | } |
453 | else | 460 | else |
454 | { | 461 | { |
455 | /* record (minus padding) is too short to contain a MAC */ | 462 | /* In this case there's no padding, so |orig_len| |
456 | #if 0 /* OK only for stream ciphers */ | 463 | * equals |rec->length| and we checked that there's |
457 | al=SSL_AD_DECODE_ERROR; | 464 | * enough bytes for |mac_size| above. */ |
458 | SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); | 465 | rr->length -= mac_size; |
459 | goto f_err; | 466 | mac = &rr->data[rr->length]; |
460 | #else | ||
461 | decryption_failed_or_bad_record_mac = 1; | ||
462 | rr->length = 0; | ||
463 | #endif | ||
464 | } | ||
465 | i=s->method->ssl3_enc->mac(s,md,0); | ||
466 | if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0) | ||
467 | { | ||
468 | decryption_failed_or_bad_record_mac = 1; | ||
469 | } | 467 | } |
468 | |||
469 | i=s->method->ssl3_enc->mac(s,md,0 /* not send */); | ||
470 | if (i < 0 || mac == NULL || timingsafe_bcmp(md, mac, (size_t)mac_size) != 0) | ||
471 | enc_err = -1; | ||
472 | if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size) | ||
473 | enc_err = -1; | ||
470 | } | 474 | } |
471 | 475 | ||
472 | if (decryption_failed_or_bad_record_mac) | 476 | if (enc_err < 0) |
473 | { | 477 | { |
474 | /* A separate 'decryption_failed' alert was introduced with TLS 1.0, | 478 | /* A separate 'decryption_failed' alert was introduced with TLS 1.0, |
475 | * SSL 3.0 only has 'bad_record_mac'. But unless a decryption | 479 | * SSL 3.0 only has 'bad_record_mac'. But unless a decryption |