69
71
/* avoid using malloc */
70
72
opaque key_block[2 * MAX_HASH_SIZE + 2 * MAX_CIPHER_KEY_SIZE +
71
2 * MAX_CIPHER_BLOCK_SIZE];
73
2 * MAX_CIPHER_BLOCK_SIZE];
74
record_state_st *client_write, *server_write;
73
if (session->cipher_specs.generated_keys != 0)
75
/* keys have already been generated.
76
* reset generated_keys and exit normally.
78
session->cipher_specs.generated_keys = 0;
77
session->security_parameters.entity ==
78
GNUTLS_CLIENT ? ¶ms->write : ¶ms->read;
80
session->security_parameters.entity ==
81
GNUTLS_SERVER ? ¶ms->write : ¶ms->read;
82
83
block_size = 2 * hash_size + 2 * key_size;
83
84
if (export_flag == 0)
84
85
block_size += 2 * IV_size;
86
87
memcpy (rnd, session->security_parameters.server_random,
88
89
memcpy (&rnd[GNUTLS_RANDOM_SIZE],
89
session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
90
session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
91
92
memcpy (rrnd, session->security_parameters.client_random,
93
94
memcpy (&rrnd[GNUTLS_RANDOM_SIZE],
94
session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
95
session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
96
97
if (session->security_parameters.version == GNUTLS_SSL3)
99
_gnutls_ssl3_generate_random
100
(session->security_parameters.master_secret, GNUTLS_MASTER_SIZE, rnd,
101
2 * GNUTLS_RANDOM_SIZE, block_size, key_block);
100
_gnutls_ssl3_generate_random
101
(session->security_parameters.master_secret, GNUTLS_MASTER_SIZE, rnd,
102
2 * GNUTLS_RANDOM_SIZE, block_size, key_block);
106
_gnutls_PRF (session, session->security_parameters.master_secret,
107
GNUTLS_MASTER_SIZE, keyexp, keyexp_length,
108
rnd, 2 * GNUTLS_RANDOM_SIZE, block_size, key_block);
107
_gnutls_PRF (session, session->security_parameters.master_secret,
108
GNUTLS_MASTER_SIZE, keyexp, keyexp_length,
109
rnd, 2 * GNUTLS_RANDOM_SIZE, block_size, key_block);
113
return gnutls_assert_val (ret);
117
115
_gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size,
118
_gnutls_bin2hex (key_block, block_size, buf,
121
_gnutls_free_datum (&session->cipher_specs.server_write_mac_secret);
122
_gnutls_free_datum (&session->cipher_specs.client_write_mac_secret);
123
_gnutls_free_datum (&session->cipher_specs.server_write_IV);
124
_gnutls_free_datum (&session->cipher_specs.client_write_IV);
125
_gnutls_free_datum (&session->cipher_specs.server_write_key);
126
_gnutls_free_datum (&session->cipher_specs.client_write_key);
116
_gnutls_bin2hex (key_block, block_size, buf,
117
sizeof (buf), NULL));
129
120
if (hash_size > 0)
132
123
if (_gnutls_sset_datum
133
(&session->cipher_specs.client_write_mac_secret,
134
&key_block[pos], hash_size) < 0)
137
return GNUTLS_E_MEMORY_ERROR;
124
(&client_write->mac_secret, &key_block[pos], hash_size) < 0)
125
return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
139
127
pos += hash_size;
141
129
if (_gnutls_sset_datum
142
(&session->cipher_specs.server_write_mac_secret,
143
&key_block[pos], hash_size) < 0)
146
return GNUTLS_E_MEMORY_ERROR;
130
(&server_write->mac_secret, &key_block[pos], hash_size) < 0)
131
return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
148
133
pos += hash_size;
156
141
int client_write_key_size, server_write_key_size;
158
143
if (export_flag == 0)
160
client_write_key = &key_block[pos];
161
client_write_key_size = key_size;
165
server_write_key = &key_block[pos];
166
server_write_key_size = key_size;
145
client_write_key = &key_block[pos];
146
client_write_key_size = key_size;
150
server_write_key = &key_block[pos];
151
server_write_key_size = key_size;
173
client_write_key = key1;
174
server_write_key = key2;
176
/* generate the final keys */
178
if (session->security_parameters.version == GNUTLS_SSL3)
181
_gnutls_ssl3_hash_md5 (&key_block[pos],
183
2 * GNUTLS_RANDOM_SIZE,
184
EXPORT_FINAL_KEY_SIZE,
191
_gnutls_PRF (session, &key_block[pos], key_size,
192
cliwrite, cliwrite_length,
194
2 * GNUTLS_RANDOM_SIZE,
195
EXPORT_FINAL_KEY_SIZE, client_write_key);
204
client_write_key_size = EXPORT_FINAL_KEY_SIZE;
207
if (session->security_parameters.version == GNUTLS_SSL3)
210
_gnutls_ssl3_hash_md5 (&key_block[pos], key_size,
211
rnd, 2 * GNUTLS_RANDOM_SIZE,
212
EXPORT_FINAL_KEY_SIZE,
218
_gnutls_PRF (session, &key_block[pos], key_size,
219
servwrite, servwrite_length,
220
rrnd, 2 * GNUTLS_RANDOM_SIZE,
221
EXPORT_FINAL_KEY_SIZE, server_write_key);
230
server_write_key_size = EXPORT_FINAL_KEY_SIZE;
158
client_write_key = key1;
159
server_write_key = key2;
161
/* generate the final keys */
163
if (session->security_parameters.version == GNUTLS_SSL3)
166
_gnutls_ssl3_hash_md5 (&key_block[pos],
168
2 * GNUTLS_RANDOM_SIZE,
169
EXPORT_FINAL_KEY_SIZE,
176
_gnutls_PRF (session, &key_block[pos], key_size,
177
cliwrite, cliwrite_length,
179
2 * GNUTLS_RANDOM_SIZE,
180
EXPORT_FINAL_KEY_SIZE, client_write_key);
184
return gnutls_assert_val (ret);
186
client_write_key_size = EXPORT_FINAL_KEY_SIZE;
189
if (session->security_parameters.version == GNUTLS_SSL3)
192
_gnutls_ssl3_hash_md5 (&key_block[pos], key_size,
193
rnd, 2 * GNUTLS_RANDOM_SIZE,
194
EXPORT_FINAL_KEY_SIZE,
200
_gnutls_PRF (session, &key_block[pos], key_size,
201
servwrite, servwrite_length,
202
rrnd, 2 * GNUTLS_RANDOM_SIZE,
203
EXPORT_FINAL_KEY_SIZE, server_write_key);
207
return gnutls_assert_val (ret);
209
server_write_key_size = EXPORT_FINAL_KEY_SIZE;
234
213
if (_gnutls_sset_datum
235
(&session->cipher_specs.client_write_key,
236
client_write_key, client_write_key_size) < 0)
239
return GNUTLS_E_MEMORY_ERROR;
214
(&client_write->key, client_write_key, client_write_key_size) < 0)
215
return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
241
217
_gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n",
242
client_write_key_size,
243
_gnutls_bin2hex (client_write_key,
244
client_write_key_size, buf,
218
client_write_key_size,
219
_gnutls_bin2hex (client_write_key,
220
client_write_key_size, buf,
221
sizeof (buf), NULL));
247
223
if (_gnutls_sset_datum
248
(&session->cipher_specs.server_write_key,
249
server_write_key, server_write_key_size) < 0)
252
return GNUTLS_E_MEMORY_ERROR;
224
(&server_write->key, server_write_key, server_write_key_size) < 0)
225
return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
255
227
_gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n",
256
server_write_key_size,
257
_gnutls_bin2hex (server_write_key,
258
server_write_key_size, buf,
228
server_write_key_size,
229
_gnutls_bin2hex (server_write_key,
230
server_write_key_size, buf,
231
sizeof (buf), NULL));
289
255
opaque iv_block[MAX_CIPHER_BLOCK_SIZE * 2];
291
257
if (session->security_parameters.version == GNUTLS_SSL3)
293
ret = _gnutls_ssl3_hash_md5 ("", 0,
294
rrnd, GNUTLS_RANDOM_SIZE * 2,
303
ret = _gnutls_ssl3_hash_md5 ("", 0, rnd,
304
GNUTLS_RANDOM_SIZE * 2,
305
IV_size, &iv_block[IV_size]);
259
ret = _gnutls_ssl3_hash_md5 ("", 0,
260
rrnd, GNUTLS_RANDOM_SIZE * 2,
264
return gnutls_assert_val (ret);
267
ret = _gnutls_ssl3_hash_md5 ("", 0, rnd,
268
GNUTLS_RANDOM_SIZE * 2,
269
IV_size, &iv_block[IV_size]);
310
ret = _gnutls_PRF (session, "", 0,
311
ivblock, ivblock_length, rrnd,
312
2 * GNUTLS_RANDOM_SIZE, IV_size * 2, iv_block);
274
ret = _gnutls_PRF (session, "", 0,
275
ivblock, ivblock_length, rrnd,
276
2 * GNUTLS_RANDOM_SIZE, IV_size * 2, iv_block);
321
if (_gnutls_sset_datum
322
(&session->cipher_specs.client_write_IV, iv_block, IV_size) < 0)
325
return GNUTLS_E_MEMORY_ERROR;
328
if (_gnutls_sset_datum
329
(&session->cipher_specs.server_write_IV,
330
&iv_block[IV_size], IV_size) < 0)
333
return GNUTLS_E_MEMORY_ERROR;
337
session->cipher_specs.generated_keys = 1;
343
_gnutls_set_read_keys (gnutls_session_t session)
347
int key_size, export_flag;
348
gnutls_cipher_algorithm_t algo;
349
gnutls_mac_algorithm_t mac_algo;
351
mac_algo = session->security_parameters.read_mac_algorithm;
352
algo = session->security_parameters.read_bulk_cipher_algorithm;
354
hash_size = _gnutls_hash_get_algo_len (mac_algo);
355
IV_size = _gnutls_cipher_get_iv_size (algo);
356
key_size = gnutls_cipher_get_key_size (algo);
357
export_flag = _gnutls_cipher_get_export_flag (algo);
359
return _gnutls_set_keys (session, hash_size, IV_size, key_size,
364
_gnutls_set_write_keys (gnutls_session_t session)
368
int key_size, export_flag;
369
gnutls_cipher_algorithm_t algo;
370
gnutls_mac_algorithm_t mac_algo;
372
mac_algo = session->security_parameters.write_mac_algorithm;
373
algo = session->security_parameters.write_bulk_cipher_algorithm;
375
hash_size = _gnutls_hash_get_algo_len (mac_algo);
376
IV_size = _gnutls_cipher_get_iv_size (algo);
377
key_size = gnutls_cipher_get_key_size (algo);
378
export_flag = _gnutls_cipher_get_export_flag (algo);
380
return _gnutls_set_keys (session, hash_size, IV_size, key_size,
384
#define CPY_EXTENSIONS \
385
gnutls_free(dst->extensions.session_ticket); \
386
gnutls_free(dst->extensions.oprfi_client); \
387
gnutls_free(dst->extensions.oprfi_server); \
388
memcpy(&dst->extensions.server_names, &src->extensions, sizeof(src->extensions)); \
389
memset(&src->extensions, 0, sizeof(src->extensions)) /* avoid duplicate free's */
280
return gnutls_assert_val (ret);
282
if (_gnutls_sset_datum (&client_write->IV, iv_block, IV_size) < 0)
283
return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
285
if (_gnutls_sset_datum
286
(&server_write->IV, &iv_block[IV_size], IV_size) < 0)
287
return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
294
_gnutls_init_record_state (record_parameters_st * params, int read,
295
record_state_st * state)
299
ret = _gnutls_cipher_init (&state->cipher_state,
300
params->cipher_algorithm,
301
&state->key, &state->IV);
302
if (ret < 0 && params->cipher_algorithm != GNUTLS_CIPHER_NULL)
303
return gnutls_assert_val (ret);
305
state->compression_state =
306
_gnutls_comp_init (params->compression_algorithm, read);
308
if (state->compression_state == GNUTLS_COMP_FAILED)
309
return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM);
315
_gnutls_epoch_set_cipher_suite (gnutls_session_t session,
316
int epoch_rel, cipher_suite_st * suite)
318
gnutls_cipher_algorithm_t cipher_algo;
319
gnutls_mac_algorithm_t mac_algo;
320
record_parameters_st *params;
323
ret = _gnutls_epoch_get (session, epoch_rel, ¶ms);
325
return gnutls_assert_val (ret);
327
if (params->initialized
328
|| params->cipher_algorithm != GNUTLS_CIPHER_UNKNOWN
329
|| params->mac_algorithm != GNUTLS_MAC_UNKNOWN)
330
return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR);
332
cipher_algo = _gnutls_cipher_suite_get_cipher_algo (suite);
333
mac_algo = _gnutls_cipher_suite_get_mac_algo (suite);
335
if (_gnutls_cipher_is_ok (cipher_algo) != 0
336
|| _gnutls_mac_is_ok (mac_algo) != 0)
337
return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM);
339
params->cipher_algorithm = cipher_algo;
340
params->mac_algorithm = mac_algo;
346
_gnutls_epoch_set_compression (gnutls_session_t session,
348
gnutls_compression_method_t comp_algo)
350
record_parameters_st *params;
353
ret = _gnutls_epoch_get (session, epoch_rel, ¶ms);
355
return gnutls_assert_val (ret);
357
if (params->initialized
358
|| params->compression_algorithm != GNUTLS_COMP_UNKNOWN)
359
return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR);
361
if (_gnutls_compression_is_ok (comp_algo) != 0)
362
return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM);
364
params->compression_algorithm = comp_algo;
370
_gnutls_epoch_set_null_algos (gnutls_session_t session,
371
record_parameters_st * params)
373
/* This is only called on startup. We are extra paranoid about this
374
because it may cause unencrypted application data to go out on
376
if (params->initialized || params->epoch != 0)
382
params->cipher_algorithm = GNUTLS_CIPHER_NULL;
383
params->mac_algorithm = GNUTLS_MAC_NULL;
384
params->compression_algorithm = GNUTLS_COMP_NULL;
385
params->initialized = 1;
389
_gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch)
393
int key_size, export_flag;
394
gnutls_cipher_algorithm_t cipher_algo;
395
gnutls_mac_algorithm_t mac_algo;
396
gnutls_compression_method_t comp_algo;
397
record_parameters_st *params;
400
ret = _gnutls_epoch_get (session, epoch, ¶ms);
402
return gnutls_assert_val (ret);
404
if (params->initialized)
408
("REC[%p]: Initializing epoch #%u\n", session, params->epoch);
410
cipher_algo = params->cipher_algorithm;
411
mac_algo = params->mac_algorithm;
412
comp_algo = params->compression_algorithm;
414
if (_gnutls_cipher_is_ok (cipher_algo) != 0
415
|| _gnutls_mac_is_ok (mac_algo) != 0)
416
return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR);
418
if (_gnutls_compression_is_ok (comp_algo) != 0)
419
return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM);
421
IV_size = _gnutls_cipher_get_iv_size (cipher_algo);
422
key_size = gnutls_cipher_get_key_size (cipher_algo);
423
export_flag = _gnutls_cipher_get_export_flag (cipher_algo);
424
hash_size = _gnutls_hash_get_algo_len (mac_algo);
426
ret = _gnutls_set_keys
427
(session, params, hash_size, IV_size, key_size, export_flag);
429
return gnutls_assert_val (ret);
431
ret = _gnutls_init_record_state (params, 1, ¶ms->read);
433
return gnutls_assert_val (ret);
435
ret = _gnutls_init_record_state (params, 0, ¶ms->write);
437
return gnutls_assert_val (ret);
439
_gnutls_record_log ("REC[%p]: Epoch #%u ready\n", session, params->epoch);
441
params->initialized = 1;
391
446
#define CPY_COMMON dst->entity = src->entity; \
392
447
dst->kx_algorithm = src->kx_algorithm; \
457
526
_gnutls_read_connection_state_init (gnutls_session_t session)
462
_gnutls_uint64zero (session->connection_state.read_sequence_number);
464
/* Update internals from CipherSuite selected.
465
* If we are resuming just copy the connection session
528
const uint16_t epoch_next = session->security_parameters.epoch_next;
531
/* Update internals from CipherSuite selected.
532
* If we are resuming just copy the connection session
467
534
if (session->internals.resumed == RESUME_FALSE)
469
rc = _gnutls_set_read_cipher (session,
470
_gnutls_cipher_suite_get_cipher_algo
472
security_parameters.current_cipher_suite));
475
rc = _gnutls_set_read_mac (session,
476
_gnutls_cipher_suite_get_mac_algo
478
security_parameters.current_cipher_suite));
482
rc = _gnutls_set_kx (session,
483
_gnutls_cipher_suite_get_kx_algo
485
security_parameters.current_cipher_suite));
489
rc = _gnutls_set_read_compression (session,
491
internals.compression_method);
497
_gnutls_cpy_read_security_parameters (&session->security_parameters,
499
internals.resumed_security_parameters);
503
rc = _gnutls_set_read_keys (session);
536
ret = _gnutls_check_algos (session,
538
security_parameters.current_cipher_suite,
539
session->internals.compression_method);
543
ret = _gnutls_set_kx (session,
544
_gnutls_cipher_suite_get_kx_algo
546
security_parameters.current_cipher_suite));
550
else if (session->security_parameters.entity == GNUTLS_CLIENT)
551
_gnutls_set_resumed_parameters (session);
553
ret = _gnutls_epoch_set_keys (session, epoch_next);
507
557
_gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n",
509
_gnutls_cipher_suite_get_name
511
security_parameters.current_cipher_suite));
513
if (_gnutls_compression_is_ok
514
(session->security_parameters.read_compression_algorithm) != 0)
517
return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
520
if (_gnutls_mac_is_ok
521
(session->security_parameters.read_mac_algorithm) != 0)
524
return GNUTLS_E_INTERNAL_ERROR;
527
/* Free all the previous keys/ sessions etc.
529
if (session->connection_state.read_mac_secret.data != NULL)
530
_gnutls_free_datum (&session->connection_state.read_mac_secret);
532
_gnutls_cipher_deinit (&session->connection_state.read_cipher_state);
534
if (session->connection_state.read_compression_state != NULL)
535
_gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
539
_gnutls_hash_get_algo_len (session->
540
security_parameters.read_mac_algorithm);
542
_gnutls_handshake_log
543
("HSK[%p]: Initializing internal [read] cipher sessions\n", session);
545
switch (session->security_parameters.entity)
548
/* initialize cipher session
550
rc = _gnutls_cipher_init (&session->connection_state.read_cipher_state,
551
session->security_parameters.
552
read_bulk_cipher_algorithm,
553
&session->cipher_specs.client_write_key,
554
&session->cipher_specs.client_write_IV);
556
&& session->security_parameters.read_bulk_cipher_algorithm !=
563
/* copy mac secrets from cipherspecs, to connection
568
if (_gnutls_sset_datum (&session->connection_state.read_mac_secret,
570
cipher_specs.client_write_mac_secret.data,
572
cipher_specs.client_write_mac_secret.size) <
576
return GNUTLS_E_MEMORY_ERROR;
584
rc = _gnutls_cipher_init (&session->connection_state.read_cipher_state,
585
session->security_parameters.
586
read_bulk_cipher_algorithm,
587
&session->cipher_specs.server_write_key,
588
&session->cipher_specs.server_write_IV);
591
&& session->security_parameters.read_bulk_cipher_algorithm !=
595
return GNUTLS_E_INTERNAL_ERROR;
599
/* copy mac secret to connection session
603
if (_gnutls_sset_datum (&session->connection_state.read_mac_secret,
605
cipher_specs.server_write_mac_secret.data,
607
cipher_specs.server_write_mac_secret.size) <
611
return GNUTLS_E_MEMORY_ERROR;
617
default: /* this check is useless */
619
return GNUTLS_E_INTERNAL_ERROR;
622
session->connection_state.read_compression_state =
623
_gnutls_comp_init (session->
624
security_parameters.read_compression_algorithm, 1);
626
if (session->connection_state.read_compression_state == GNUTLS_COMP_FAILED)
629
return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
559
_gnutls_cipher_suite_get_name
561
security_parameters.current_cipher_suite));
563
session->security_parameters.epoch_read = epoch_next;
564
_gnutls_epoch_gc (session);
641
575
_gnutls_write_connection_state_init (gnutls_session_t session)
646
_gnutls_uint64zero (session->connection_state.write_sequence_number);
577
const uint16_t epoch_next = session->security_parameters.epoch_next;
648
580
/* Update internals from CipherSuite selected.
649
581
* If we are resuming just copy the connection session
651
583
if (session->internals.resumed == RESUME_FALSE)
653
rc = _gnutls_set_write_cipher (session,
654
_gnutls_cipher_suite_get_cipher_algo
656
security_parameters.current_cipher_suite));
659
rc = _gnutls_set_write_mac (session,
660
_gnutls_cipher_suite_get_mac_algo
662
security_parameters.current_cipher_suite));
666
rc = _gnutls_set_kx (session,
667
_gnutls_cipher_suite_get_kx_algo
669
security_parameters.current_cipher_suite));
673
rc = _gnutls_set_write_compression (session,
675
internals.compression_method);
681
_gnutls_cpy_write_security_parameters (&session->security_parameters,
683
internals.resumed_security_parameters);
686
rc = _gnutls_set_write_keys (session);
585
ret = _gnutls_check_algos (session,
587
security_parameters.current_cipher_suite,
588
session->internals.compression_method);
592
ret = _gnutls_set_kx (session,
593
_gnutls_cipher_suite_get_kx_algo
595
security_parameters.current_cipher_suite));
599
else if (session->security_parameters.entity == GNUTLS_SERVER)
600
_gnutls_set_resumed_parameters (session);
602
ret = _gnutls_epoch_set_keys (session, epoch_next);
604
return gnutls_assert_val (ret);
690
606
_gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n", session,
691
_gnutls_cipher_suite_get_name
693
security_parameters.current_cipher_suite));
695
if (_gnutls_compression_is_ok
696
(session->security_parameters.write_compression_algorithm) != 0)
699
return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
702
if (_gnutls_mac_is_ok
703
(session->security_parameters.write_mac_algorithm) != 0)
706
return GNUTLS_E_INTERNAL_ERROR;
711
/* Free all the previous keys/ sessions etc.
713
if (session->connection_state.write_mac_secret.data != NULL)
714
_gnutls_free_datum (&session->connection_state.write_mac_secret);
716
_gnutls_cipher_deinit (&session->connection_state.write_cipher_state);
718
if (session->connection_state.write_compression_state != NULL)
719
_gnutls_comp_deinit (session->connection_state.write_compression_state,
723
_gnutls_hash_get_algo_len (session->
724
security_parameters.write_mac_algorithm);
607
_gnutls_cipher_suite_get_name
609
security_parameters.current_cipher_suite));
726
611
_gnutls_handshake_log
727
612
("HSK[%p]: Initializing internal [write] cipher sessions\n", session);
729
switch (session->security_parameters.entity)
732
/* initialize cipher session
734
rc = _gnutls_cipher_init (&session->connection_state.write_cipher_state,
736
security_parameters.write_bulk_cipher_algorithm,
737
&session->cipher_specs.server_write_key,
738
&session->cipher_specs.server_write_IV);
741
&& session->security_parameters.write_bulk_cipher_algorithm !=
745
return GNUTLS_E_INTERNAL_ERROR;
749
/* copy mac secrets from cipherspecs, to connection
754
if (_gnutls_sset_datum (&session->connection_state.write_mac_secret,
756
cipher_specs.server_write_mac_secret.data,
758
cipher_specs.server_write_mac_secret.size) <
762
return GNUTLS_E_MEMORY_ERROR;
771
rc = _gnutls_cipher_init (&session->connection_state.write_cipher_state,
773
security_parameters.write_bulk_cipher_algorithm,
774
&session->cipher_specs.client_write_key,
775
&session->cipher_specs.client_write_IV);
778
&& session->security_parameters.write_bulk_cipher_algorithm !=
782
return GNUTLS_E_INTERNAL_ERROR;
785
/* copy mac secret to connection session
789
if (_gnutls_sset_datum (&session->connection_state.write_mac_secret,
791
cipher_specs.client_write_mac_secret.data,
793
cipher_specs.client_write_mac_secret.size) <
797
return GNUTLS_E_MEMORY_ERROR;
805
return GNUTLS_E_INTERNAL_ERROR;
809
session->connection_state.write_compression_state =
810
_gnutls_comp_init (session->
811
security_parameters.write_compression_algorithm, 0);
813
if (session->connection_state.write_compression_state == GNUTLS_COMP_FAILED)
816
return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
822
/* Sets the specified cipher into the pending session
825
_gnutls_set_read_cipher (gnutls_session_t session,
826
gnutls_cipher_algorithm_t algo)
829
if (_gnutls_cipher_is_ok (algo) == 0)
831
if (_gnutls_cipher_priority (session, algo) < 0)
834
return GNUTLS_E_UNWANTED_ALGORITHM;
837
session->security_parameters.read_bulk_cipher_algorithm = algo;
843
return GNUTLS_E_INTERNAL_ERROR;
851
_gnutls_set_write_cipher (gnutls_session_t session,
852
gnutls_cipher_algorithm_t algo)
855
if (_gnutls_cipher_is_ok (algo) == 0)
857
if (_gnutls_cipher_priority (session, algo) < 0)
860
return GNUTLS_E_UNWANTED_ALGORITHM;
863
session->security_parameters.write_bulk_cipher_algorithm = algo;
869
return GNUTLS_E_INTERNAL_ERROR;
877
/* Sets the specified algorithm into pending compression session
880
_gnutls_set_read_compression (gnutls_session_t session,
881
gnutls_compression_method_t algo)
884
if (_gnutls_compression_is_ok (algo) == 0)
886
session->security_parameters.read_compression_algorithm = algo;
891
return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
898
_gnutls_set_write_compression (gnutls_session_t session,
899
gnutls_compression_method_t algo)
902
if (_gnutls_compression_is_ok (algo) == 0)
904
session->security_parameters.write_compression_algorithm = algo;
909
return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
915
/* Sets the specified kx algorithm into pending session
614
session->security_parameters.epoch_write = epoch_next;
615
_gnutls_epoch_gc (session);
620
/* Sets the specified kx algorithm into pending session
918
623
_gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo)
923
628
session->security_parameters.kx_algorithm = algo;
928
return GNUTLS_E_INTERNAL_ERROR;
631
return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR);
930
633
if (_gnutls_kx_priority (session, algo) < 0)
933
/* we shouldn't get here */
934
return GNUTLS_E_UNWANTED_ALGORITHM;
941
/* Sets the specified mac algorithm into pending session */
943
_gnutls_set_read_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
946
if (_gnutls_mac_is_ok (algo) == 0)
948
session->security_parameters.read_mac_algorithm = algo;
953
return GNUTLS_E_INTERNAL_ERROR;
955
if (_gnutls_mac_priority (session, algo) < 0)
958
return GNUTLS_E_UNWANTED_ALGORITHM;
967
_gnutls_set_write_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
970
if (_gnutls_mac_is_ok (algo) == 0)
972
session->security_parameters.write_mac_algorithm = algo;
977
return GNUTLS_E_INTERNAL_ERROR;
979
if (_gnutls_mac_priority (session, algo) < 0)
982
return GNUTLS_E_UNWANTED_ALGORITHM;
634
return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM);
640
epoch_resolve (gnutls_session_t session,
641
unsigned int epoch_rel, uint16_t * epoch_out)
645
case EPOCH_READ_CURRENT:
646
*epoch_out = session->security_parameters.epoch_read;
649
case EPOCH_WRITE_CURRENT:
650
*epoch_out = session->security_parameters.epoch_write;
654
*epoch_out = session->security_parameters.epoch_next;
658
if (epoch_rel > 0xffffu)
659
return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST);
661
*epoch_out = epoch_rel;
666
static inline record_parameters_st **
667
epoch_get_slot (gnutls_session_t session, uint16_t epoch)
669
uint16_t epoch_index = epoch - session->security_parameters.epoch_min;
671
if (epoch_index >= MAX_EPOCH_INDEX)
677
/* The slot may still be empty (NULL) */
678
return &session->record_parameters[epoch_index];
682
_gnutls_epoch_get (gnutls_session_t session, unsigned int epoch_rel,
683
record_parameters_st ** params_out)
686
record_parameters_st **params;
689
ret = epoch_resolve (session, epoch_rel, &epoch);
691
return gnutls_assert_val (ret);
693
params = epoch_get_slot (session, epoch);
694
if (params == NULL || *params == NULL)
695
return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST);
697
*params_out = *params;
703
_gnutls_epoch_alloc (gnutls_session_t session, uint16_t epoch,
704
record_parameters_st ** out)
706
record_parameters_st **slot;
708
_gnutls_record_log ("REC[%p]: Allocating epoch #%u\n", session, epoch);
710
slot = epoch_get_slot (session, epoch);
712
/* If slot out of range or not empty. */
714
return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST);
717
return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST);
719
*slot = gnutls_calloc (1, sizeof (record_parameters_st));
721
return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR);
723
(*slot)->epoch = epoch;
724
(*slot)->cipher_algorithm = GNUTLS_CIPHER_UNKNOWN;
725
(*slot)->mac_algorithm = GNUTLS_MAC_UNKNOWN;
726
(*slot)->compression_algorithm = GNUTLS_COMP_UNKNOWN;
735
epoch_alive (gnutls_session_t session, record_parameters_st * params)
737
const security_parameters_st *sp = &session->security_parameters;
739
/* DTLS will, in addition, need to check the epoch timeout value. */
740
return (params->epoch == sp->epoch_read
741
|| params->epoch == sp->epoch_write
742
|| params->epoch == sp->epoch_next);
746
_gnutls_epoch_gc (gnutls_session_t session)
749
unsigned int min_index = 0;
751
_gnutls_record_log ("REC[%p]: Start of epoch cleanup\n", session);
753
/* Free all dead cipher state */
754
for (i = 0; i < MAX_EPOCH_INDEX; i++)
755
if (session->record_parameters[i] != NULL
756
&& !epoch_alive (session, session->record_parameters[i]))
758
_gnutls_epoch_free (session, session->record_parameters[i]);
759
session->record_parameters[i] = NULL;
762
/* Look for contiguous NULLs at the start of the array */
763
for (i = 0; i < MAX_EPOCH_INDEX && session->record_parameters[i] == NULL;
767
/* Pick up the slack in the epoch window. */
768
for (i = 0, j = min_index; j < MAX_EPOCH_INDEX; i++, j++)
769
session->record_parameters[i] = session->record_parameters[j];
771
/* Set the new epoch_min */
772
if (session->record_parameters[0] != NULL)
773
session->security_parameters.epoch_min =
774
session->record_parameters[0]->epoch;
776
_gnutls_record_log ("REC[%p]: End of epoch cleanup\n", session);
780
free_record_state (record_state_st * state, int read)
782
_gnutls_free_datum (&state->mac_secret);
783
_gnutls_free_datum (&state->IV);
784
_gnutls_free_datum (&state->key);
786
_gnutls_cipher_deinit (&state->cipher_state);
788
if (state->compression_state != NULL)
789
_gnutls_comp_deinit (state->compression_state, read);
793
_gnutls_epoch_free (gnutls_session_t session, record_parameters_st * params)
795
_gnutls_record_log ("REC[%p]: Epoch #%u freed\n", session, params->epoch);
797
free_record_state (¶ms->read, 1);
798
free_record_state (¶ms->write, 0);
800
gnutls_free (params);