summaryrefslogtreecommitdiff
path: root/src/lib/libssl/d1_pkt.c
diff options
context:
space:
mode:
authormarkus <>2013-02-14 15:11:44 +0000
committermarkus <>2013-02-14 15:11:44 +0000
commit9822d929c08eed1446dc09464293449326730af2 (patch)
treecd2035e8f8ac3d4ade1ee779dcaabbe671c2003a /src/lib/libssl/d1_pkt.c
parent692574e51be904b35cfcb2609fd641e93dc8cef7 (diff)
downloadopenbsd-9822d929c08eed1446dc09464293449326730af2.tar.gz
openbsd-9822d929c08eed1446dc09464293449326730af2.tar.bz2
openbsd-9822d929c08eed1446dc09464293449326730af2.zip
cherry pick bugfixes for http://www.openssl.org/news/secadv_20130205.txt
from the openssl git (changes between openssl 1.0.1c and 1.0.1d). ok djm@
Diffstat (limited to 'src/lib/libssl/d1_pkt.c')
-rw-r--r--src/lib/libssl/d1_pkt.c91
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
376dtls1_process_record(SSL *s) 376dtls1_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;