LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - cipher-cbc.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 52 55 94.5 %
Date: 2020-10-30 04:50:48 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2000-2013 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2013 Nikos Mavrogiannopoulos
       4             :  * Copyright (C) 2017-2018 Red Hat, Inc.
       5             :  *
       6             :  * Author: Nikos Mavrogiannopoulos
       7             :  *
       8             :  * This file is part of GnuTLS.
       9             :  *
      10             :  * The GnuTLS is free software; you can redistribute it and/or
      11             :  * modify it under the terms of the GNU Lesser General Public License
      12             :  * as published by the Free Software Foundation; either version 2.1 of
      13             :  * the License, or (at your option) any later version.
      14             :  *
      15             :  * This library is distributed in the hope that it will be useful, but
      16             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :  * Lesser General Public License for more details.
      19             :  *
      20             :  * You should have received a copy of the GNU Lesser General Public License
      21             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      22             :  *
      23             :  */
      24             : 
      25             : #include "gnutls_int.h"
      26             : #include "cipher.h"
      27             : 
      28          85 : static void dummy_wait(record_parameters_st *params,
      29             :                        const uint8_t *data, size_t data_size,
      30             :                        unsigned int mac_data, unsigned int max_mac_data)
      31             : {
      32             :         /* this hack is only needed on CBC ciphers when Encrypt-then-MAC mode
      33             :          * is not supported by the peer. */
      34          85 :         unsigned v;
      35          85 :         unsigned int tag_size =
      36          85 :             _gnutls_auth_cipher_tag_len(&params->read.ctx.tls12);
      37          85 :         unsigned hash_block = _gnutls_mac_block_size(params->mac);
      38             : 
      39             :         /* force additional hash compression function evaluations to prevent timing
      40             :          * attacks that distinguish between wrong-mac + correct pad, from wrong-mac + incorrect pad.
      41             :          */
      42             : 
      43          85 :         if (params->mac && params->mac->id == GNUTLS_MAC_SHA384)
      44             :                 /* v = 1 for the hash function padding + 16 for message length */
      45             :                 v = 17;
      46             :         else /* v = 1 for the hash function padding + 8 for message length */
      47          85 :                 v = 9;
      48             : 
      49          85 :         if (hash_block > 0) {
      50          85 :                 int max_blocks = (max_mac_data+v+hash_block-1)/hash_block;
      51          85 :                 int hashed_blocks = (mac_data+v+hash_block-1)/hash_block;
      52          85 :                 unsigned to_hash;
      53             : 
      54          85 :                 max_blocks -= hashed_blocks;
      55          85 :                 if (max_blocks < 1)
      56             :                         return;
      57             : 
      58          11 :                 to_hash = max_blocks * hash_block;
      59          11 :                 if ((unsigned)to_hash+1+tag_size < data_size) {
      60          11 :                         _gnutls_auth_cipher_add_auth
      61             :                                     (&params->read.ctx.tls12,
      62          11 :                                      data+data_size-tag_size-to_hash-1,
      63             :                                      to_hash);
      64             :                 }
      65             :         }
      66             : }
      67             : 
      68             : /* Verifies the CBC HMAC. That's a special case as it tries to avoid
      69             :  * any leaks which could make CBC ciphersuites without EtM usable as an
      70             :  * oracle to attacks.
      71             :  */
      72        8561 : int cbc_mac_verify(gnutls_session_t session, record_parameters_st *params,
      73             :                    uint8_t preamble[MAX_PREAMBLE_SIZE],
      74             :                    content_type_t type,
      75             :                    uint64_t sequence,
      76             :                    const uint8_t *data, size_t data_size,
      77             :                    size_t tag_size)
      78             : {
      79        8561 :         int ret;
      80        8561 :         const version_entry_st *ver = get_version(session);
      81        8561 :         unsigned int tmp_pad_failed = 0;
      82        8561 :         unsigned int pad_failed = 0;
      83        8561 :         unsigned int pad, i, length;
      84        8561 :         const uint8_t *tag_ptr = NULL;
      85        8561 :         unsigned preamble_size;
      86        8561 :         uint8_t tag[MAX_HASH_SIZE];
      87             : #ifdef ENABLE_SSL3
      88             :         unsigned blocksize = _gnutls_cipher_get_block_size(params->cipher);
      89             : #endif
      90             : 
      91        8561 :         pad = data[data_size - 1];      /* pad */
      92             : 
      93             :         /* Check the padding bytes (TLS 1.x).
      94             :          * Note that we access all 256 bytes of ciphertext for padding check
      95             :          * because there is a timing channel in that memory access (in certain CPUs).
      96             :          */
      97             : #ifdef ENABLE_SSL3
      98             :         if (ver->id == GNUTLS_SSL3) {
      99             :                 if (pad >= blocksize)
     100             :                         pad_failed = 1;
     101             :         } else
     102             : #endif
     103             :         {
     104      515672 :                 for (i = 2; i <= MIN(256, data_size); i++) {
     105      507111 :                         tmp_pad_failed |=
     106      507111 :                             (data[data_size - i] != pad);
     107      507111 :                         pad_failed |=
     108      507111 :                             ((i <= (1 + pad)) & (tmp_pad_failed));
     109             :                 }
     110             :         }
     111             : 
     112        8561 :         if (unlikely
     113             :             (pad_failed != 0
     114             :              || (1 + pad > ((int) data_size - tag_size)))) {
     115             :                 /* We do not fail here. We check below for the
     116             :                  * the pad_failed. If zero means success.
     117             :                  */
     118          45 :                 pad_failed = 1;
     119          45 :                 pad = 0;
     120             :         }
     121             : 
     122        8561 :         length = data_size - tag_size - pad - 1;
     123        8561 :         tag_ptr = &data[length];
     124             : 
     125             :         /* Pass the type, version, length and plain through
     126             :          * MAC.
     127             :          */
     128       17122 :         preamble_size =
     129        8561 :             _gnutls_make_preamble(sequence, type,
     130             :                                   length, ver, preamble);
     131             : 
     132        8561 :         ret =
     133        8561 :             _gnutls_auth_cipher_add_auth(&params->read.
     134             :                                          ctx.tls12, preamble,
     135             :                                          preamble_size);
     136        8561 :         if (unlikely(ret < 0))
     137           0 :                 return gnutls_assert_val(ret);
     138             : 
     139        8561 :         ret =
     140        8561 :             _gnutls_auth_cipher_add_auth(&params->read.
     141             :                                          ctx.tls12,
     142             :                                          data, length);
     143        8561 :         if (unlikely(ret < 0))
     144           0 :                 return gnutls_assert_val(ret);
     145             : 
     146        8561 :         ret =
     147        8561 :             _gnutls_auth_cipher_tag(&params->read.ctx.tls12, tag,
     148             :                                     tag_size);
     149        8561 :         if (unlikely(ret < 0))
     150           0 :                 return gnutls_assert_val(ret);
     151             : 
     152        8561 :         if (unlikely
     153             :             (gnutls_memcmp(tag, tag_ptr, tag_size) != 0 || pad_failed != 0)) {
     154             :                 /* HMAC was not the same. */
     155          85 :                 dummy_wait(params, data, data_size,
     156             :                            length + preamble_size,
     157          85 :                            preamble_size + data_size - tag_size - 1);
     158             : 
     159         139 :                 return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
     160             :         }
     161             : 
     162             :         return length;
     163             : }

Generated by: LCOV version 1.14