LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib - constate.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 515 562 91.6 %
Date: 2020-10-30 04:50:48 Functions: 23 23 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2001-2012 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2017 Red Hat, Inc.
       4             :  *
       5             :  * Author: Nikos Mavrogiannopoulos
       6             :  *
       7             :  * This file is part of GnuTLS.
       8             :  *
       9             :  * The GnuTLS is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public License
      11             :  * as published by the Free Software Foundation; either version 2.1 of
      12             :  * the License, or (at your option) any later version.
      13             :  *
      14             :  * This library is distributed in the hope that it will be useful, but
      15             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public License
      20             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      21             :  *
      22             :  */
      23             : 
      24             : /* Functions that are supposed to run after the handshake procedure is
      25             :  * finished. These functions activate the established security parameters.
      26             :  */
      27             : 
      28             : #include "gnutls_int.h"
      29             : #include <constate.h>
      30             : #include "errors.h"
      31             : #include <kx.h>
      32             : #include <algorithms.h>
      33             : #include <num.h>
      34             : #include <datum.h>
      35             : #include <state.h>
      36             : #include <hello_ext.h>
      37             : #include <buffers.h>
      38             : #include "dtls.h"
      39             : #include "secrets.h"
      40             : #include "handshake.h"
      41             : #include "crypto-api.h"
      42             : #include "locks.h"
      43             : 
      44             : static const char keyexp[] = "key expansion";
      45             : static const int keyexp_length = sizeof(keyexp) - 1;
      46             : 
      47             : static int
      48             : _tls13_init_record_state(gnutls_cipher_algorithm_t algo, record_state_st *state);
      49             : 
      50             : /* This function is to be called after handshake, when master_secret,
      51             :  *  client_random and server_random have been initialized. 
      52             :  * This function creates the keys and stores them into pending session.
      53             :  * (session->cipher_specs)
      54             :  */
      55             : static int
      56        9414 : _gnutls_set_keys(gnutls_session_t session, record_parameters_st * params,
      57             :                  unsigned hash_size, unsigned IV_size, unsigned key_size)
      58             : {
      59        9414 :         uint8_t rnd[2 * GNUTLS_RANDOM_SIZE];
      60        9414 :         int pos, ret;
      61        9414 :         int block_size;
      62        9414 :         char buf[4 * MAX_HASH_SIZE + 4 * MAX_CIPHER_KEY_SIZE +
      63             :                  4 * MAX_CIPHER_BLOCK_SIZE];
      64             :         /* avoid using malloc */
      65        9414 :         uint8_t key_block[2 * MAX_HASH_SIZE + 2 * MAX_CIPHER_KEY_SIZE +
      66             :                           2 * MAX_CIPHER_BLOCK_SIZE];
      67        9414 :         record_state_st *client_write, *server_write;
      68             : 
      69        9414 :         if (session->security_parameters.entity == GNUTLS_CLIENT) {
      70        1584 :                 client_write = &params->write;
      71        1584 :                 server_write = &params->read;
      72             :         } else {
      73        7830 :                 client_write = &params->read;
      74        7830 :                 server_write = &params->write;
      75             :         }
      76             : 
      77        9414 :         block_size = 2 * hash_size + 2 * key_size;
      78        9414 :         block_size += 2 * IV_size;
      79             : 
      80        9414 :         memcpy(rnd, session->security_parameters.server_random,
      81             :                GNUTLS_RANDOM_SIZE);
      82        9414 :         memcpy(&rnd[GNUTLS_RANDOM_SIZE],
      83        9414 :                session->security_parameters.client_random,
      84             :                GNUTLS_RANDOM_SIZE);
      85             : 
      86             : #ifdef ENABLE_SSL3
      87             :         if (get_num_version(session) == GNUTLS_SSL3) {  /* SSL 3 */
      88             :                 ret =
      89             :                     _gnutls_ssl3_generate_random
      90             :                     (session->security_parameters.master_secret,
      91             :                      GNUTLS_MASTER_SIZE, rnd, 2 * GNUTLS_RANDOM_SIZE,
      92             :                      block_size, key_block);
      93             :         } else /* TLS 1.0+ */
      94             : #endif
      95        9414 :                 ret =
      96        9414 :                     _gnutls_PRF(session,
      97        9414 :                                 session->security_parameters.master_secret,
      98             :                                 GNUTLS_MASTER_SIZE, keyexp, keyexp_length,
      99             :                                 rnd, 2 * GNUTLS_RANDOM_SIZE, block_size,
     100             :                                 key_block);
     101             : 
     102        9414 :         if (ret < 0)
     103           0 :                 return gnutls_assert_val(ret);
     104             : 
     105        9414 :         _gnutls_hard_log("INT: KEY BLOCK[%d]: %s\n", block_size,
     106             :                          _gnutls_bin2hex(key_block, block_size, buf,
     107             :                                          sizeof(buf), NULL));
     108             : 
     109        9414 :         pos = 0;
     110        9414 :         if (hash_size > 0) {
     111        4577 :                 assert(hash_size<=sizeof(client_write->mac_key));
     112        4577 :                 client_write->mac_key_size = hash_size;
     113        4577 :                 memcpy(client_write->mac_key, &key_block[pos], hash_size);
     114             : 
     115        4577 :                 pos += hash_size;
     116             : 
     117        4577 :                 server_write->mac_key_size = hash_size;
     118        4577 :                 memcpy(server_write->mac_key, &key_block[pos], hash_size);
     119             : 
     120        4577 :                 pos += hash_size;
     121             : 
     122        4577 :                 _gnutls_hard_log("INT: CLIENT MAC KEY [%d]: %s\n",
     123             :                                  key_size,
     124             :                                  _gnutls_bin2hex(client_write->mac_key,
     125             :                                                  hash_size,
     126             :                                                  buf, sizeof(buf), NULL));
     127             : 
     128        4577 :                 _gnutls_hard_log("INT: SERVER MAC KEY [%d]: %s\n",
     129             :                                  key_size,
     130             :                                  _gnutls_bin2hex(server_write->mac_key,
     131             :                                                  hash_size,
     132             :                                                  buf, sizeof(buf), NULL));
     133             :         }
     134             : 
     135        9414 :         if (key_size > 0) {
     136        9374 :                 assert(key_size <=sizeof(client_write->key));
     137        9374 :                 client_write->key_size = key_size;
     138        9374 :                 memcpy(client_write->key, &key_block[pos], key_size);
     139             : 
     140        9374 :                 pos += key_size;
     141             : 
     142        9374 :                 server_write->key_size = key_size;
     143        9374 :                 memcpy(server_write->key, &key_block[pos], key_size);
     144             : 
     145        9374 :                 pos += key_size;
     146             : 
     147        9374 :                 _gnutls_hard_log("INT: CLIENT WRITE KEY [%d]: %s\n",
     148             :                                  key_size,
     149             :                                  _gnutls_bin2hex(client_write->key,
     150             :                                                  key_size,
     151             :                                                  buf, sizeof(buf), NULL));
     152             : 
     153        9374 :                 _gnutls_hard_log("INT: SERVER WRITE KEY [%d]: %s\n",
     154             :                                  key_size,
     155             :                                  _gnutls_bin2hex(server_write->key,
     156             :                                                  key_size,
     157             :                                                  buf, sizeof(buf), NULL));
     158             : 
     159             :         }
     160             : 
     161             :         /* IV generation in export and non export ciphers.
     162             :          */
     163        9414 :         if (IV_size > 0) {
     164        9296 :                 assert(IV_size <= sizeof(client_write->iv));
     165             : 
     166        9296 :                 client_write->iv_size = IV_size;
     167        9296 :                 memcpy(client_write->iv, &key_block[pos], IV_size);
     168             : 
     169        9296 :                 pos += IV_size;
     170             : 
     171        9296 :                 server_write->iv_size = IV_size;
     172        9296 :                 memcpy(server_write->iv, &key_block[pos], IV_size);
     173             : 
     174        9296 :                 _gnutls_hard_log("INT: CLIENT WRITE IV [%d]: %s\n",
     175             :                                  client_write->iv_size,
     176             :                                  _gnutls_bin2hex(client_write->iv,
     177             :                                                  client_write->iv_size,
     178             :                                                  buf, sizeof(buf), NULL));
     179             : 
     180        9296 :                 _gnutls_hard_log("INT: SERVER WRITE IV [%d]: %s\n",
     181             :                                  server_write->iv_size,
     182             :                                  _gnutls_bin2hex(server_write->iv,
     183             :                                                  server_write->iv_size,
     184             :                                                  buf, sizeof(buf), NULL));
     185             :         }
     186             : 
     187             :         return 0;
     188             : }
     189             : 
     190             : static int
     191          97 : _tls13_update_keys(gnutls_session_t session, hs_stage_t stage,
     192             :                    record_parameters_st *params,
     193             :                    unsigned iv_size, unsigned key_size)
     194             : {
     195          97 :         uint8_t key_block[MAX_CIPHER_KEY_SIZE];
     196          97 :         uint8_t iv_block[MAX_CIPHER_IV_SIZE];
     197          97 :         char buf[65];
     198          97 :         record_state_st *upd_state;
     199          97 :         record_parameters_st *prev = NULL;
     200          97 :         int ret;
     201             : 
     202             :         /* generate new keys for direction needed and copy old from previous epoch */
     203             : 
     204          97 :         if (stage == STAGE_UPD_OURS) {
     205          51 :                 upd_state = &params->write;
     206             : 
     207          51 :                 ret = _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &prev);
     208          51 :                 if (ret < 0)
     209           0 :                         return gnutls_assert_val(ret);
     210          51 :                 assert(prev != NULL);
     211             : 
     212          51 :                 params->read.sequence_number = prev->read.sequence_number;
     213             : 
     214          51 :                 params->read.key_size = prev->read.key_size;
     215          51 :                 memcpy(params->read.key, prev->read.key, prev->read.key_size);
     216             : 
     217          51 :                 _gnutls_hard_log("INT: READ KEY [%d]: %s\n",
     218             :                                  params->read.key_size,
     219             :                                  _gnutls_bin2hex(params->read.key, params->read.key_size,
     220             :                                                  buf, sizeof(buf), NULL));
     221             : 
     222          51 :                 params->read.iv_size = prev->read.iv_size;
     223          51 :                 memcpy(params->read.iv, prev->read.iv, prev->read.key_size);
     224             : 
     225          51 :                 _gnutls_hard_log("INT: READ IV [%d]: %s\n",
     226             :                                  params->read.iv_size,
     227             :                                  _gnutls_bin2hex(params->read.iv, params->read.iv_size,
     228             :                                                  buf, sizeof(buf), NULL));
     229             :         } else {
     230          46 :                 upd_state = &params->read;
     231             : 
     232          46 :                 ret = _gnutls_epoch_get(session, EPOCH_WRITE_CURRENT, &prev);
     233          46 :                 if (ret < 0)
     234           0 :                         return gnutls_assert_val(ret);
     235          46 :                 assert(prev != NULL);
     236             : 
     237          46 :                 params->write.sequence_number = prev->write.sequence_number;
     238             : 
     239          46 :                 params->write.key_size = prev->write.key_size;
     240          46 :                 memcpy(params->write.key, prev->write.key, prev->write.key_size);
     241             : 
     242          46 :                 _gnutls_hard_log("INT: WRITE KEY [%d]: %s\n",
     243             :                                  params->write.key_size,
     244             :                                  _gnutls_bin2hex(params->write.key, params->write.key_size,
     245             :                                                  buf, sizeof(buf), NULL));
     246             : 
     247          46 :                 params->write.iv_size = prev->write.iv_size;
     248          46 :                 memcpy(params->write.iv, prev->write.iv, prev->write.iv_size);
     249             : 
     250          46 :                 _gnutls_hard_log("INT: WRITE IV [%d]: %s\n",
     251             :                                  params->write.iv_size,
     252             :                                  _gnutls_bin2hex(params->write.iv, params->write.iv_size,
     253             :                                                  buf, sizeof(buf), NULL));
     254             :         }
     255             : 
     256             : 
     257          97 :         if ((session->security_parameters.entity == GNUTLS_CLIENT && stage == STAGE_UPD_OURS) ||
     258          50 :             (session->security_parameters.entity == GNUTLS_SERVER && stage == STAGE_UPD_PEERS)) {
     259             : 
     260             :                 /* client keys */
     261         118 :                 ret = _tls13_expand_secret(session, APPLICATION_TRAFFIC_UPDATE,
     262             :                                            sizeof(APPLICATION_TRAFFIC_UPDATE)-1,
     263             :                                            NULL, 0,
     264             :                                            session->key.proto.tls13.ap_ckey,
     265          59 :                                            session->security_parameters.prf->output_size,
     266          59 :                                            session->key.proto.tls13.ap_ckey);
     267          59 :                 if (ret < 0)
     268           0 :                         return gnutls_assert_val(ret);
     269             : 
     270          59 :                 ret = _tls13_expand_secret(session, "key", 3, NULL, 0, session->key.proto.tls13.ap_ckey, key_size, key_block);
     271          59 :                 if (ret < 0)
     272           0 :                         return gnutls_assert_val(ret);
     273             : 
     274          59 :                 ret = _tls13_expand_secret(session, "iv", 2, NULL, 0, session->key.proto.tls13.ap_ckey, iv_size, iv_block);
     275          59 :                 if (ret < 0)
     276           0 :                         return gnutls_assert_val(ret);
     277             :         } else {
     278          76 :                 ret = _tls13_expand_secret(session, APPLICATION_TRAFFIC_UPDATE,
     279             :                                            sizeof(APPLICATION_TRAFFIC_UPDATE)-1,
     280             :                                            NULL, 0,
     281             :                                            session->key.proto.tls13.ap_skey,
     282          38 :                                            session->security_parameters.prf->output_size,
     283          38 :                                            session->key.proto.tls13.ap_skey);
     284          38 :                 if (ret < 0)
     285           0 :                         return gnutls_assert_val(ret);
     286             : 
     287          38 :                 ret = _tls13_expand_secret(session, "key", 3, NULL, 0, session->key.proto.tls13.ap_skey, key_size, key_block);
     288          38 :                 if (ret < 0)
     289           0 :                         return gnutls_assert_val(ret);
     290             : 
     291          38 :                 ret = _tls13_expand_secret(session, "iv", 2, NULL, 0, session->key.proto.tls13.ap_skey, iv_size, iv_block);
     292          38 :                 if (ret < 0)
     293           0 :                         return gnutls_assert_val(ret);
     294             :         }
     295             : 
     296          97 :         upd_state->mac_key_size = 0;
     297             : 
     298          97 :         assert(key_size <= sizeof(upd_state->key));
     299          97 :         memcpy(upd_state->key, key_block, key_size);
     300          97 :         upd_state->key_size = key_size;
     301             : 
     302          97 :         _gnutls_hard_log("INT: NEW %s KEY [%d]: %s\n",
     303             :                          (upd_state == &params->read)?"READ":"WRITE",
     304             :                          key_size,
     305             :                          _gnutls_bin2hex(key_block, key_size,
     306             :                                          buf, sizeof(buf), NULL));
     307             : 
     308          97 :         if (iv_size > 0) {
     309          97 :                 assert(iv_size <= sizeof(upd_state->iv));
     310          97 :                 memcpy(upd_state->iv, iv_block, iv_size);
     311          97 :                 upd_state->iv_size = iv_size;
     312             : 
     313          97 :                 _gnutls_hard_log("INT: NEW %s IV [%d]: %s\n",
     314             :                                  (upd_state == &params->read)?"READ":"WRITE",
     315             :                                  iv_size,
     316             :                                  _gnutls_bin2hex(iv_block, iv_size,
     317             :                                                  buf, sizeof(buf), NULL));
     318             :         }
     319             : 
     320             :         return 0;
     321             : }
     322             : 
     323             : static int
     324           8 : _tls13_set_early_keys(gnutls_session_t session,
     325             :                       record_parameters_st * params,
     326             :                       unsigned iv_size, unsigned key_size)
     327             : {
     328           8 :         uint8_t key_block[MAX_CIPHER_KEY_SIZE];
     329           8 :         uint8_t iv_block[MAX_CIPHER_IV_SIZE];
     330           8 :         char buf[65];
     331           8 :         record_state_st *early_state;
     332           8 :         int ret;
     333             : 
     334           8 :         if (session->security_parameters.entity == GNUTLS_CLIENT &&
     335           3 :             !(session->internals.hsk_flags & HSK_TLS13_TICKET_SENT)) {
     336             :                 return GNUTLS_E_INVALID_REQUEST;
     337             :         }
     338             : 
     339           8 :         ret = _tls13_expand_secret(session, "key", 3, NULL, 0, session->key.proto.tls13.e_ckey, key_size, key_block);
     340           8 :         if (ret < 0)
     341           0 :                 return gnutls_assert_val(ret);
     342             : 
     343           8 :         ret = _tls13_expand_secret(session, "iv", 2, NULL, 0, session->key.proto.tls13.e_ckey, iv_size, iv_block);
     344           8 :         if (ret < 0)
     345           0 :                 return gnutls_assert_val(ret);
     346             : 
     347           8 :         if (session->security_parameters.entity == GNUTLS_CLIENT) {
     348           3 :                 early_state = &params->write;
     349             :         } else {
     350           5 :                 early_state = &params->read;
     351             :         }
     352             : 
     353           8 :         early_state->mac_key_size = 0;
     354             : 
     355           8 :         assert(key_size <= sizeof(early_state->key));
     356           8 :         memcpy(early_state->key, key_block, key_size);
     357           8 :         early_state->key_size = key_size;
     358             : 
     359           8 :         _gnutls_hard_log("INT: EARLY KEY [%d]: %s\n",
     360             :                          key_size,
     361             :                          _gnutls_bin2hex(key_block, key_size,
     362             :                                          buf, sizeof(buf), NULL));
     363             : 
     364           8 :         if (iv_size > 0) {
     365           8 :                 assert(iv_size <= sizeof(early_state->iv));
     366           8 :                 memcpy(early_state->iv, iv_block, iv_size);
     367           8 :                 early_state->iv_size = iv_size;
     368             : 
     369           8 :                 _gnutls_hard_log("INT: EARLY IV [%d]: %s\n",
     370             :                                  iv_size,
     371             :                                  _gnutls_bin2hex(iv_block, iv_size,
     372             :                                                  buf, sizeof(buf), NULL));
     373             :         }
     374             : 
     375             :         return 0;
     376             : }
     377             : 
     378             : static int
     379       11462 : _tls13_set_keys(gnutls_session_t session, hs_stage_t stage,
     380             :                 record_parameters_st * params,
     381             :                 unsigned iv_size, unsigned key_size)
     382             : {
     383       11462 :         uint8_t ckey_block[MAX_CIPHER_KEY_SIZE];
     384       11462 :         uint8_t civ_block[MAX_CIPHER_IV_SIZE];
     385       11462 :         uint8_t skey_block[MAX_CIPHER_KEY_SIZE];
     386       11462 :         uint8_t siv_block[MAX_CIPHER_IV_SIZE];
     387       11462 :         char buf[65];
     388       11462 :         record_state_st *client_write, *server_write;
     389       11462 :         const char *label;
     390       11462 :         unsigned label_size, hsk_len;
     391       11462 :         const char *keylog_label;
     392       11462 :         void *ckey, *skey;
     393       11462 :         int ret;
     394             : 
     395       11462 :         if (stage == STAGE_UPD_OURS || stage == STAGE_UPD_PEERS)
     396          97 :                 return _tls13_update_keys(session, stage,
     397             :                                           params, iv_size, key_size);
     398             : 
     399       11365 :         else if (stage == STAGE_EARLY)
     400           8 :                 return _tls13_set_early_keys(session,
     401             :                                              params, iv_size, key_size);
     402             : 
     403       11357 :         else if (stage == STAGE_HS) {
     404        5699 :                 label = HANDSHAKE_CLIENT_TRAFFIC_LABEL;
     405        5699 :                 label_size = sizeof(HANDSHAKE_CLIENT_TRAFFIC_LABEL)-1;
     406        5699 :                 hsk_len = session->internals.handshake_hash_buffer.length;
     407        5699 :                 keylog_label = "CLIENT_HANDSHAKE_TRAFFIC_SECRET";
     408        5699 :                 ckey = session->key.proto.tls13.hs_ckey;
     409             :         } else {
     410        5658 :                 label = APPLICATION_CLIENT_TRAFFIC_LABEL;
     411        5658 :                 label_size = sizeof(APPLICATION_CLIENT_TRAFFIC_LABEL)-1;
     412        5658 :                 hsk_len = session->internals.handshake_hash_buffer_server_finished_len;
     413        5658 :                 keylog_label = "CLIENT_TRAFFIC_SECRET_0";
     414        5658 :                 ckey = session->key.proto.tls13.ap_ckey;
     415             :         }
     416             : 
     417       22714 :         ret = _tls13_derive_secret(session, label, label_size,
     418       11357 :                                    session->internals.handshake_hash_buffer.data,
     419             :                                    hsk_len,
     420       11357 :                                    session->key.proto.tls13.temp_secret,
     421             :                                    ckey);
     422       11357 :         if (ret < 0)
     423           0 :                 return gnutls_assert_val(ret);
     424             : 
     425       22714 :         ret = _gnutls_call_keylog_func(session, keylog_label,
     426             :                                        ckey,
     427       11357 :                                        session->security_parameters.prf->output_size);
     428       11357 :         if (ret < 0)
     429           0 :                 return gnutls_assert_val(ret);
     430             : 
     431             :         /* client keys */
     432       11357 :         ret = _tls13_expand_secret(session, "key", 3, NULL, 0, ckey, key_size, ckey_block);
     433       11357 :         if (ret < 0)
     434           0 :                 return gnutls_assert_val(ret);
     435             : 
     436       11357 :         ret = _tls13_expand_secret(session, "iv", 2, NULL, 0, ckey, iv_size, civ_block);
     437       11357 :         if (ret < 0)
     438           0 :                 return gnutls_assert_val(ret);
     439             : 
     440             :         /* server keys */
     441       11357 :         if (stage == STAGE_HS) {
     442        5699 :                 label = HANDSHAKE_SERVER_TRAFFIC_LABEL;
     443        5699 :                 label_size = sizeof(HANDSHAKE_SERVER_TRAFFIC_LABEL)-1;
     444        5699 :                 keylog_label = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
     445        5699 :                 skey = session->key.proto.tls13.hs_skey;
     446             :         } else {
     447        5658 :                 label = APPLICATION_SERVER_TRAFFIC_LABEL;
     448        5658 :                 label_size = sizeof(APPLICATION_SERVER_TRAFFIC_LABEL)-1;
     449        5658 :                 keylog_label = "SERVER_TRAFFIC_SECRET_0";
     450        5658 :                 skey = session->key.proto.tls13.ap_skey;
     451             :         }
     452             : 
     453       22714 :         ret = _tls13_derive_secret(session, label, label_size,
     454       11357 :                                    session->internals.handshake_hash_buffer.data,
     455             :                                    hsk_len,
     456             :                                    session->key.proto.tls13.temp_secret,
     457             :                                    skey);
     458             : 
     459       11357 :         if (ret < 0)
     460           0 :                 return gnutls_assert_val(ret);
     461             : 
     462       22714 :         ret = _gnutls_call_keylog_func(session, keylog_label,
     463             :                                        skey,
     464       11357 :                                        session->security_parameters.prf->output_size);
     465       11357 :         if (ret < 0)
     466           0 :                 return gnutls_assert_val(ret);
     467             : 
     468       11357 :         ret = _tls13_expand_secret(session, "key", 3, NULL, 0, skey, key_size, skey_block);
     469       11357 :         if (ret < 0)
     470           0 :                 return gnutls_assert_val(ret);
     471             : 
     472       11357 :         ret = _tls13_expand_secret(session, "iv", 2, NULL, 0, skey, iv_size, siv_block);
     473       11357 :         if (ret < 0)
     474           0 :                 return gnutls_assert_val(ret);
     475             : 
     476       11357 :         if (session->security_parameters.entity == GNUTLS_CLIENT) {
     477        1167 :                 client_write = &params->write;
     478        1167 :                 server_write = &params->read;
     479             :         } else {
     480       10190 :                 client_write = &params->read;
     481       10190 :                 server_write = &params->write;
     482             :         }
     483             : 
     484       11357 :         client_write->mac_key_size = 0;
     485       11357 :         server_write->mac_key_size = 0;
     486             : 
     487       11357 :         assert(key_size <= sizeof(client_write->key));
     488       11357 :         memcpy(client_write->key, ckey_block, key_size);
     489       11357 :         client_write->key_size = key_size;
     490             : 
     491       11357 :         _gnutls_hard_log("INT: CLIENT WRITE KEY [%d]: %s\n",
     492             :                          key_size,
     493             :                          _gnutls_bin2hex(ckey_block, key_size,
     494             :                                          buf, sizeof(buf), NULL));
     495             : 
     496       11357 :         memcpy(server_write->key, skey_block, key_size);
     497       11357 :         server_write->key_size = key_size;
     498             : 
     499       11357 :         _gnutls_hard_log("INT: SERVER WRITE KEY [%d]: %s\n",
     500             :                          key_size,
     501             :                          _gnutls_bin2hex(skey_block, key_size,
     502             :                                          buf, sizeof(buf), NULL));
     503             : 
     504       11357 :         if (iv_size > 0) {
     505       11357 :                 assert(iv_size <= sizeof(client_write->iv));
     506       11357 :                 memcpy(client_write->iv, civ_block, iv_size);
     507       11357 :                 client_write->iv_size = iv_size;
     508             : 
     509       11357 :                 _gnutls_hard_log("INT: CLIENT WRITE IV [%d]: %s\n",
     510             :                                  iv_size,
     511             :                                  _gnutls_bin2hex(civ_block, iv_size,
     512             :                                                  buf, sizeof(buf), NULL));
     513             : 
     514       11357 :                 memcpy(server_write->iv, siv_block, iv_size);
     515       11357 :                 server_write->iv_size = iv_size;
     516             : 
     517       11357 :                 _gnutls_hard_log("INT: SERVER WRITE IV [%d]: %s\n",
     518             :                                  iv_size,
     519             :                                  _gnutls_bin2hex(siv_block, iv_size,
     520             :                                                  buf, sizeof(buf), NULL));
     521             :         }
     522             : 
     523             :         return 0;
     524             : }
     525             : 
     526             : static int
     527       18828 : _gnutls_init_record_state(record_parameters_st * params,
     528             :                           const version_entry_st * ver, int read,
     529             :                           record_state_st * state)
     530             : {
     531       18828 :         int ret;
     532       18828 :         gnutls_datum_t *iv = NULL, _iv;
     533       18828 :         gnutls_datum_t key;
     534       18828 :         gnutls_datum_t mac;
     535             : 
     536       18828 :         _iv.data = state->iv;
     537       18828 :         _iv.size = state->iv_size;
     538             : 
     539       18828 :         key.data = state->key;
     540       18828 :         key.size = state->key_size;
     541             : 
     542       18828 :         mac.data = state->mac_key;
     543       18828 :         mac.size = state->mac_key_size;
     544             : 
     545       18828 :         if (_gnutls_cipher_type(params->cipher) == CIPHER_BLOCK) {
     546        8766 :                 if (!_gnutls_version_has_explicit_iv(ver))
     547        1254 :                         iv = &_iv;
     548       10062 :         } else if (_gnutls_cipher_type(params->cipher) == CIPHER_STREAM) {
     549             :                 /* To handle GOST ciphersuites */
     550         388 :                 if (_gnutls_cipher_get_implicit_iv_size(params->cipher))
     551         152 :                         iv = &_iv;
     552             :         }
     553             : 
     554       37656 :         ret = _gnutls_auth_cipher_init(&state->ctx.tls12,
     555             :                                        params->cipher, &key, iv,
     556             :                                        params->mac, &mac,
     557       18828 :                                        params->etm,
     558             : #ifdef ENABLE_SSL3
     559             :                                        (ver->id == GNUTLS_SSL3) ? 1 : 0,
     560             : #endif
     561             :                                        1 - read /*1==encrypt */ );
     562       18828 :         if (ret < 0 && params->cipher->id != GNUTLS_CIPHER_NULL)
     563           0 :                 return gnutls_assert_val(ret);
     564             : 
     565             :         return 0;
     566             : }
     567             : 
     568             : int
     569       19283 : _gnutls_set_cipher_suite2(gnutls_session_t session,
     570             :                           const gnutls_cipher_suite_entry_st *cs)
     571             : {
     572       19283 :         const cipher_entry_st *cipher_algo;
     573       19283 :         const mac_entry_st *mac_algo;
     574       19283 :         record_parameters_st *params;
     575       19283 :         int ret;
     576       19283 :         const version_entry_st *ver = get_version(session);
     577             : 
     578       19283 :         ret = _gnutls_epoch_get(session, EPOCH_NEXT, &params);
     579       19283 :         if (ret < 0)
     580           0 :                 return gnutls_assert_val(ret);
     581             : 
     582       19283 :         cipher_algo = cipher_to_entry(cs->block_algorithm);
     583       19283 :         mac_algo = mac_to_entry(cs->mac_algorithm);
     584             : 
     585       19283 :         if (ver->tls13_sem && (session->internals.hsk_flags & HSK_HRR_SENT)) {
     586          63 :                 if (params->initialized && (params->cipher != cipher_algo ||
     587           0 :                     params->mac != mac_algo || cs != session->security_parameters.cs))
     588           0 :                         return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
     589             : 
     590             :                 return 0;
     591             :         } else {
     592       19220 :                 if (params->initialized
     593       19220 :                     || params->cipher != NULL || params->mac != NULL)
     594           1 :                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     595             :         }
     596             : 
     597       38438 :         if (_gnutls_cipher_is_ok(cipher_algo) == 0
     598       19219 :             || _gnutls_mac_is_ok(mac_algo) == 0)
     599           0 :                 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
     600             : 
     601       19219 :         if (_gnutls_version_has_selectable_prf(get_version(session))) {
     602       16885 :                 if (cs->prf == GNUTLS_MAC_UNKNOWN ||
     603       16885 :                     _gnutls_mac_is_ok(mac_to_entry(cs->prf)) == 0)
     604           0 :                         return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
     605       16885 :                 session->security_parameters.prf = mac_to_entry(cs->prf);
     606             :         } else {
     607        2334 :                 session->security_parameters.prf = mac_to_entry(GNUTLS_MAC_MD5_SHA1);
     608             :         }
     609             : 
     610       19219 :         session->security_parameters.cs = cs;
     611       19219 :         params->cipher = cipher_algo;
     612       19219 :         params->mac = mac_algo;
     613             : 
     614       19219 :         return 0;
     615             : }
     616             : 
     617             : /* Sets the next epoch to be a clone of the current one.
     618             :  * The keys are not cloned, only the cipher and MAC.
     619             :  */
     620        5763 : int _gnutls_epoch_dup(gnutls_session_t session, unsigned int epoch_rel)
     621             : {
     622        5763 :         record_parameters_st *prev;
     623        5763 :         record_parameters_st *next;
     624        5763 :         int ret;
     625             : 
     626        5763 :         ret = _gnutls_epoch_get(session, epoch_rel, &prev);
     627        5763 :         if (ret < 0)
     628           0 :                 return gnutls_assert_val(ret);
     629             : 
     630        5763 :         ret = _gnutls_epoch_get(session, EPOCH_NEXT, &next);
     631        5763 :         if (ret < 0) {
     632        5763 :                 ret = _gnutls_epoch_setup_next(session, 0, &next);
     633        5763 :                 if (ret < 0)
     634           0 :                         return gnutls_assert_val(ret);
     635             :         }
     636             : 
     637        5763 :         if (next->initialized
     638        5763 :             || next->cipher != NULL || next->mac != NULL)
     639           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     640             : 
     641        5763 :         next->cipher = prev->cipher;
     642        5763 :         next->mac = prev->mac;
     643             : 
     644        5763 :         return 0;
     645             : }
     646             : 
     647       35529 : int _gnutls_epoch_set_keys(gnutls_session_t session, uint16_t epoch, hs_stage_t stage)
     648             : {
     649       35529 :         int hash_size;
     650       35529 :         int IV_size;
     651       35529 :         int key_size;
     652       35529 :         record_parameters_st *params;
     653       35529 :         int ret;
     654       35529 :         const version_entry_st *ver = get_version(session);
     655             : 
     656       35529 :         if (unlikely(ver == NULL))
     657           0 :                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     658             : 
     659       35529 :         ret = _gnutls_epoch_get(session, epoch, &params);
     660       35529 :         if (ret < 0)
     661           0 :                 return gnutls_assert_val(ret);
     662             : 
     663       35529 :         if (params->initialized)
     664             :                 return 0;
     665             : 
     666       20876 :         _gnutls_record_log
     667             :             ("REC[%p]: Initializing epoch #%u\n", session, params->epoch);
     668             : 
     669       20876 :         if (_gnutls_cipher_is_ok(params->cipher) == 0 ||
     670       20876 :             _gnutls_mac_is_ok(params->mac) == 0)
     671           0 :                 return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM);
     672             : 
     673       20876 :         if (_gnutls_version_has_explicit_iv(ver) &&
     674        8693 :             (_gnutls_cipher_type(params->cipher) != CIPHER_BLOCK)) {
     675        4937 :                 IV_size = _gnutls_cipher_get_implicit_iv_size(params->cipher);
     676             :         } else {
     677       15939 :                 IV_size = _gnutls_cipher_get_iv_size(params->cipher);
     678             :         }
     679             : 
     680       20876 :         key_size = _gnutls_cipher_get_key_size(params->cipher);
     681       20876 :         hash_size = _gnutls_mac_get_key_size(params->mac);
     682       20876 :         params->etm = session->security_parameters.etm;
     683             : 
     684       20876 :         if (ver->tls13_sem) {
     685       11462 :                 ret = _tls13_set_keys
     686             :                     (session, stage, params, IV_size, key_size);
     687       11462 :                 if (ret < 0)
     688           0 :                         return gnutls_assert_val(ret);
     689             : 
     690       11462 :                 if (stage != STAGE_EARLY ||
     691           8 :                     session->security_parameters.entity == GNUTLS_SERVER) {
     692       11459 :                         ret = _tls13_init_record_state(params->cipher->id, &params->read);
     693       11459 :                         if (ret < 0)
     694           0 :                                 return gnutls_assert_val(ret);
     695             :                 }
     696             : 
     697       11462 :                 if (stage != STAGE_EARLY ||
     698           8 :                     session->security_parameters.entity == GNUTLS_CLIENT) {
     699       11457 :                         ret = _tls13_init_record_state(params->cipher->id, &params->write);
     700       11457 :                         if (ret < 0)
     701           0 :                                 return gnutls_assert_val(ret);
     702             :                 }
     703             :         } else {
     704        9414 :                 ret = _gnutls_set_keys
     705             :                     (session, params, hash_size, IV_size, key_size);
     706        9414 :                 if (ret < 0)
     707           0 :                         return gnutls_assert_val(ret);
     708             : 
     709        9414 :                 ret = _gnutls_init_record_state(params, ver, 1, &params->read);
     710        9414 :                 if (ret < 0)
     711           0 :                         return gnutls_assert_val(ret);
     712             : 
     713        9414 :                 ret = _gnutls_init_record_state(params, ver, 0, &params->write);
     714        9414 :                 if (ret < 0)
     715           0 :                         return gnutls_assert_val(ret);
     716             :         }
     717             : 
     718             :         /* The TLS1.3 limit of 256 additional bytes is also enforced under CBC
     719             :          * ciphers to ensure we interoperate with gnutls 2.12.x which could add padding
     720             :          * data exceeding the maximum. */
     721       20876 :         if (ver->tls13_sem || _gnutls_cipher_type(params->cipher) == CIPHER_BLOCK) {
     722       15845 :                 session->internals.max_recv_size = 256;
     723             :         } else {
     724        5031 :                 session->internals.max_recv_size = 0;
     725             :         }
     726             : 
     727       20876 :         if (!ver->tls13_sem) {
     728        9414 :                 session->internals.max_recv_size += _gnutls_record_overhead(ver, params->cipher, params->mac, 1);
     729        9414 :                 if (session->internals.allow_large_records != 0)
     730          91 :                         session->internals.max_recv_size += EXTRA_COMP_SIZE;
     731             :         }
     732             : 
     733       20876 :         session->internals.max_recv_size += session->security_parameters.max_record_recv_size + RECORD_HEADER_SIZE(session);
     734             : 
     735       20876 :         _dtls_reset_window(params);
     736             : 
     737       20876 :         _gnutls_record_log("REC[%p]: Epoch #%u ready\n", session,
     738             :                            params->epoch);
     739             : 
     740       20876 :         params->initialized = 1;
     741       20876 :         return 0;
     742             : }
     743             : 
     744             : /* This copies the session values which apply to subsequent/resumed
     745             :  * sessions. Under TLS 1.3, these values are items which are not
     746             :  * negotiated on the subsequent session. */
     747             : #define CPY_COMMON(tls13_sem) \
     748             :         if (!tls13_sem) { \
     749             :                 dst->cs = src->cs; \
     750             :                 memcpy(dst->master_secret, src->master_secret, GNUTLS_MASTER_SIZE); \
     751             :                 memcpy(dst->client_random, src->client_random, GNUTLS_RANDOM_SIZE); \
     752             :                 memcpy(dst->server_random, src->server_random, GNUTLS_RANDOM_SIZE); \
     753             :                 dst->ext_master_secret = src->ext_master_secret; \
     754             :                 dst->etm = src->etm; \
     755             :                 dst->prf = src->prf; \
     756             :                 dst->grp = src->grp; \
     757             :                 dst->pversion = src->pversion; \
     758             :         } \
     759             :         memcpy(dst->session_id, src->session_id, GNUTLS_MAX_SESSION_ID_SIZE); \
     760             :         dst->session_id_size = src->session_id_size; \
     761             :         dst->timestamp = src->timestamp; \
     762             :         dst->client_ctype = src->client_ctype; \
     763             :         dst->server_ctype = src->server_ctype; \
     764             :         dst->client_auth_type = src->client_auth_type; \
     765             :         dst->server_auth_type = src->server_auth_type
     766             : 
     767        1121 : void _gnutls_set_resumed_parameters(gnutls_session_t session)
     768             : {
     769        1121 :         security_parameters_st *src =
     770             :             &session->internals.resumed_security_parameters;
     771        1121 :         security_parameters_st *dst = &session->security_parameters;
     772        1121 :         const version_entry_st *ver = get_version(session);
     773             : 
     774        1121 :         CPY_COMMON(ver->tls13_sem);
     775             : 
     776        1121 :         if (!ver->tls13_sem &&
     777         897 :             !(session->internals.hsk_flags & HSK_RECORD_SIZE_LIMIT_NEGOTIATED)) {
     778          37 :                 dst->max_record_recv_size = src->max_record_recv_size;
     779          37 :                 dst->max_record_send_size = src->max_record_send_size;
     780             :         }
     781        1121 : }
     782             : 
     783             : /* Sets the current connection session to conform with the
     784             :  * Security parameters(pending session), and initializes encryption.
     785             :  * Actually it initializes and starts encryption ( so it needs
     786             :  * secrets and random numbers to have been negotiated)
     787             :  * This is to be called after sending the Change Cipher Spec packet.
     788             :  */
     789        9414 : int _gnutls_connection_state_init(gnutls_session_t session)
     790             : {
     791        9414 :         int ret;
     792             : 
     793             : /* Setup the master secret 
     794             :  */
     795        9414 :         if ((ret = _gnutls_generate_master(session, 0)) < 0)
     796           0 :                 return gnutls_assert_val(ret);
     797             : 
     798             :         return 0;
     799             : }
     800             : 
     801             : /* Initializes the read connection session
     802             :  * (read encrypted data)
     803             :  */
     804        9293 : int _gnutls_read_connection_state_init(gnutls_session_t session)
     805             : {
     806        9293 :         const uint16_t epoch_next =
     807             :             session->security_parameters.epoch_next;
     808        9293 :         int ret;
     809             : 
     810             :         /* Update internals from CipherSuite selected.
     811             :          * If we are resuming just copy the connection session
     812             :          */
     813        9293 :         if (session->internals.resumed != RESUME_FALSE &&
     814         896 :             session->security_parameters.entity == GNUTLS_CLIENT)
     815         114 :                 _gnutls_set_resumed_parameters(session);
     816             : 
     817        9293 :         ret = _gnutls_epoch_set_keys(session, epoch_next, 0);
     818        9293 :         if (ret < 0)
     819             :                 return ret;
     820             : 
     821        9293 :         _gnutls_handshake_log("HSK[%p]: Cipher Suite: %s\n",
     822             :                               session,
     823             :                               session->security_parameters.cs->name);
     824             : 
     825        9293 :         session->security_parameters.epoch_read = epoch_next;
     826             : 
     827        9293 :         return 0;
     828             : }
     829             : 
     830             : /* Initializes the write connection session
     831             :  * (write encrypted data)
     832             :  */
     833        8983 : int _gnutls_write_connection_state_init(gnutls_session_t session)
     834             : {
     835        8983 :         const uint16_t epoch_next =
     836             :             session->security_parameters.epoch_next;
     837        8983 :         int ret;
     838             : 
     839             :         /* reset max_record_send_size if it was negotiated in the
     840             :          * previous handshake using the record_size_limit extension */
     841        8983 :         if (!(session->internals.hsk_flags & HSK_RECORD_SIZE_LIMIT_NEGOTIATED) &&
     842        3356 :             session->security_parameters.entity == GNUTLS_SERVER)
     843        3161 :                 session->security_parameters.max_record_send_size =
     844        3161 :                         session->security_parameters.max_user_record_send_size;
     845             : 
     846             : /* Update internals from CipherSuite selected.
     847             :  * If we are resuming just copy the connection session
     848             :  */
     849        8983 :         if (session->internals.resumed != RESUME_FALSE &&
     850         897 :             session->security_parameters.entity == GNUTLS_SERVER)
     851         783 :                 _gnutls_set_resumed_parameters(session);
     852             : 
     853        8983 :         ret = _gnutls_epoch_set_keys(session, epoch_next, 0);
     854        8983 :         if (ret < 0)
     855           0 :                 return gnutls_assert_val(ret);
     856             : 
     857        8983 :         _gnutls_handshake_log("HSK[%p]: Cipher Suite: %s\n", session,
     858             :                               session->security_parameters.cs->name);
     859             : 
     860        8983 :         _gnutls_handshake_log
     861             :             ("HSK[%p]: Initializing internal [write] cipher sessions\n",
     862             :              session);
     863             : 
     864        8983 :         session->security_parameters.epoch_write = epoch_next;
     865             : 
     866        8983 :         return 0;
     867             : }
     868             : 
     869             : static inline int
     870    53245900 : epoch_resolve(gnutls_session_t session,
     871             :               unsigned int epoch_rel, uint16_t * epoch_out)
     872             : {
     873    53245900 :         switch (epoch_rel) {
     874    23525200 :         case EPOCH_READ_CURRENT:
     875    23525200 :                 *epoch_out = session->security_parameters.epoch_read;
     876    23525200 :                 return 0;
     877             : 
     878    29453200 :         case EPOCH_WRITE_CURRENT:
     879    29453200 :                 *epoch_out = session->security_parameters.epoch_write;
     880    29453200 :                 return 0;
     881             : 
     882       25046 :         case EPOCH_NEXT:
     883       25046 :                 *epoch_out = session->security_parameters.epoch_next;
     884       25046 :                 return 0;
     885             : 
     886      242428 :         default:
     887      242428 :                 if (epoch_rel > 0xffffu)
     888           0 :                         return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     889             : 
     890      242428 :                 *epoch_out = epoch_rel;
     891      242428 :                 return 0;
     892             :         }
     893             : }
     894             : 
     895    53298100 : static inline record_parameters_st **epoch_get_slot(gnutls_session_t
     896             :                                                     session,
     897             :                                                     uint16_t epoch)
     898             : {
     899    53298100 :         uint16_t epoch_index =
     900    53298100 :             epoch - session->security_parameters.epoch_min;
     901             : 
     902    53298100 :         if (epoch_index >= MAX_EPOCH_INDEX) {
     903           7 :                 _gnutls_handshake_log
     904             :                     ("Epoch %d out of range (idx: %d, max: %d)\n",
     905             :                      (int) epoch, (int) epoch_index, MAX_EPOCH_INDEX);
     906           7 :                 gnutls_assert();
     907           7 :                 return NULL;
     908             :         }
     909             :         /* The slot may still be empty (NULL) */
     910    53298100 :         return &session->record_parameters[epoch_index];
     911             : }
     912             : 
     913             : int
     914    53245900 : _gnutls_epoch_get(gnutls_session_t session, unsigned int epoch_rel,
     915             :                   record_parameters_st ** params_out)
     916             : {
     917    53245900 :         uint16_t epoch;
     918    53245900 :         record_parameters_st **params;
     919    53245900 :         int ret;
     920             : 
     921    53245900 :         gnutls_mutex_lock(&session->internals.epoch_lock);
     922             : 
     923    53245900 :         ret = epoch_resolve(session, epoch_rel, &epoch);
     924    53245900 :         if (ret < 0) {
     925           0 :                 gnutls_assert();
     926           0 :                 goto cleanup;
     927             :         }
     928             : 
     929    53245900 :         params = epoch_get_slot(session, epoch);
     930    53245900 :         if (params == NULL || *params == NULL) {
     931        5770 :                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     932        5770 :                 goto cleanup;
     933             :         }
     934             : 
     935    53240100 :         if (params_out)
     936    53226700 :                 *params_out = *params;
     937             : 
     938             :         ret = 0;
     939             : 
     940    53245900 : cleanup:
     941    53245900 :         gnutls_mutex_unlock(&session->internals.epoch_lock);
     942    53245900 :         return ret;
     943             : }
     944             : 
     945             : /* Ensures that the next epoch is setup. When an epoch will null ciphers
     946             :  * is to be setup, call with @null_epoch set to true. In that case
     947             :  * the epoch is fully initialized after call.
     948             :  */
     949             : int
     950       52185 : _gnutls_epoch_setup_next(gnutls_session_t session, unsigned null_epoch, record_parameters_st **newp)
     951             : {
     952       52185 :         record_parameters_st **slot;
     953             : 
     954       52185 :         slot = epoch_get_slot(session, session->security_parameters.epoch_next);
     955             : 
     956             :         /* If slot out of range or not empty. */
     957       52185 :         if (slot == NULL)
     958           0 :                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
     959             : 
     960       52185 :         if (*slot != NULL) { /* already initialized */
     961          53 :                 if (unlikely(null_epoch && !(*slot)->initialized))
     962           0 :                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     963             : 
     964          53 :                 if (unlikely((*slot)->epoch != session->security_parameters.epoch_next))
     965           0 :                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
     966             : 
     967          53 :                 goto finish;
     968             :         }
     969             : 
     970       52132 :         _gnutls_record_log("REC[%p]: Allocating epoch #%u\n", session,
     971             :                            session->security_parameters.epoch_next);
     972             : 
     973       52132 :         *slot = gnutls_calloc(1, sizeof(record_parameters_st));
     974       52132 :         if (*slot == NULL)
     975           0 :                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
     976             : 
     977       52132 :         (*slot)->epoch = session->security_parameters.epoch_next;
     978             : 
     979       52132 :         if (null_epoch) {
     980       23101 :                 (*slot)->cipher = cipher_to_entry(GNUTLS_CIPHER_NULL);
     981       23101 :                 (*slot)->mac = mac_to_entry(GNUTLS_MAC_NULL);
     982       23101 :                 (*slot)->initialized = 1;
     983             :         } else {
     984       29031 :                 (*slot)->cipher = NULL;
     985       29031 :                 (*slot)->mac = NULL;
     986             :         }
     987             : 
     988       52132 :         if (IS_DTLS(session)) {
     989         601 :                 uint64_t seq = (*slot)->write.sequence_number;
     990         601 :                 seq &= UINT64_C(0xffffffffffff);
     991         601 :                 seq |= ((uint64_t)session->security_parameters.epoch_next) << 48;
     992         601 :                 (*slot)->write.sequence_number = seq;
     993             :         }
     994             : 
     995       51531 :  finish:
     996       52185 :         if (newp != NULL)
     997        5763 :                 *newp = *slot;
     998             : 
     999             :         return 0;
    1000             : }
    1001             : 
    1002             : static inline int
    1003      133440 : epoch_is_active(gnutls_session_t session, record_parameters_st * params)
    1004             : {
    1005      133440 :         const security_parameters_st *sp = &session->security_parameters;
    1006             : 
    1007      133440 :         if (params->epoch == sp->epoch_read)
    1008             :                 return 1;
    1009             : 
    1010       58111 :         if (params->epoch == sp->epoch_write)
    1011             :                 return 1;
    1012             : 
    1013       56817 :         if (params->epoch == sp->epoch_next)
    1014             :                 return 1;
    1015             : 
    1016             :         return 0;
    1017             : }
    1018             : 
    1019             : static inline int
    1020       67211 : epoch_alive(gnutls_session_t session, record_parameters_st * params)
    1021             : {
    1022       67211 :         if (params->usage_cnt > 0)
    1023             :                 return 1;
    1024             : 
    1025       66229 :         return epoch_is_active(session, params);
    1026             : }
    1027             : 
    1028       37925 : void _gnutls_epoch_gc(gnutls_session_t session)
    1029             : {
    1030       37925 :         int i, j;
    1031       37925 :         unsigned int min_index = 0;
    1032             : 
    1033       37925 :         _gnutls_record_log("REC[%p]: Start of epoch cleanup\n", session);
    1034             : 
    1035       37925 :         gnutls_mutex_lock(&session->internals.epoch_lock);
    1036             : 
    1037             :         /* Free all dead cipher state */
    1038      227550 :         for (i = 0; i < MAX_EPOCH_INDEX; i++) {
    1039      151700 :                 if (session->record_parameters[i] != NULL) {
    1040       67211 :                         if (!epoch_is_active
    1041             :                             (session, session->record_parameters[i])
    1042       20503 :                             && session->record_parameters[i]->usage_cnt)
    1043         455 :                                 _gnutls_record_log
    1044             :                                     ("REC[%p]: Note inactive epoch %d has %d users\n",
    1045             :                                      session,
    1046             :                                      session->record_parameters[i]->epoch,
    1047             :                                      session->record_parameters[i]->
    1048             :                                      usage_cnt);
    1049      217929 :                         if (!epoch_alive
    1050             :                             (session, session->record_parameters[i])) {
    1051       20048 :                                 _gnutls_epoch_free(session,
    1052             :                                                    session->
    1053             :                                                    record_parameters[i]);
    1054       20048 :                                 session->record_parameters[i] = NULL;
    1055             :                         }
    1056             :                 }
    1057             :         }
    1058             : 
    1059             :         /* Look for contiguous NULLs at the start of the array */
    1060       58007 :         for (i = 0;
    1061       58007 :              i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL;
    1062       20082 :              i++);
    1063       37925 :         min_index = i;
    1064             : 
    1065             :         /* Pick up the slack in the epoch window. */
    1066       37925 :         if (min_index != 0) {
    1067       52328 :                 for (i = 0, j = min_index; j < MAX_EPOCH_INDEX; i++, j++) {
    1068       37846 :                         session->record_parameters[i] =
    1069       37846 :                             session->record_parameters[j];
    1070       37846 :                         session->record_parameters[j] = NULL;
    1071             :                 }
    1072             :         }
    1073             : 
    1074             :         /* Set the new epoch_min */
    1075       37925 :         if (session->record_parameters[0] != NULL)
    1076       37925 :                 session->security_parameters.epoch_min =
    1077       37925 :                     session->record_parameters[0]->epoch;
    1078             : 
    1079       37925 :         gnutls_mutex_unlock(&session->internals.epoch_lock);
    1080             : 
    1081       37925 :         _gnutls_record_log("REC[%p]: End of epoch cleanup\n", session);
    1082       37925 : }
    1083             : 
    1084      103986 : static inline void free_record_state(record_state_st * state)
    1085             : {
    1086      103986 :         zeroize_temp_key(state->mac_key, state->mac_key_size);
    1087      103986 :         zeroize_temp_key(state->iv, state->iv_size);
    1088      103986 :         zeroize_temp_key(state->key, state->key_size);
    1089             : 
    1090      103986 :         if (state->is_aead)
    1091       22882 :                 _gnutls_aead_cipher_deinit(&state->ctx.aead);
    1092             :         else
    1093       81104 :                 _gnutls_auth_cipher_deinit(&state->ctx.tls12);
    1094      103986 : }
    1095             : 
    1096             : void
    1097       51993 : _gnutls_epoch_free(gnutls_session_t session, record_parameters_st * params)
    1098             : {
    1099       51993 :         _gnutls_record_log("REC[%p]: Epoch #%u freed\n", session,
    1100             :                            params->epoch);
    1101             : 
    1102       51993 :         free_record_state(&params->read);
    1103       51993 :         free_record_state(&params->write);
    1104             : 
    1105       51993 :         gnutls_free(params);
    1106       51993 : }
    1107             : 
    1108        6357 : int _tls13_connection_state_init(gnutls_session_t session, hs_stage_t stage)
    1109             : {
    1110        6357 :         const uint16_t epoch_next =
    1111             :             session->security_parameters.epoch_next;
    1112        6357 :         int ret;
    1113             : 
    1114        6357 :         ret = _gnutls_epoch_set_keys(session, epoch_next, stage);
    1115        6357 :         if (ret < 0)
    1116             :                 return ret;
    1117             : 
    1118        6357 :         _gnutls_handshake_log("HSK[%p]: TLS 1.3 re-key with cipher suite: %s\n",
    1119             :                               session,
    1120             :                               session->security_parameters.cs->name);
    1121             : 
    1122        6357 :         session->security_parameters.epoch_read = epoch_next;
    1123        6357 :         session->security_parameters.epoch_write = epoch_next;
    1124             : 
    1125        6357 :         return 0;
    1126             : }
    1127             : 
    1128        5002 : int _tls13_read_connection_state_init(gnutls_session_t session, hs_stage_t stage)
    1129             : {
    1130        5002 :         const uint16_t epoch_next =
    1131             :             session->security_parameters.epoch_next;
    1132        5002 :         int ret;
    1133             : 
    1134        5002 :         ret = _gnutls_epoch_set_keys(session, epoch_next, stage);
    1135        5002 :         if (ret < 0)
    1136             :                 return ret;
    1137             : 
    1138        5002 :         _gnutls_handshake_log("HSK[%p]: TLS 1.3 set read key with cipher suite: %s\n",
    1139             :                               session,
    1140             :                               session->security_parameters.cs->name);
    1141             : 
    1142        5002 :         session->security_parameters.epoch_read = epoch_next;
    1143             : 
    1144        5002 :         return 0;
    1145             : }
    1146             : 
    1147        5100 : int _tls13_write_connection_state_init(gnutls_session_t session, hs_stage_t stage)
    1148             : {
    1149        5100 :         const uint16_t epoch_next =
    1150             :             session->security_parameters.epoch_next;
    1151        5100 :         int ret;
    1152             : 
    1153        5100 :         ret = _gnutls_epoch_set_keys(session, epoch_next, stage);
    1154        5100 :         if (ret < 0)
    1155             :                 return ret;
    1156             : 
    1157        5100 :         _gnutls_handshake_log("HSK[%p]: TLS 1.3 set write key with cipher suite: %s\n",
    1158             :                               session,
    1159             :                               session->security_parameters.cs->name);
    1160             : 
    1161        5100 :         session->security_parameters.epoch_write = epoch_next;
    1162             : 
    1163        5100 :         return 0;
    1164             : }
    1165             : 
    1166             : static int
    1167       22916 : _tls13_init_record_state(gnutls_cipher_algorithm_t algo, record_state_st *state)
    1168             : {
    1169       22916 :         int ret;
    1170       22916 :         gnutls_datum_t key;
    1171             : 
    1172       22916 :         key.data = state->key;
    1173       22916 :         key.size = state->key_size;
    1174             : 
    1175       22916 :         ret = _gnutls_aead_cipher_init(&state->ctx.aead,
    1176             :                                        algo, &key);
    1177       22916 :         if (ret < 0)
    1178           0 :                 return gnutls_assert_val(ret);
    1179             : 
    1180       22916 :         state->aead_tag_size = gnutls_cipher_get_tag_size(algo);
    1181       22916 :         state->is_aead = 1;
    1182             : 
    1183       22916 :         return 0;
    1184             : }

Generated by: LCOV version 1.14