Implemented key derivation, output record signing and encryption
[strongswan.git] / src / charon / plugins / eap_tls / tls / tls_crypto.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tls_crypto.h"
17
18 #include <daemon.h>
19
20 typedef struct private_tls_crypto_t private_tls_crypto_t;
21
22 /**
23 * Private data of an tls_crypto_t object.
24 */
25 struct private_tls_crypto_t {
26
27 /**
28 * Public tls_crypto_t interface.
29 */
30 tls_crypto_t public;
31
32 /**
33 * List of supported/acceptable cipher suites
34 */
35 tls_cipher_suite_t *suites;
36
37 /**
38 * Number of supported suites
39 */
40 int suite_count;
41
42 /**
43 * Selected cipher suite
44 */
45 tls_cipher_suite_t suite;
46
47 /**
48 * TLS context
49 */
50 tls_t *tls;
51
52 /**
53 * Connection state TLS PRF
54 */
55 tls_prf_t *prf;
56
57 /**
58 * Signer instance for inbound traffic
59 */
60 signer_t *signer_in;
61
62 /**
63 * Signer instance for outbound traffic
64 */
65 signer_t *signer_out;
66
67 /**
68 * Crypter instance for inbound traffic
69 */
70 crypter_t *crypter_in;
71
72 /**
73 * Crypter instance for outbound traffic
74 */
75 crypter_t *crypter_out;
76
77 /**
78 * IV for input decryption, if < TLSv1.2
79 */
80 chunk_t iv_in;
81
82 /**
83 * IV for output decryption, if < TLSv1.2
84 */
85 chunk_t iv_out;
86 };
87
88 typedef struct {
89 tls_cipher_suite_t suite;
90 hash_algorithm_t hash;
91 pseudo_random_function_t prf;
92 integrity_algorithm_t mac;
93 encryption_algorithm_t encr;
94 size_t encr_size;
95 } suite_algs_t;
96
97 /**
98 * Mapping suites to a set of algorithms
99 */
100 static suite_algs_t suite_algs[] = {
101 { TLS_RSA_WITH_NULL_MD5,
102 HASH_MD5,
103 PRF_HMAC_MD5,
104 AUTH_HMAC_MD5_128,
105 ENCR_NULL, 0
106 },
107 { TLS_RSA_WITH_NULL_SHA,
108 HASH_SHA1,
109 PRF_HMAC_SHA1,
110 AUTH_HMAC_SHA1_160,
111 ENCR_NULL, 0
112 },
113 { TLS_RSA_WITH_NULL_SHA256,
114 HASH_SHA256,
115 PRF_HMAC_SHA2_256,
116 AUTH_HMAC_SHA2_256_256,
117 ENCR_NULL, 0
118 },
119 { TLS_RSA_WITH_AES_128_CBC_SHA,
120 HASH_SHA1,
121 PRF_HMAC_SHA1,
122 AUTH_HMAC_SHA1_160,
123 ENCR_AES_CBC, 16
124 },
125 { TLS_RSA_WITH_AES_256_CBC_SHA,
126 HASH_SHA1,
127 PRF_HMAC_SHA1,
128 AUTH_HMAC_SHA1_160,
129 ENCR_AES_CBC, 32
130 },
131 { TLS_RSA_WITH_3DES_EDE_CBC_SHA,
132 HASH_SHA1,
133 PRF_HMAC_SHA1,
134 AUTH_HMAC_SHA1_160,
135 ENCR_3DES, 0
136 },
137 { TLS_RSA_WITH_AES_128_CBC_SHA256,
138 HASH_SHA256,
139 PRF_HMAC_SHA2_256,
140 AUTH_HMAC_SHA2_256_256,
141 ENCR_AES_CBC, 16
142 },
143 };
144
145 /**
146 * Look up algoritms by a suite
147 */
148 static suite_algs_t *find_suite(tls_cipher_suite_t suite)
149 {
150 int i;
151
152 for (i = 0; i < countof(suite_algs); i++)
153 {
154 if (suite_algs[i].suite == suite)
155 {
156 return &suite_algs[i];
157 }
158 }
159 return NULL;
160 }
161
162 /**
163 * Initialize the cipher suite list
164 */
165 static void build_cipher_suite_list(private_tls_crypto_t *this)
166 {
167 encryption_algorithm_t encr;
168 integrity_algorithm_t mac;
169 enumerator_t *encrs, *macs;
170 tls_cipher_suite_t supported[64], unique[64];
171 int count = 0, i, j;
172
173 /* we assume that we support RSA, but no DHE yet */
174 macs = lib->crypto->create_signer_enumerator(lib->crypto);
175 while (macs->enumerate(macs, &mac))
176 {
177 switch (mac)
178 {
179 case AUTH_HMAC_SHA1_160:
180 supported[count++] = TLS_RSA_WITH_NULL_SHA;
181 break;
182 case AUTH_HMAC_SHA2_256_256:
183 supported[count++] = TLS_RSA_WITH_NULL_SHA256;
184 break;
185 case AUTH_HMAC_MD5_128:
186 supported[count++] = TLS_RSA_WITH_NULL_MD5;
187 break;
188 default:
189 break;
190 }
191 encrs = lib->crypto->create_crypter_enumerator(lib->crypto);
192 while (encrs->enumerate(encrs, &encr))
193 {
194 switch (encr)
195 {
196 case ENCR_AES_CBC:
197 switch (mac)
198 {
199 case AUTH_HMAC_SHA1_160:
200 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
201 supported[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
202 break;
203 case AUTH_HMAC_SHA2_256_256:
204 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
205 supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
206 break;
207 default:
208 break;
209 }
210 break;
211 case ENCR_3DES:
212 switch (mac)
213 {
214 case AUTH_HMAC_SHA1_160:
215 supported[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
216 break;
217 default:
218 break;
219 }
220 break;
221 default:
222 break;
223 }
224 }
225 encrs->destroy(encrs);
226 }
227 macs->destroy(macs);
228
229 /* remove duplicates */
230 this->suite_count = 0;
231 for (i = 0; i < count; i++)
232 {
233 bool match = FALSE;
234
235 for (j = 0; j < this->suite_count; j++)
236 {
237 if (supported[i] == unique[j])
238 {
239 match = TRUE;
240 break;
241 }
242 }
243 if (!match)
244 {
245 unique[this->suite_count++] = supported[i];
246 }
247 }
248 free(this->suites);
249 this->suites = malloc(sizeof(tls_cipher_suite_t) * this->suite_count);
250 memcpy(this->suites, unique, sizeof(tls_cipher_suite_t) * this->suite_count);
251 }
252
253 METHOD(tls_crypto_t, get_cipher_suites, int,
254 private_tls_crypto_t *this, tls_cipher_suite_t **suites)
255 {
256 *suites = this->suites;
257 return this->suite_count;
258 }
259
260 /**
261 * Create crypto primitives
262 */
263 static bool create_ciphers(private_tls_crypto_t *this, tls_cipher_suite_t suite)
264 {
265 suite_algs_t *algs;
266
267 algs = find_suite(suite);
268 if (!algs)
269 {
270 DBG1(DBG_IKE, "selected TLS suite not supported");
271 return FALSE;
272 }
273
274 DESTROY_IF(this->prf);
275 if (this->tls->get_version(this->tls) < TLS_1_2)
276 {
277 this->prf = tls_prf_create_10();
278 }
279 else
280 {
281 this->prf = tls_prf_create_12(algs->prf);
282 }
283 if (!this->prf)
284 {
285 DBG1(DBG_IKE, "selected TLS PRF not supported");
286 return FALSE;
287 }
288
289 DESTROY_IF(this->signer_in);
290 DESTROY_IF(this->signer_out);
291 this->signer_in = lib->crypto->create_signer(lib->crypto, algs->mac);
292 this->signer_out = lib->crypto->create_signer(lib->crypto, algs->mac);
293 if (!this->signer_in || !this->signer_out)
294 {
295 DBG1(DBG_IKE, "selected TLS MAC %N not supported",
296 integrity_algorithm_names, algs->mac);
297 return FALSE;
298 }
299
300 DESTROY_IF(this->crypter_in);
301 DESTROY_IF(this->crypter_out);
302 if (algs->encr == ENCR_NULL)
303 {
304 this->crypter_in = this->crypter_out = NULL;
305 }
306 else
307 {
308 this->crypter_in = lib->crypto->create_crypter(lib->crypto,
309 algs->encr, algs->encr_size);
310 this->crypter_out = lib->crypto->create_crypter(lib->crypto,
311 algs->encr, algs->encr_size);
312 if (!this->crypter_in || !this->crypter_out)
313 {
314 DBG1(DBG_IKE, "selected TLS crypter %N not supported",
315 encryption_algorithm_names, algs->encr);
316 return FALSE;
317 }
318 }
319 return TRUE;
320 }
321
322 METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
323 private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count)
324 {
325 int i, j;
326
327 for (i = 0; i < this->suite_count; i++)
328 {
329 for (j = 0; j < count; j++)
330 {
331 if (this->suites[i] == suites[j])
332 {
333 if (create_ciphers(this, this->suites[i]))
334 {
335 this->suite = this->suites[i];
336 return this->suite;
337 }
338 }
339 }
340 }
341 return 0;
342 }
343
344 METHOD(tls_crypto_t, derive_master_secret, void,
345 private_tls_crypto_t *this, chunk_t premaster,
346 chunk_t client_random, chunk_t server_random)
347 {
348 char master[48];
349 chunk_t seed, block, client_write, server_write;
350 int mks, eks = 0, ivs = 0;
351
352 /* derive master secret */
353 seed = chunk_cata("cc", client_random, server_random);
354 this->prf->set_key(this->prf, premaster);
355 this->prf->get_bytes(this->prf, "master secret", seed,
356 sizeof(master), master);
357
358 this->prf->set_key(this->prf, chunk_from_thing(master));
359 memset(master, 0, sizeof(master));
360
361 /* derive key block for key expansion */
362 mks = this->signer_out->get_key_size(this->signer_out);
363 if (this->crypter_out)
364 {
365 eks = this->crypter_out->get_key_size(this->crypter_out);
366 if (this->tls->get_version(this->tls) < TLS_1_2)
367 {
368 ivs = this->crypter_out->get_block_size(this->crypter_out);
369 }
370 }
371 seed = chunk_cata("cc", server_random, client_random);
372 block = chunk_alloca((mks + eks + ivs) * 2);
373 this->prf->get_bytes(this->prf, "key expansion", seed, block.len, block.ptr);
374
375 /* signer keys */
376 client_write = chunk_create(block.ptr, mks);
377 block = chunk_skip(block, mks);
378 server_write = chunk_create(block.ptr, mks);
379 block = chunk_skip(block, mks);
380 if (this->tls->is_server(this->tls))
381 {
382 this->signer_in->set_key(this->signer_in, client_write);
383 this->signer_out->set_key(this->signer_out, server_write);
384 }
385 else
386 {
387 this->signer_out->set_key(this->signer_out, client_write);
388 this->signer_in->set_key(this->signer_in, server_write);
389 }
390
391 /* crypter keys, and IVs if < TLSv1.2 */
392 if (this->crypter_out && this->crypter_in)
393 {
394 client_write = chunk_create(block.ptr, eks);
395 block = chunk_skip(block, eks);
396 server_write = chunk_create(block.ptr, eks);
397 block = chunk_skip(block, eks);
398
399 if (this->tls->is_server(this->tls))
400 {
401 this->crypter_in->set_key(this->crypter_in, client_write);
402 this->crypter_out->set_key(this->crypter_out, server_write);
403 }
404 else
405 {
406 this->crypter_out->set_key(this->crypter_out, client_write);
407 this->crypter_in->set_key(this->crypter_in, server_write);
408 }
409 if (ivs)
410 {
411 client_write = chunk_create(block.ptr, ivs);
412 block = chunk_skip(block, ivs);
413 server_write = chunk_create(block.ptr, ivs);
414 block = chunk_skip(block, ivs);
415
416 if (this->tls->is_server(this->tls))
417 {
418 this->iv_in = chunk_clone(client_write);
419 this->iv_out = chunk_clone(server_write);
420 }
421 else
422 {
423 this->iv_out = chunk_clone(client_write);
424 this->iv_in = chunk_clone(server_write);
425 }
426 }
427 }
428 }
429
430 METHOD(tls_crypto_t, change_cipher, void,
431 private_tls_crypto_t *this, bool inbound)
432 {
433 if (inbound)
434 {
435 this->tls->change_cipher(this->tls, TRUE, this->signer_in,
436 this->crypter_in, this->iv_in);
437 }
438 else
439 {
440 this->tls->change_cipher(this->tls, FALSE, this->signer_out,
441 this->crypter_out, this->iv_out);
442 }
443 }
444
445 METHOD(tls_crypto_t, get_prf, tls_prf_t*,
446 private_tls_crypto_t *this)
447 {
448 return this->prf;
449 }
450
451 METHOD(tls_crypto_t, destroy, void,
452 private_tls_crypto_t *this)
453 {
454 DESTROY_IF(this->signer_in);
455 DESTROY_IF(this->signer_out);
456 DESTROY_IF(this->crypter_in);
457 DESTROY_IF(this->crypter_out);
458 free(this->iv_in.ptr);
459 free(this->iv_out.ptr);
460 DESTROY_IF(this->prf);
461 free(this->suites);
462 free(this);
463 }
464
465 /**
466 * See header
467 */
468 tls_crypto_t *tls_crypto_create(tls_t *tls)
469 {
470 private_tls_crypto_t *this;
471
472 INIT(this,
473 .public = {
474 .get_cipher_suites = _get_cipher_suites,
475 .select_cipher_suite = _select_cipher_suite,
476 .derive_master_secret = _derive_master_secret,
477 .change_cipher = _change_cipher,
478 .get_prf = _get_prf,
479 .destroy = _destroy,
480 },
481 .tls = tls,
482 );
483
484 build_cipher_suite_list(this);
485
486 return &this->public;
487 }