Bug Summary

File:lib/gnutls_constate.c
Location:line 252, column 7
Description:Value stored to 'pos' is never read

Annotated Source Code

1/*
2 * Copyright (C) 2001-2006, 2008, 2010, 2012 Free Software Foundation,
3 * 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 3 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 <http://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 <gnutls_constate.h>
30#include <gnutls_errors.h>
31#include <gnutls_kx.h>
32#include <algorithms.h>
33#include <gnutls_num.h>
34#include <gnutls_datumgnutls_datum_t.h>
35#include <gnutls_state.h>
36#include <gnutls_extensions.h>
37#include <gnutls_buffers.h>
38
39static const char keyexp[] = "key expansion";
40static const int keyexp_length = sizeof (keyexp) - 1;
41
42static const char ivblock[] = "IV block";
43static const int ivblock_length = sizeof (ivblock) - 1;
44
45static const char cliwrite[] = "client write key";
46static const int cliwrite_length = sizeof (cliwrite) - 1;
47
48static const char servwrite[] = "server write key";
49static const int servwrite_length = sizeof (servwrite) - 1;
50
51#define EXPORT_FINAL_KEY_SIZE16 16
52
53/* This function is to be called after handshake, when master_secret,
54 * client_random and server_random have been initialized.
55 * This function creates the keys and stores them into pending session.
56 * (session->cipher_specs)
57 */
58static int
59_gnutls_set_keys (gnutls_session_t session, record_parameters_st * params,
60 int hash_size, int IV_size, int key_size, int export_flag)
61{
62 /* FIXME: This function is too long
63 */
64 opaque rnd[2 * GNUTLS_RANDOM_SIZE32];
65 opaque rrnd[2 * GNUTLS_RANDOM_SIZE32];
66 int pos, ret;
67 int block_size;
68 char buf[65];
69 /* avoid using malloc */
70 opaque key_block[2 * MAX_HASH_SIZE64 + 2 * MAX_CIPHER_KEY_SIZE32 +
71 2 * MAX_CIPHER_BLOCK_SIZE16];
72 record_state_st *client_write, *server_write;
73
74 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
75 {
76 client_write = &params->write;
77 server_write = &params->read;
78 }
79 else
80 {
81 client_write = &params->read;
82 server_write = &params->write;
83 }
84
85 block_size = 2 * hash_size + 2 * key_size;
86 if (export_flag == 0)
87 block_size += 2 * IV_size;
88
89 memcpy (rnd, session->security_parameters.server_random,
90 GNUTLS_RANDOM_SIZE32);
91 memcpy (&rnd[GNUTLS_RANDOM_SIZE32],
92 session->security_parameters.client_random, GNUTLS_RANDOM_SIZE32);
93
94 memcpy (rrnd, session->security_parameters.client_random,
95 GNUTLS_RANDOM_SIZE32);
96 memcpy (&rrnd[GNUTLS_RANDOM_SIZE32],
97 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE32);
98
99 if (session->security_parameters.version == GNUTLS_SSL3)
100 { /* SSL 3 */
101 ret =
102 _gnutls_ssl3_generate_random
103 (session->security_parameters.master_secret, GNUTLS_MASTER_SIZE48, rnd,
104 2 * GNUTLS_RANDOM_SIZE32, block_size, key_block);
105 }
106 else
107 { /* TLS 1.0 */
108 ret =
109 _gnutls_PRF (session, session->security_parameters.master_secret,
110 GNUTLS_MASTER_SIZE48, keyexp, keyexp_length,
111 rnd, 2 * GNUTLS_RANDOM_SIZE32, block_size, key_block);
112 }
113
114 if (ret < 0)
115 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 115);
116
117 _gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: KEY BLOCK[%d]: %s\n", block_size, _gnutls_bin2hex (
key_block, block_size, buf, sizeof (buf), ((void*)0))); } while
(0)
118 _gnutls_bin2hex (key_block, block_size, buf,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: KEY BLOCK[%d]: %s\n", block_size, _gnutls_bin2hex (
key_block, block_size, buf, sizeof (buf), ((void*)0))); } while
(0)
119 sizeof (buf), NULL))do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: KEY BLOCK[%d]: %s\n", block_size, _gnutls_bin2hex (
key_block, block_size, buf, sizeof (buf), ((void*)0))); } while
(0)
;
120
121 pos = 0;
122 if (hash_size > 0)
123 {
124
125 if (_gnutls_sset_datum_gnutls_set_datum_m(&client_write->mac_secret,&key_block
[pos],hash_size, gnutls_secure_malloc)
126 (&client_write->mac_secret, &key_block[pos], hash_size)_gnutls_set_datum_m(&client_write->mac_secret,&key_block
[pos],hash_size, gnutls_secure_malloc)
< 0)
127 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 127);
128
129 pos += hash_size;
130
131 if (_gnutls_sset_datum_gnutls_set_datum_m(&server_write->mac_secret,&key_block
[pos],hash_size, gnutls_secure_malloc)
132 (&server_write->mac_secret, &key_block[pos], hash_size)_gnutls_set_datum_m(&server_write->mac_secret,&key_block
[pos],hash_size, gnutls_secure_malloc)
< 0)
133 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 133);
134
135 pos += hash_size;
136 }
137
138 if (key_size > 0)
139 {
140 opaque key1[EXPORT_FINAL_KEY_SIZE16];
141 opaque key2[EXPORT_FINAL_KEY_SIZE16];
142 opaque *client_write_key, *server_write_key;
143 int client_write_key_size, server_write_key_size;
144
145 if (export_flag == 0)
146 {
147 client_write_key = &key_block[pos];
148 client_write_key_size = key_size;
149
150 pos += key_size;
151
152 server_write_key = &key_block[pos];
153 server_write_key_size = key_size;
154
155 pos += key_size;
156
157 }
158 else
159 { /* export */
160 client_write_key = key1;
161 server_write_key = key2;
162
163 /* generate the final keys */
164
165 if (session->security_parameters.version == GNUTLS_SSL3)
166 { /* SSL 3 */
167 ret =
168 _gnutls_ssl3_hash_md5 (&key_block[pos],
169 key_size, rrnd,
170 2 * GNUTLS_RANDOM_SIZE32,
171 EXPORT_FINAL_KEY_SIZE16,
172 client_write_key);
173
174 }
175 else
176 { /* TLS 1.0 */
177 ret =
178 _gnutls_PRF (session, &key_block[pos], key_size,
179 cliwrite, cliwrite_length,
180 rrnd,
181 2 * GNUTLS_RANDOM_SIZE32,
182 EXPORT_FINAL_KEY_SIZE16, client_write_key);
183 }
184
185 if (ret < 0)
186 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 186);
187
188 client_write_key_size = EXPORT_FINAL_KEY_SIZE16;
189 pos += key_size;
190
191 if (session->security_parameters.version == GNUTLS_SSL3)
192 { /* SSL 3 */
193 ret =
194 _gnutls_ssl3_hash_md5 (&key_block[pos], key_size,
195 rnd, 2 * GNUTLS_RANDOM_SIZE32,
196 EXPORT_FINAL_KEY_SIZE16,
197 server_write_key);
198 }
199 else
200 { /* TLS 1.0 */
201 ret =
202 _gnutls_PRF (session, &key_block[pos], key_size,
203 servwrite, servwrite_length,
204 rrnd, 2 * GNUTLS_RANDOM_SIZE32,
205 EXPORT_FINAL_KEY_SIZE16, server_write_key);
206 }
207
208 if (ret < 0)
209 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 209);
210
211 server_write_key_size = EXPORT_FINAL_KEY_SIZE16;
212 pos += key_size;
213 }
214
215 if (_gnutls_sset_datum_gnutls_set_datum_m(&client_write->key,client_write_key
,client_write_key_size, gnutls_secure_malloc)
216 (&client_write->key, client_write_key, client_write_key_size)_gnutls_set_datum_m(&client_write->key,client_write_key
,client_write_key_size, gnutls_secure_malloc)
< 0)
217 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 217);
218
219 _gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: CLIENT WRITE KEY [%d]: %s\n", client_write_key_size
, _gnutls_bin2hex (client_write_key, client_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
220 client_write_key_size,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: CLIENT WRITE KEY [%d]: %s\n", client_write_key_size
, _gnutls_bin2hex (client_write_key, client_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
221 _gnutls_bin2hex (client_write_key,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: CLIENT WRITE KEY [%d]: %s\n", client_write_key_size
, _gnutls_bin2hex (client_write_key, client_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
222 client_write_key_size, buf,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: CLIENT WRITE KEY [%d]: %s\n", client_write_key_size
, _gnutls_bin2hex (client_write_key, client_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
223 sizeof (buf), NULL))do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: CLIENT WRITE KEY [%d]: %s\n", client_write_key_size
, _gnutls_bin2hex (client_write_key, client_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
;
224
225 if (_gnutls_sset_datum_gnutls_set_datum_m(&server_write->key,server_write_key
,server_write_key_size, gnutls_secure_malloc)
226 (&server_write->key, server_write_key, server_write_key_size)_gnutls_set_datum_m(&server_write->key,server_write_key
,server_write_key_size, gnutls_secure_malloc)
< 0)
227 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 227);
228
229 _gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: SERVER WRITE KEY [%d]: %s\n", server_write_key_size
, _gnutls_bin2hex (server_write_key, server_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
230 server_write_key_size,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: SERVER WRITE KEY [%d]: %s\n", server_write_key_size
, _gnutls_bin2hex (server_write_key, server_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
231 _gnutls_bin2hex (server_write_key,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: SERVER WRITE KEY [%d]: %s\n", server_write_key_size
, _gnutls_bin2hex (server_write_key, server_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
232 server_write_key_size, buf,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: SERVER WRITE KEY [%d]: %s\n", server_write_key_size
, _gnutls_bin2hex (server_write_key, server_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
233 sizeof (buf), NULL))do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "INT: SERVER WRITE KEY [%d]: %s\n", server_write_key_size
, _gnutls_bin2hex (server_write_key, server_write_key_size, buf
, sizeof (buf), ((void*)0))); } while(0)
;
234
235 }
236
237
238 /* IV generation in export and non export ciphers.
239 */
240 if (IV_size > 0 && export_flag == 0)
241 {
242 if (_gnutls_sset_datum_gnutls_set_datum_m(&client_write->IV,&key_block[pos
],IV_size, gnutls_secure_malloc)
243 (&client_write->IV, &key_block[pos], IV_size)_gnutls_set_datum_m(&client_write->IV,&key_block[pos
],IV_size, gnutls_secure_malloc)
< 0)
244 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 244);
245
246 pos += IV_size;
247
248 if (_gnutls_sset_datum_gnutls_set_datum_m(&server_write->IV,&key_block[pos
],IV_size, gnutls_secure_malloc)
249 (&server_write->IV, &key_block[pos], IV_size)_gnutls_set_datum_m(&server_write->IV,&key_block[pos
],IV_size, gnutls_secure_malloc)
< 0)
250 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 250);
251
252 pos += IV_size;
Value stored to 'pos' is never read
253
254 }
255 else if (IV_size > 0 && export_flag != 0)
256 {
257 opaque iv_block[MAX_CIPHER_BLOCK_SIZE16 * 2];
258
259 if (session->security_parameters.version == GNUTLS_SSL3)
260 { /* SSL 3 */
261 ret = _gnutls_ssl3_hash_md5 ("", 0,
262 rrnd, GNUTLS_RANDOM_SIZE32 * 2,
263 IV_size, iv_block);
264
265 if (ret < 0)
266 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 266);
267
268
269 ret = _gnutls_ssl3_hash_md5 ("", 0, rnd,
270 GNUTLS_RANDOM_SIZE32 * 2,
271 IV_size, &iv_block[IV_size]);
272
273 }
274 else
275 { /* TLS 1.0 */
276 ret = _gnutls_PRF (session, "", 0,
277 ivblock, ivblock_length, rrnd,
278 2 * GNUTLS_RANDOM_SIZE32, IV_size * 2, iv_block);
279 }
280
281 if (ret < 0)
282 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 282);
283
284 if (_gnutls_sset_datum (&client_write->IV, iv_block, IV_size)_gnutls_set_datum_m(&client_write->IV,iv_block,IV_size
, gnutls_secure_malloc)
< 0)
285 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 285);
286
287 if (_gnutls_sset_datum_gnutls_set_datum_m(&server_write->IV,&iv_block[IV_size
],IV_size, gnutls_secure_malloc)
288 (&server_write->IV, &iv_block[IV_size], IV_size)_gnutls_set_datum_m(&server_write->IV,&iv_block[IV_size
],IV_size, gnutls_secure_malloc)
< 0)
289 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 289);
290 }
291
292 return 0;
293}
294
295static int
296_gnutls_init_record_state (record_parameters_st * params, gnutls_protocol_t ver, int read,
297 record_state_st * state)
298{
299 int ret;
300 gnutls_datum_t * iv = NULL((void*)0);
301
302 if (!_gnutls_version_has_explicit_iv(ver))
303 {
304 iv = &state->IV;
305 }
306
307 ret = _gnutls_auth_cipher_init (&state->cipher_state,
308 params->cipher_algorithm, &state->key, iv,
309 params->mac_algorithm, &state->mac_secret, (ver==GNUTLS_SSL3)?1:0, 1-read/*1==encrypt*/);
310 if (ret < 0 && params->cipher_algorithm != GNUTLS_CIPHER_NULL)
311 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 311);
312
313 ret =
314 _gnutls_comp_init (&state->compression_state, params->compression_algorithm, read/*1==decompress*/);
315
316 if (ret < 0)
317 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 317);
318
319 return 0;
320}
321
322int
323_gnutls_epoch_set_cipher_suite (gnutls_session_t session,
324 int epoch_rel, const uint8_t suite[2])
325{
326 gnutls_cipher_algorithm_t cipher_algo;
327 gnutls_mac_algorithm_t mac_algo;
328 record_parameters_st *params;
329 int ret;
330
331 ret = _gnutls_epoch_get (session, epoch_rel, &params);
332 if (ret < 0)
333 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 333);
334
335 if (params->initialized
336 || params->cipher_algorithm != GNUTLS_CIPHER_UNKNOWN
337 || params->mac_algorithm != GNUTLS_MAC_UNKNOWN)
338 return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "gnutls_constate.c", 338);
339
340 cipher_algo = _gnutls_cipher_suite_get_cipher_algo (suite);
341 mac_algo = _gnutls_cipher_suite_get_mac_algo (suite);
342
343 if (_gnutls_cipher_is_ok (cipher_algo) != 0
344 || _gnutls_mac_is_ok (mac_algo) != 0)
345 return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM)gnutls_assert_val_int(-22, "gnutls_constate.c", 345);
346
347 params->cipher_algorithm = cipher_algo;
348 params->mac_algorithm = mac_algo;
349
350 return 0;
351}
352
353int
354_gnutls_epoch_set_compression (gnutls_session_t session,
355 int epoch_rel,
356 gnutls_compression_method_t comp_algo)
357{
358 record_parameters_st *params;
359 int ret;
360
361 ret = _gnutls_epoch_get (session, epoch_rel, &params);
362 if (ret < 0)
363 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 363);
364
365 if (params->initialized
366 || params->compression_algorithm != GNUTLS_COMP_UNKNOWN)
367 return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "gnutls_constate.c", 367);
368
369 if (_gnutls_compression_is_ok (comp_algo) != 0)
370 return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM)gnutls_assert_val_int(-3, "gnutls_constate.c", 370);
371
372 params->compression_algorithm = comp_algo;
373
374 return 0;
375}
376
377void
378_gnutls_epoch_set_null_algos (gnutls_session_t session,
379 record_parameters_st * params)
380{
381 /* This is only called on startup. We are extra paranoid about this
382 because it may cause unencrypted application data to go out on
383 the wire. */
384 if (params->initialized || params->epoch != 0)
385 {
386 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_constate.c",386); } while(0);
;
387 return;
388 }
389
390 params->cipher_algorithm = GNUTLS_CIPHER_NULL;
391 params->mac_algorithm = GNUTLS_MAC_NULL;
392 params->compression_algorithm = GNUTLS_COMP_NULL;
393 params->initialized = 1;
394}
395
396int
397_gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch)
398{
399 int hash_size;
400 int IV_size;
401 int key_size, export_flag;
402 gnutls_cipher_algorithm_t cipher_algo;
403 gnutls_mac_algorithm_t mac_algo;
404 gnutls_compression_method_t comp_algo;
405 record_parameters_st *params;
406 int ret;
407 gnutls_protocol_t ver = gnutls_protocol_get_version_gnutls_protocol_get_version (session);
408
409 ret = _gnutls_epoch_get (session, epoch, &params);
410 if (ret < 0)
411 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 411);
412
413 if (params->initialized)
414 return 0;
415
416 _gnutls_record_logdo { if (__builtin_expect((_gnutls_log_level >= 4), 0)) _gnutls_log
( 4, "REC[%p]: Initializing epoch #%u\n", session, params->
epoch); } while(0)
417 ("REC[%p]: Initializing epoch #%u\n", session, params->epoch)do { if (__builtin_expect((_gnutls_log_level >= 4), 0)) _gnutls_log
( 4, "REC[%p]: Initializing epoch #%u\n", session, params->
epoch); } while(0)
;
418
419 cipher_algo = params->cipher_algorithm;
420 mac_algo = params->mac_algorithm;
421 comp_algo = params->compression_algorithm;
422
423 if (_gnutls_cipher_is_ok (cipher_algo) != 0
424 || _gnutls_mac_is_ok (mac_algo) != 0)
425 return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "gnutls_constate.c", 425);
426
427 if (_gnutls_compression_is_ok (comp_algo) != 0)
428 return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM)gnutls_assert_val_int(-3, "gnutls_constate.c", 428);
429
430 IV_size = _gnutls_cipher_get_iv_size (cipher_algo);
431 key_size = gnutls_cipher_get_key_size (cipher_algo);
432 export_flag = _gnutls_cipher_get_export_flag (cipher_algo);
433 hash_size = _gnutls_hash_get_algo_len (mac_algo);
434
435 ret = _gnutls_set_keys
436 (session, params, hash_size, IV_size, key_size, export_flag);
437 if (ret < 0)
438 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 438);
439
440 ret = _gnutls_init_record_state (params, ver, 1, &params->read);
441 if (ret < 0)
442 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 442);
443
444 ret = _gnutls_init_record_state (params, ver, 0, &params->write);
445 if (ret < 0)
446 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 446);
447
448 _gnutls_record_log ("REC[%p]: Epoch #%u ready\n", session, params->epoch)do { if (__builtin_expect((_gnutls_log_level >= 4), 0)) _gnutls_log
( 4, "REC[%p]: Epoch #%u ready\n", session, params->epoch)
; } while(0)
;
449
450 params->initialized = 1;
451 return 0;
452}
453
454
455#define CPY_COMMONdst->entity = src->entity; dst->kx_algorithm = src->
kx_algorithm; memcpy( dst->cipher_suite, src->cipher_suite
, 2); memcpy( dst->master_secret, src->master_secret, 48
); memcpy( dst->client_random, src->client_random, 32);
memcpy( dst->server_random, src->server_random, 32); memcpy
( dst->session_id, src->session_id, 32); dst->session_id_size
= src->session_id_size; dst->cert_type = src->cert_type
; dst->compression_method = src->compression_method; dst
->timestamp = src->timestamp; dst->max_record_recv_size
= src->max_record_recv_size; dst->max_record_send_size
= src->max_record_send_size; dst->version = src->version
dst->entity = src->entity; \
456 dst->kx_algorithm = src->kx_algorithm; \
457 memcpy( dst->cipher_suite, src->cipher_suite, 2); \
458 memcpy( dst->master_secret, src->master_secret, GNUTLS_MASTER_SIZE48); \
459 memcpy( dst->client_random, src->client_random, GNUTLS_RANDOM_SIZE32); \
460 memcpy( dst->server_random, src->server_random, GNUTLS_RANDOM_SIZE32); \
461 memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE32); \
462 dst->session_id_size = src->session_id_size; \
463 dst->cert_type = src->cert_type; \
464 dst->compression_method = src->compression_method; \
465 dst->timestamp = src->timestamp; \
466 dst->max_record_recv_size = src->max_record_recv_size; \
467 dst->max_record_send_size = src->max_record_send_size; \
468 dst->version = src->version
469
470static void
471_gnutls_set_resumed_parameters (gnutls_session_t session)
472{
473 security_parameters_st *src =
474 &session->internals.resumed_security_parameters;
475 security_parameters_st *dst = &session->security_parameters;
476
477 CPY_COMMONdst->entity = src->entity; dst->kx_algorithm = src->
kx_algorithm; memcpy( dst->cipher_suite, src->cipher_suite
, 2); memcpy( dst->master_secret, src->master_secret, 48
); memcpy( dst->client_random, src->client_random, 32);
memcpy( dst->server_random, src->server_random, 32); memcpy
( dst->session_id, src->session_id, 32); dst->session_id_size
= src->session_id_size; dst->cert_type = src->cert_type
; dst->compression_method = src->compression_method; dst
->timestamp = src->timestamp; dst->max_record_recv_size
= src->max_record_recv_size; dst->max_record_send_size
= src->max_record_send_size; dst->version = src->version
;
478}
479
480/* Sets the current connection session to conform with the
481 * Security parameters(pending session), and initializes encryption.
482 * Actually it initializes and starts encryption ( so it needs
483 * secrets and random numbers to have been negotiated)
484 * This is to be called after sending the Change Cipher Spec packet.
485 */
486int
487_gnutls_connection_state_init (gnutls_session_t session)
488{
489 int ret;
490
491/* Setup the master secret
492 */
493 if ((ret = _gnutls_generate_master (session, 0)) < 0)
494 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 494);
495
496 return 0;
497}
498
499
500
501static int
502_gnutls_check_algos (gnutls_session_t session,
503 const uint8_t suite[2],
504 gnutls_compression_method_t comp_algo)
505{
506 gnutls_cipher_algorithm_t cipher_algo;
507 gnutls_mac_algorithm_t mac_algo;
508
509 cipher_algo = _gnutls_cipher_suite_get_cipher_algo (suite);
510 mac_algo = _gnutls_cipher_suite_get_mac_algo (suite);
511
512 if (_gnutls_cipher_is_ok (cipher_algo) != 0)
513 return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "gnutls_constate.c", 513);
514
515 if (_gnutls_cipher_priority (session, cipher_algo) < 0)
516 return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM)gnutls_assert_val_int(-22, "gnutls_constate.c", 516);
517
518
519 if (_gnutls_mac_is_ok (mac_algo) != 0)
520 return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "gnutls_constate.c", 520);
521
522 if (_gnutls_mac_priority (session, mac_algo) < 0)
523 return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM)gnutls_assert_val_int(-22, "gnutls_constate.c", 523);
524
525
526 if (_gnutls_compression_is_ok (comp_algo) != 0)
527 return gnutls_assert_val (GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM)gnutls_assert_val_int(-3, "gnutls_constate.c", 527);
528
529 return 0;
530}
531
532int _gnutls_epoch_get_compression(gnutls_session_t session, int epoch)
533{
534record_parameters_st *params;
535int ret;
536
537 ret = _gnutls_epoch_get (session, epoch, &params);
538 if (ret < 0)
539 return GNUTLS_COMP_UNKNOWN;
540
541 return params->compression_algorithm;
542}
543
544/* Initializes the read connection session
545 * (read encrypted data)
546 */
547int
548_gnutls_read_connection_state_init (gnutls_session_t session)
549{
550 const uint16_t epoch_next = session->security_parameters.epoch_next;
551 int ret;
552
553 /* Update internals from CipherSuite selected.
554 * If we are resuming just copy the connection session
555 */
556 if (session->internals.resumed == RESUME_FALSE0)
557 {
558
559 ret = _gnutls_check_algos (session,
560 session->
561 security_parameters.cipher_suite,
562 _gnutls_epoch_get_compression(session, epoch_next));
563 if (ret < 0)
564 return ret;
565
566 ret = _gnutls_set_kx (session,
567 _gnutls_cipher_suite_get_kx_algo
568 (session->
569 security_parameters.cipher_suite));
570 if (ret < 0)
571 return ret;
572 }
573 else if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
574 _gnutls_set_resumed_parameters (session);
575
576 ret = _gnutls_epoch_set_keys (session, epoch_next);
577 if (ret < 0)
578 return ret;
579
580 _gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
581 session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
582 _gnutls_cipher_suite_get_namedo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
583 (session->do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
584 security_parameters.cipher_suite))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
;
585
586 session->security_parameters.epoch_read = epoch_next;
587
588 return 0;
589}
590
591
592
593/* Initializes the write connection session
594 * (write encrypted data)
595 */
596int
597_gnutls_write_connection_state_init (gnutls_session_t session)
598{
599 const uint16_t epoch_next = session->security_parameters.epoch_next;
600 int ret;
601
602/* Update internals from CipherSuite selected.
603 * If we are resuming just copy the connection session
604 */
605 if (session->internals.resumed == RESUME_FALSE0)
606 {
607 ret = _gnutls_check_algos (session,
608 session->
609 security_parameters.cipher_suite,
610 _gnutls_epoch_get_compression(session, epoch_next));
611 if (ret < 0)
612 return ret;
613
614 ret = _gnutls_set_kx (session,
615 _gnutls_cipher_suite_get_kx_algo
616 (session->
617 security_parameters.cipher_suite));
618 if (ret < 0)
619 return ret;
620 }
621 else if (session->security_parameters.entity == GNUTLS_SERVER1)
622 _gnutls_set_resumed_parameters (session);
623
624 ret = _gnutls_epoch_set_keys (session, epoch_next);
625 if (ret < 0)
626 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 626);
627
628 _gnutls_handshake_log ("HSK[%p]: Cipher Suite: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
629 _gnutls_cipher_suite_get_namedo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
630 (session->do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
631 security_parameters.cipher_suite))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
;
632
633 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Initializing internal [write] cipher sessions\n"
, session); } while(0)
634 ("HSK[%p]: Initializing internal [write] cipher sessions\n", session)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Initializing internal [write] cipher sessions\n"
, session); } while(0)
;
635
636 session->security_parameters.epoch_write = epoch_next;
637
638 return 0;
639}
640
641/* Sets the specified kx algorithm into pending session
642 */
643int
644_gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo)
645{
646
647 if (_gnutls_kx_is_ok (algo) == 0)
648 {
649 session->security_parameters.kx_algorithm = algo;
650 }
651 else
652 return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR)gnutls_assert_val_int(-59, "gnutls_constate.c", 652);
653
654 if (_gnutls_kx_priority (session, algo) < 0)
655 return gnutls_assert_val (GNUTLS_E_UNWANTED_ALGORITHM)gnutls_assert_val_int(-22, "gnutls_constate.c", 655);
656
657 return 0;
658}
659
660static inline int
661epoch_resolve (gnutls_session_t session,
662 unsigned int epoch_rel, uint16_t * epoch_out)
663{
664 switch (epoch_rel)
665 {
666 case EPOCH_READ_CURRENT70000:
667 *epoch_out = session->security_parameters.epoch_read;
668 return 0;
669
670 case EPOCH_WRITE_CURRENT70001:
671 *epoch_out = session->security_parameters.epoch_write;
672 return 0;
673
674 case EPOCH_NEXT70002:
675 *epoch_out = session->security_parameters.epoch_next;
676 return 0;
677
678 default:
679 if (epoch_rel > 0xffffu)
680 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST)gnutls_assert_val_int(-50, "gnutls_constate.c", 680);
681
682 *epoch_out = epoch_rel;
683 return 0;
684 }
685}
686
687static inline record_parameters_st **
688epoch_get_slot (gnutls_session_t session, uint16_t epoch)
689{
690 uint16_t epoch_index = epoch - session->security_parameters.epoch_min;
691
692 if (epoch_index >= MAX_EPOCH_INDEX16)
693 {
694 _gnutls_handshake_log("Epoch %d out of range (idx: %d, max: %d)\n", (int)epoch, (int)epoch_index, MAX_EPOCH_INDEX)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "Epoch %d out of range (idx: %d, max: %d)\n", (int)epoch
, (int)epoch_index, 16); } while(0)
;
695 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_constate.c",695); } while(0);
;
696 return NULL((void*)0);
697 }
698 /* The slot may still be empty (NULL) */
699 return &session->record_parameters[epoch_index];
700}
701
702int
703_gnutls_epoch_get (gnutls_session_t session, unsigned int epoch_rel,
704 record_parameters_st ** params_out)
705{
706 uint16_t epoch;
707 record_parameters_st **params;
708 int ret;
709
710 ret = epoch_resolve (session, epoch_rel, &epoch);
711 if (ret < 0)
712 return gnutls_assert_val (ret)gnutls_assert_val_int(ret, "gnutls_constate.c", 712);
713
714 params = epoch_get_slot (session, epoch);
715 if (params == NULL((void*)0) || *params == NULL((void*)0))
716 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST)gnutls_assert_val_int(-50, "gnutls_constate.c", 716);
717
718 *params_out = *params;
719
720 return 0;
721}
722
723int
724_gnutls_epoch_alloc (gnutls_session_t session, uint16_t epoch,
725 record_parameters_st ** out)
726{
727 record_parameters_st **slot;
728
729 _gnutls_record_log ("REC[%p]: Allocating epoch #%u\n", session, epoch)do { if (__builtin_expect((_gnutls_log_level >= 4), 0)) _gnutls_log
( 4, "REC[%p]: Allocating epoch #%u\n", session, epoch); } while
(0)
;
730
731 slot = epoch_get_slot (session, epoch);
732
733 /* If slot out of range or not empty. */
734 if (slot == NULL((void*)0))
735 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST)gnutls_assert_val_int(-50, "gnutls_constate.c", 735);
736
737 if (*slot != NULL((void*)0))
738 return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST)gnutls_assert_val_int(-50, "gnutls_constate.c", 738);
739
740 *slot = gnutls_calloc (1, sizeof (record_parameters_st));
741 if (*slot == NULL((void*)0))
742 return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_constate.c", 742);
743
744 (*slot)->epoch = epoch;
745 (*slot)->cipher_algorithm = GNUTLS_CIPHER_UNKNOWN;
746 (*slot)->mac_algorithm = GNUTLS_MAC_UNKNOWN;
747 (*slot)->compression_algorithm = GNUTLS_COMP_UNKNOWN;
748
749 if (IS_DTLS (session)(session->internals.transport == GNUTLS_DGRAM))
750 _gnutls_write_uint16 (epoch, UINT64DATA((*slot)->write.sequence_number)(((*slot)->write.sequence_number).i));
751
752 if (out != NULL((void*)0))
753 *out = *slot;
754
755 return 0;
756}
757
758static inline int
759epoch_alive (gnutls_session_t session, record_parameters_st * params)
760{
761 const security_parameters_st *sp = &session->security_parameters;
762
763 /* DTLS will, in addition, need to check the epoch timeout value. */
764 if (params->usage_cnt > 0)
765 return 1;
766
767 if (params->epoch == sp->epoch_read)
768 return 1;
769
770 if (params->epoch == sp->epoch_write)
771 return 1;
772
773 if (params->epoch == sp->epoch_next)
774 return 1;
775
776 return 0;
777}
778
779void
780_gnutls_epoch_gc (gnutls_session_t session)
781{
782 int i, j;
783 unsigned int min_index = 0;
784
785 _gnutls_record_log ("REC[%p]: Start of epoch cleanup\n", session)do { if (__builtin_expect((_gnutls_log_level >= 4), 0)) _gnutls_log
( 4, "REC[%p]: Start of epoch cleanup\n", session); } while(0
)
;
786
787 /* Free all dead cipher state */
788 for (i = 0; i < MAX_EPOCH_INDEX16; i++)
789 if (session->record_parameters[i] != NULL((void*)0)
790 && !epoch_alive (session, session->record_parameters[i]))
791 {
792 _gnutls_epoch_free (session, session->record_parameters[i]);
793 session->record_parameters[i] = NULL((void*)0);
794 }
795
796 /* Look for contiguous NULLs at the start of the array */
797 for (i = 0; i < MAX_EPOCH_INDEX16 && session->record_parameters[i] == NULL((void*)0);
798 i++);
799 min_index = i;
800
801 /* Pick up the slack in the epoch window. */
802 for (i = 0, j = min_index; j < MAX_EPOCH_INDEX16; i++, j++)
803 session->record_parameters[i] = session->record_parameters[j];
804
805 /* Set the new epoch_min */
806 if (session->record_parameters[0] != NULL((void*)0))
807 session->security_parameters.epoch_min =
808 session->record_parameters[0]->epoch;
809
810 _gnutls_record_log ("REC[%p]: End of epoch cleanup\n", session)do { if (__builtin_expect((_gnutls_log_level >= 4), 0)) _gnutls_log
( 4, "REC[%p]: End of epoch cleanup\n", session); } while(0)
;
811}
812
813static inline void
814free_record_state (record_state_st * state, int d)
815{
816 _gnutls_free_datum (&state->mac_secret)_gnutls_free_datum_m(&state->mac_secret, gnutls_free);
817 _gnutls_free_datum (&state->IV)_gnutls_free_datum_m(&state->IV, gnutls_free);
818 _gnutls_free_datum (&state->key)_gnutls_free_datum_m(&state->key, gnutls_free);
819
820 _gnutls_auth_cipher_deinit (&state->cipher_state);
821
822 if (state->compression_state.handle != NULL((void*)0))
823 _gnutls_comp_deinit (&state->compression_state, d);
824}
825
826void
827_gnutls_epoch_free (gnutls_session_t session, record_parameters_st * params)
828{
829 _gnutls_record_log ("REC[%p]: Epoch #%u freed\n", session, params->epoch)do { if (__builtin_expect((_gnutls_log_level >= 4), 0)) _gnutls_log
( 4, "REC[%p]: Epoch #%u freed\n", session, params->epoch)
; } while(0)
;
830
831 free_record_state (&params->read, 1);
832 free_record_state (&params->write, 0);
833
834 gnutls_free (params);
835}