LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/tls13 - finished.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 64 83 77.1 %
Date: 2020-10-30 04:50:48 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2017 Red Hat, Inc.
       3             :  *
       4             :  * Author: Nikos Mavrogiannopoulos
       5             :  *
       6             :  * This file is part of GnuTLS.
       7             :  *
       8             :  * The GnuTLS is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public License
      10             :  * as published by the Free Software Foundation; either version 2.1 of
      11             :  * the License, or (at your option) any later version.
      12             :  *
      13             :  * This library is distributed in the hope that it will be useful, but
      14             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public License
      19             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      20             :  *
      21             :  */
      22             : 
      23             : #include "gnutls_int.h"
      24             : #include "errors.h"
      25             : #include "handshake.h"
      26             : #include "tls13/finished.h"
      27             : #include "mem.h"
      28             : #include "mbuffers.h"
      29             : #include "secrets.h"
      30             : 
      31       17836 : int _gnutls13_compute_finished(const mac_entry_st *prf,
      32             :                 const uint8_t *base_key,
      33             :                 gnutls_buffer_st *handshake_hash_buffer,
      34             :                 void *out)
      35             : {
      36       17836 :         int ret;
      37       17836 :         uint8_t fkey[MAX_HASH_SIZE];
      38       17836 :         uint8_t ts_hash[MAX_HASH_SIZE];
      39             : 
      40       17836 :         ret = _tls13_expand_secret2(prf,
      41             :                         "finished", 8,
      42             :                         NULL, 0,
      43             :                         base_key,
      44             :                         prf->output_size, fkey);
      45       17836 :         if (ret < 0)
      46           0 :                 return gnutls_assert_val(ret);
      47             : 
      48       17836 :         ret = gnutls_hash_fast(MAC_TO_DIG(prf->id),
      49       17836 :                                handshake_hash_buffer->data,
      50             :                                handshake_hash_buffer->length,
      51             :                                ts_hash);
      52       17836 :         if (ret < 0)
      53           0 :                 return gnutls_assert_val(ret);
      54             : 
      55       35672 :         ret = gnutls_hmac_fast(prf->id,
      56             :                                fkey, prf->output_size,
      57       17836 :                                ts_hash, prf->output_size,
      58             :                                out);
      59       17836 :         if (ret < 0)
      60           0 :                 return gnutls_assert_val(ret);
      61             : 
      62             :         return 0;
      63             : }
      64             : 
      65        5955 : int _gnutls13_recv_finished(gnutls_session_t session)
      66             : {
      67        5955 :         int ret;
      68        5955 :         gnutls_buffer_st buf;
      69        5955 :         uint8_t verifier[MAX_HASH_SIZE];
      70        5955 :         const uint8_t *base_key;
      71        5955 :         unsigned hash_size;
      72             : 
      73        5955 :         if (unlikely(session->security_parameters.prf == NULL))
      74           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
      75             : 
      76        5955 :         hash_size = session->security_parameters.prf->output_size;
      77             : 
      78        5955 :         if (!session->internals.initial_negotiation_completed) {
      79        5928 :                 if (session->security_parameters.entity == GNUTLS_CLIENT)
      80         618 :                         base_key = session->key.proto.tls13.hs_skey;
      81             :                 else
      82        5310 :                         base_key = session->key.proto.tls13.hs_ckey;
      83             :         } else {
      84          27 :                 if (session->security_parameters.entity == GNUTLS_CLIENT)
      85           0 :                         base_key = session->key.proto.tls13.ap_skey;
      86             :                 else
      87          27 :                         base_key = session->key.proto.tls13.ap_ckey;
      88             :         }
      89             : 
      90        5955 :         ret = _gnutls13_compute_finished(session->security_parameters.prf,
      91             :                         base_key,
      92             :                         &session->internals.handshake_hash_buffer,
      93             :                         verifier);
      94        5955 :         if (ret < 0) {
      95           0 :                 gnutls_assert();
      96           0 :                 goto cleanup;
      97             :         }
      98             : 
      99        5955 :         ret = _gnutls_recv_handshake(session, GNUTLS_HANDSHAKE_FINISHED, 0, &buf);
     100        5955 :         if (ret < 0)
     101         272 :                 return gnutls_assert_val(ret);
     102             : 
     103        5705 :         _gnutls_handshake_log("HSK[%p]: parsing finished\n", session);
     104             : 
     105        5705 :         if (buf.length != hash_size) {
     106           0 :                 gnutls_assert();
     107           0 :                 ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
     108           0 :                 goto cleanup;
     109             :         }
     110             : 
     111             : 
     112             : #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
     113             : # warning This is unsafe for production builds
     114             : #else
     115        5705 :         if (gnutls_memcmp(verifier, buf.data, buf.length) != 0) {
     116           5 :                 gnutls_assert();
     117           5 :                 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
     118           5 :                 goto cleanup;
     119             :         }
     120             : #endif
     121             : 
     122             :         ret = 0;
     123        5705 : cleanup:
     124             :         
     125        5705 :         _gnutls_buffer_clear(&buf);
     126        5705 :         return ret;
     127             : }
     128             : 
     129        5809 : int _gnutls13_send_finished(gnutls_session_t session, unsigned again)
     130             : {
     131        5809 :         int ret;
     132        5809 :         uint8_t verifier[MAX_HASH_SIZE];
     133        5809 :         mbuffer_st *bufel = NULL;
     134        5809 :         const uint8_t *base_key;
     135        5809 :         unsigned hash_size;
     136             : 
     137        5809 :         if (again == 0) {
     138        5775 :                 if (unlikely(session->security_parameters.prf == NULL))
     139           0 :                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     140             : 
     141        5775 :                 hash_size = session->security_parameters.prf->output_size;
     142             : 
     143        5775 :                 if (!session->internals.initial_negotiation_completed) {
     144        5773 :                         if (session->security_parameters.entity == GNUTLS_CLIENT)
     145         593 :                                 base_key = session->key.proto.tls13.hs_ckey;
     146             :                         else
     147        5180 :                                 base_key = session->key.proto.tls13.hs_skey;
     148             :                 } else {
     149           2 :                         if (session->security_parameters.entity == GNUTLS_CLIENT)
     150           2 :                                 base_key = session->key.proto.tls13.ap_ckey;
     151             :                         else
     152           0 :                                 base_key = session->key.proto.tls13.ap_skey;
     153             :                 }
     154             : 
     155        5775 :                 ret = _gnutls13_compute_finished(session->security_parameters.prf,
     156             :                                 base_key,
     157             :                                 &session->internals.handshake_hash_buffer,
     158             :                                 verifier);
     159        5775 :                 if (ret < 0) {
     160           0 :                         gnutls_assert();
     161           0 :                         goto cleanup;
     162             :                 }
     163             : 
     164        5775 :                 _gnutls_handshake_log("HSK[%p]: sending finished\n", session);
     165             : 
     166        5775 :                 bufel = _gnutls_handshake_alloc(session, hash_size);
     167        5775 :                 if (bufel == NULL)
     168           0 :                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     169             : 
     170        5775 :                 _mbuffer_set_udata_size(bufel, 0);
     171        5775 :                 ret = _mbuffer_append_data(bufel, verifier, hash_size);
     172        5775 :                 if (ret < 0) {
     173           0 :                         gnutls_assert();
     174           0 :                         goto cleanup;
     175             :                 }
     176             :         }
     177             : 
     178        5809 :         return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_FINISHED);
     179             : 
     180           0 : cleanup:
     181           0 :         _mbuffer_xfree(&bufel);
     182             :         return ret;
     183             : }

Generated by: LCOV version 1.14