File: | lib/gnutls_constate.c |
Location: | line 252, column 7 |
Description: | Value stored to 'pos' is never read |
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 | |
39 | static const char keyexp[] = "key expansion"; |
40 | static const int keyexp_length = sizeof (keyexp) - 1; |
41 | |
42 | static const char ivblock[] = "IV block"; |
43 | static const int ivblock_length = sizeof (ivblock) - 1; |
44 | |
45 | static const char cliwrite[] = "client write key"; |
46 | static const int cliwrite_length = sizeof (cliwrite) - 1; |
47 | |
48 | static const char servwrite[] = "server write key"; |
49 | static 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 | */ |
58 | static 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 = ¶ms->write; |
77 | server_write = ¶ms->read; |
78 | } |
79 | else |
80 | { |
81 | client_write = ¶ms->read; |
82 | server_write = ¶ms->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 | |
295 | static 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 | |
322 | int |
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, ¶ms); |
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 | |
353 | int |
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, ¶ms); |
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 | |
377 | void |
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 | |
396 | int |
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, ¶ms); |
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, ¶ms->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, ¶ms->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 | |
470 | static 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 | */ |
486 | int |
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 | |
501 | static 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 | |
532 | int _gnutls_epoch_get_compression(gnutls_session_t session, int epoch) |
533 | { |
534 | record_parameters_st *params; |
535 | int ret; |
536 | |
537 | ret = _gnutls_epoch_get (session, epoch, ¶ms); |
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 | */ |
547 | int |
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 | */ |
596 | int |
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 | */ |
643 | int |
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 | |
660 | static inline int |
661 | epoch_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 | |
687 | static inline record_parameters_st ** |
688 | epoch_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 | |
702 | int |
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 | |
723 | int |
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 | |
758 | static inline int |
759 | epoch_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 | |
779 | void |
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 | |
813 | static inline void |
814 | free_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 | |
826 | void |
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 (¶ms->read, 1); |
832 | free_record_state (¶ms->write, 0); |
833 | |
834 | gnutls_free (params); |
835 | } |