Coverage Report

Created: 2025-03-06 07:58

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