~ubuntu-branches/ubuntu/lucid/gnutls26/lucid-updates

« back to all changes in this revision

Viewing changes to lib/gnutls_cipher.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-02-25 12:36:24 UTC
  • mfrom: (21.2.1 lucid-security)
  • Revision ID: package-import@ubuntu.com-20130225123624-trcbw410sdydk9t9
Tags: 2.8.5-2ubuntu0.3
* SECURITY UPDATE: "Lucky Thirteen" timing side-channel TLS attack
  - debian/patches/CVE-2013-1619.patch: avoid timing attacks in
    lib/gnutls_cipher.c, lib/gnutls_hash_int.h.
  - CVE-2013-1619

Show diffs side-by-side

added added

removed removed

Lines of Context:
418
418
  return length;
419
419
}
420
420
 
 
421
static void dummy_wait(gnutls_session_t session, gnutls_datum_t* plaintext, 
 
422
                       unsigned pad_failed, unsigned int pad, unsigned total, int ver)
 
423
{
 
424
  /* this hack is only needed on CBC ciphers */
 
425
  if (_gnutls_cipher_is_block (session->security_parameters.read_bulk_cipher_algorithm) == CIPHER_BLOCK)
 
426
    {
 
427
      uint8_t MAC[MAX_HASH_SIZE];
 
428
      unsigned len;
 
429
      digest_hd_st td;
 
430
      int ret;
 
431
 
 
432
      ret = mac_init (&td, session->security_parameters.read_mac_algorithm,
 
433
                      session->connection_state.read_mac_secret.data,
 
434
                      session->connection_state.read_mac_secret.size, ver);
 
435
 
 
436
      if (ret < 0)
 
437
        return;
 
438
 
 
439
      /* force an additional hash compression function evaluation to prevent timing 
 
440
       * attacks that distinguish between wrong-mac + correct pad, from wrong-mac + incorrect pad.
 
441
       */
 
442
      if (pad_failed == 0 && pad > 0) 
 
443
        {
 
444
          len = _gnutls_get_hash_block_len(session->security_parameters.read_mac_algorithm);
 
445
          if (len > 0)
 
446
            {
 
447
              /* This is really specific to the current hash functions.
 
448
               * It should be removed once a protocol fix is in place.
 
449
               */
 
450
              if ((pad+total) % len > len-9 && total % len <= len-9) 
 
451
                {
 
452
                  if (len < plaintext->size)
 
453
                    _gnutls_hmac (&td, plaintext->data, len);
 
454
                  else
 
455
                    _gnutls_hmac (&td, plaintext->data, plaintext->size);
 
456
                }
 
457
            }
 
458
        }
 
459
 
 
460
      mac_deinit (&td, MAC, ver);
 
461
    }
 
462
}
 
463
 
421
464
/* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
422
465
 * Returns the actual compressed packet size.
423
466
 */
429
472
{
430
473
  uint8_t MAC[MAX_HASH_SIZE];
431
474
  uint16_t c_length;
432
 
  uint8_t pad;
 
475
  unsigned int pad = 0;
433
476
  int length;
434
477
  digest_hd_st td;
435
478
  uint16_t blocksize;
436
479
  int ret, i, pad_failed = 0;
 
480
  int preamble_size = 0;
437
481
  uint8_t major, minor;
438
482
  gnutls_protocol_t ver;
439
483
  int hash_size =
508
552
          gnutls_assert ();
509
553
          return GNUTLS_E_DECRYPTION_FAILED;
510
554
        }
511
 
      pad = ciphertext.data[ciphertext.size - 1] + 1;   /* pad */
512
 
 
513
 
      if ((int) pad > (int) ciphertext.size - hash_size)
514
 
        {
515
 
          gnutls_assert ();
516
 
          _gnutls_record_log
517
 
            ("REC[%p]: Short record length %d > %d - %d (under attack?)\n",
518
 
             session, pad, ciphertext.size, hash_size);
519
 
          /* We do not fail here. We check below for the
520
 
           * the pad_failed. If zero means success.
521
 
           */
522
 
          pad_failed = GNUTLS_E_DECRYPTION_FAILED;
523
 
        }
524
 
 
525
 
      length = ciphertext.size - hash_size - pad;
526
 
 
527
 
      /* Check the pading bytes (TLS 1.x)
 
555
      pad = ciphertext.data[ciphertext.size - 1];   /* pad */
 
556
 
 
557
      /* Check the pading bytes (TLS 1.x). 
 
558
       * Note that we access all 256 bytes of ciphertext for padding check
 
559
       * because there is a timing channel in that memory access (in certain CPUs).
528
560
       */
529
561
      if (ver >= GNUTLS_TLS1 && pad_failed == 0)
530
 
        for (i = 2; i < pad; i++)
 
562
        for (i = 2; i <= pad; i++)
531
563
          {
532
 
            if (ciphertext.data[ciphertext.size - i] !=
533
 
                ciphertext.data[ciphertext.size - 1])
 
564
            if (ciphertext.data[ciphertext.size - i] != pad)
534
565
              pad_failed = GNUTLS_E_DECRYPTION_FAILED;
535
566
          }
 
567
          
 
568
      if (pad_failed)
 
569
        pad = 0;
 
570
      length = ciphertext.size - hash_size - pad - 1;
 
571
 
536
572
      break;
537
573
    default:
538
574
      gnutls_assert ();
551
587
      _gnutls_hmac (&td,
552
588
                    UINT64DATA (session->connection_state.
553
589
                                read_sequence_number), 8);
 
590
      preamble_size += 8;
554
591
 
555
592
      _gnutls_hmac (&td, &type, 1);
 
593
      preamble_size++;
556
594
      if (ver >= GNUTLS_TLS1)
557
595
        {                       /* TLS 1.x */
558
596
          _gnutls_hmac (&td, &major, 1);
 
597
          preamble_size++;
559
598
          _gnutls_hmac (&td, &minor, 1);
 
599
          preamble_size++;
560
600
        }
561
601
      _gnutls_hmac (&td, &c_length, 2);
 
602
      preamble_size += 2;
562
603
 
563
604
      if (length > 0)
564
605
        _gnutls_hmac (&td, ciphertext.data, length);
566
607
      mac_deinit (&td, MAC, ver);
567
608
    }
568
609
 
569
 
  /* This one was introduced to avoid a timing attack against the TLS
570
 
   * 1.0 protocol.
571
 
   */
572
 
  if (pad_failed != 0)
573
 
    return pad_failed;
574
 
 
575
610
  /* HMAC was not the same. 
576
611
   */
577
 
  if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
 
612
  if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0 || pad_failed != 0)
578
613
    {
 
614
      gnutls_datum_t compressed = {compress_data, compress_size};
 
615
      /* HMAC was not the same. */
 
616
      dummy_wait(session, &compressed, pad_failed, pad, length+preamble_size, ver);
 
617
 
579
618
      gnutls_assert ();
580
619
      return GNUTLS_E_DECRYPTION_FAILED;
581
620
    }
582
621
 
583
 
  /* copy the decrypted stuff to compress_data.
 
622
  /* copy the decrypted stuff to compressed_data.
584
623
   */
585
624
  if (compress_size < length)
586
625
    {